diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..2e5c95b61a2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule ".opensource/forgerock-javascript-sdk"] + path = .opensource/forgerock-javascript-sdk + url = git@github.com:ForgeRock/forgerock-javascript-sdk.git +[submodule ".repos/effect"] + path = .repos/effect + url = https://github.com/Effect-TS/effect diff --git a/.repos/effect b/.repos/effect new file mode 160000 index 00000000000..7a41f5aa72d --- /dev/null +++ b/.repos/effect @@ -0,0 +1 @@ +Subproject commit 7a41f5aa72d540ecf2746992ecc3fa3e6b40d31f diff --git a/e2e/device-client-app/src/device-binding/main.ts b/e2e/device-client-app/src/device-binding/main.ts index 49d30b9cda1..b1fd2abd5e3 100644 --- a/e2e/device-client-app/src/device-binding/main.ts +++ b/e2e/device-client-app/src/device-binding/main.ts @@ -7,7 +7,7 @@ * */ -import { Console, Effect } from 'effect'; +import { Console, Context, Effect } from 'effect'; import { getUser, handleError, handleSuccess, LoginAndGetClient } from '../utils/index.js'; @@ -58,4 +58,4 @@ const deviceBinding = Effect.gen(function* () { yield* Console.log('deleted', deletedDevice); }); -Effect.runPromise(deviceBinding).then(handleSuccess).catch(handleError); +Effect.runPromiseWith(Context.empty())(deviceBinding).then(handleSuccess).catch(handleError); diff --git a/e2e/device-client-app/src/device-profile/main.ts b/e2e/device-client-app/src/device-profile/main.ts index 0068848b169..c2042b6c00c 100644 --- a/e2e/device-client-app/src/device-profile/main.ts +++ b/e2e/device-client-app/src/device-profile/main.ts @@ -7,7 +7,7 @@ * */ -import { Console, Effect } from 'effect'; +import { Console, Context, Effect } from 'effect'; import { getUser, handleError, handleSuccess, LoginAndGetClient } from '../utils/index.js'; @@ -58,4 +58,4 @@ const deviceProfiling = Effect.gen(function* () { yield* Console.log('deleted', deletedDevice); }); -Effect.runPromise(deviceProfiling).then(handleSuccess).catch(handleError); +Effect.runPromiseWith(Context.empty())(deviceProfiling).then(handleSuccess).catch(handleError); diff --git a/e2e/device-client-app/src/oath/main.ts b/e2e/device-client-app/src/oath/main.ts index 2c4784097f6..dbc8d2c4d98 100644 --- a/e2e/device-client-app/src/oath/main.ts +++ b/e2e/device-client-app/src/oath/main.ts @@ -7,7 +7,7 @@ * */ -import { Console, Effect } from 'effect'; +import { Console, Context, Effect } from 'effect'; import { getUser, handleError, handleSuccess, LoginAndGetClient } from '../utils/index.js'; @@ -45,4 +45,4 @@ const oath = Effect.gen(function* () { yield* Console.log('deleted', deletedDevice); }); -Effect.runPromise(oath).then(handleSuccess).catch(handleError); +Effect.runPromiseWith(Context.empty())(oath).then(handleSuccess).catch(handleError); diff --git a/e2e/device-client-app/src/push/main.ts b/e2e/device-client-app/src/push/main.ts index ec0f7e0810b..56ce3c613ef 100644 --- a/e2e/device-client-app/src/push/main.ts +++ b/e2e/device-client-app/src/push/main.ts @@ -7,7 +7,7 @@ * */ -import { Console, Effect } from 'effect'; +import { Console, Context, Effect } from 'effect'; import { getUser, handleError, handleSuccess, LoginAndGetClient } from '../utils/index.js'; @@ -45,4 +45,4 @@ const push = Effect.gen(function* () { yield* Console.log('deleted', deletedDevice); }); -Effect.runPromise(push).then(handleSuccess).catch(handleError); +Effect.runPromiseWith(Context.empty())(push).then(handleSuccess).catch(handleError); diff --git a/e2e/device-client-app/src/utils/index.ts b/e2e/device-client-app/src/utils/index.ts index 721d453d025..966c7ec597b 100644 --- a/e2e/device-client-app/src/utils/index.ts +++ b/e2e/device-client-app/src/utils/index.ts @@ -122,7 +122,7 @@ export const LoginAndGetClient = Effect.gen(function* () { yield* Effect.tryPromise({ try: () => oidcClientOrThrow().user.logout(), catch: (err) => new Error(`Logout failed: ${err}`), - }).pipe(Effect.catchAll((err) => Console.warn('Logout failed, continuing:', err))); + }).pipe(Effect.orElseSucceed((err) => Console.warn('Logout failed, continuing:', err))); yield* Effect.tryPromise({ try: () => journeyClient.start({ journey: tree }), diff --git a/e2e/device-client-app/src/webauthn/main.ts b/e2e/device-client-app/src/webauthn/main.ts index 2cbc75dcaa9..36896e50b74 100644 --- a/e2e/device-client-app/src/webauthn/main.ts +++ b/e2e/device-client-app/src/webauthn/main.ts @@ -7,7 +7,7 @@ * */ -import { Console, Effect } from 'effect'; +import { Console, Context, Effect } from 'effect'; import { getUser, handleError, handleSuccess, LoginAndGetClient } from '../utils/index.js'; @@ -58,4 +58,4 @@ const webauthn = Effect.gen(function* () { yield* Console.log('deleted', deletedDevice); }); -Effect.runPromise(webauthn).then(handleSuccess).catch(handleError); +Effect.runPromiseWith(Context.empty())(webauthn).then(handleSuccess).catch(handleError); diff --git a/e2e/journey-app/components/webauthn-step.ts b/e2e/journey-app/components/webauthn-step.ts index 5fd28ab2c83..bfbf344cb0d 100644 --- a/e2e/journey-app/components/webauthn-step.ts +++ b/e2e/journey-app/components/webauthn-step.ts @@ -65,7 +65,7 @@ export async function handleWebAuthnStep( // True only when the browser supports conditional mediation AND AM requested it // (meta.mediation === 'conditional'). - const isConditionalMediation = await WebAuthn.isConditionalMediationSupported(step); + const isConditionalMediation = await WebAuthn.isConditionalMediationSupported(); const hasPasskeyAutocompleteValues = callbacks.some((callback) => { const values = callback.getOutputByName('autocompleteValues', []); diff --git a/e2e/mock-api-v2/package.json b/e2e/mock-api-v2/package.json index 9ad43d1b2ce..fadae46c1e3 100644 --- a/e2e/mock-api-v2/package.json +++ b/e2e/mock-api-v2/package.json @@ -6,7 +6,7 @@ "type": "module", "main": "./src/main.js", "scripts": { - "build": "pnpm nx nxBuild", + "build": "pnpm nx build", "dev": "node dist/src/main.js --watch-path=./", "lint": "pnpm nx nxLint", "serve": "node dist/src/main.js", @@ -15,7 +15,6 @@ "dependencies": { "@effect/language-service": "catalog:effect", "@effect/opentelemetry": "catalog:effect", - "@effect/platform": "catalog:effect", "@effect/platform-node": "catalog:effect", "@opentelemetry/sdk-logs": "0.207.0", "@opentelemetry/sdk-metrics": "2.2.0", diff --git a/e2e/mock-api-v2/src/handlers/authorize.handler.ts b/e2e/mock-api-v2/src/handlers/authorize.handler.ts index bc225fb7fc9..930fd5196b0 100644 --- a/e2e/mock-api-v2/src/handlers/authorize.handler.ts +++ b/e2e/mock-api-v2/src/handlers/authorize.handler.ts @@ -4,14 +4,15 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder, HttpApiError, HttpServerResponse } from '@effect/platform'; import { Effect, pipe } from 'effect'; +import { HttpServerResponse } from 'effect/http'; +import { HttpApiBuilder, HttpApiError } from 'effect/http-api'; import { getFirstElementAndRespond } from '../services/mock-env-helpers/index.js'; import { MockApi } from '../spec.js'; const AuthorizeHandlerMock = HttpApiBuilder.group(MockApi, 'Authorization', (handlers) => - handlers.handle('authorize', ({ urlParams }) => + handlers.handle('authorize', ({ query: urlParams }) => Effect.gen(function* () { const acr_value = urlParams?.acr_values ?? ''; @@ -20,8 +21,10 @@ const AuthorizeHandlerMock = HttpApiBuilder.group(MockApi, 'Authorization', (han const res = yield* pipe( HttpServerResponse.json(body), Effect.flatMap(HttpServerResponse.setCookie('acr_values', acr_value, { path: '/' })), - Effect.catchTag('CookieError', () => Effect.fail(new HttpApiError.InternalServerError())), - Effect.catchTag('HttpBodyError', () => Effect.fail(new HttpApiError.InternalServerError())), + Effect.catchTags({ + CookiesError: () => Effect.fail(new HttpApiError.InternalServerError()), + HttpBodyError: () => Effect.fail(new HttpApiError.InternalServerError()), + }), ); return res; diff --git a/e2e/mock-api-v2/src/handlers/capabilities.handler.ts b/e2e/mock-api-v2/src/handlers/capabilities.handler.ts index 4a0d66265be..e9ebfb9c251 100644 --- a/e2e/mock-api-v2/src/handlers/capabilities.handler.ts +++ b/e2e/mock-api-v2/src/handlers/capabilities.handler.ts @@ -4,13 +4,10 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { - HttpApiBuilder, - HttpApiError, - HttpServerRequest, - HttpServerResponse, -} from '@effect/platform'; import { Effect, pipe } from 'effect'; +import { HttpServerRequest } from 'effect/http'; +import { HttpServerResponse } from 'effect/http'; +import { HttpApiBuilder, HttpApiError } from 'effect/http-api'; import { validator } from '../helpers/match.js'; import { responseMap } from '../responses/index.js'; @@ -106,15 +103,15 @@ const CapabilitiesHandlerMock = HttpApiBuilder.group(MockApi, 'Capabilities', (h }, ), ), - Effect.flatMap((res) => HttpServerResponse.removeCookie(res, 'stepIndex')), - Effect.flatMap((res) => HttpServerResponse.setStatus(res, 200)), - Effect.flatMap((res) => + Effect.map((res) => HttpServerResponse.removeCookie(res, 'stepIndex')), + Effect.map((res) => HttpServerResponse.setStatus(res, 200)), + Effect.map((res) => HttpServerResponse.setHeader(res, 'Content-Type', 'application/json'), ), - Effect.catchTag('CookieError', () => Effect.fail(new HttpApiError.InternalServerError())), - Effect.catchTag('HttpBodyError', () => - Effect.fail(new HttpApiError.InternalServerError()), - ), + Effect.catchTags({ + CookiesError: () => Effect.fail(new HttpApiError.InternalServerError()), + HttpBodyError: () => Effect.fail(new HttpApiError.InternalServerError()), + }), ); } diff --git a/e2e/mock-api-v2/src/handlers/end-session.handler.ts b/e2e/mock-api-v2/src/handlers/end-session.handler.ts index 680c6a9c5ce..b4194955528 100644 --- a/e2e/mock-api-v2/src/handlers/end-session.handler.ts +++ b/e2e/mock-api-v2/src/handlers/end-session.handler.ts @@ -4,8 +4,9 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder, HttpServerRequest } from '@effect/platform'; import { Console, Effect } from 'effect'; +import { HttpServerRequest } from 'effect/http'; +import { HttpApiBuilder } from 'effect/http-api'; import { SessionStorage } from '../services/session.service.js'; import { MockApi } from '../spec.js'; diff --git a/e2e/mock-api-v2/src/handlers/healthcheck.handler.ts b/e2e/mock-api-v2/src/handlers/healthcheck.handler.ts index bea605181e0..6d29602a64d 100644 --- a/e2e/mock-api-v2/src/handlers/healthcheck.handler.ts +++ b/e2e/mock-api-v2/src/handlers/healthcheck.handler.ts @@ -1,12 +1,5 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -import { HttpApiBuilder } from '@effect/platform'; import { Effect } from 'effect'; +import { HttpApiBuilder } from 'effect/http-api'; import { MockApi } from '../spec.js'; diff --git a/e2e/mock-api-v2/src/handlers/open-id-configuration.handler.ts b/e2e/mock-api-v2/src/handlers/open-id-configuration.handler.ts index 3c71a5eb0d1..adf1f0d2489 100644 --- a/e2e/mock-api-v2/src/handlers/open-id-configuration.handler.ts +++ b/e2e/mock-api-v2/src/handlers/open-id-configuration.handler.ts @@ -4,16 +4,16 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder } from '@effect/platform'; -import { HttpServerRequest } from '@effect/platform/HttpServerRequest'; import { Effect } from 'effect'; +import { HttpServerRequest } from 'effect/http'; +import { HttpApiBuilder } from 'effect/http-api'; import { MockApi } from '../spec.js'; const OpenidConfigMock = HttpApiBuilder.group(MockApi, 'OpenIDConfig', (handlers) => - handlers.handle('openid', ({ path: { envid } }) => + handlers.handle('openid', ({ params: { envid } }) => Effect.gen(function* () { - const request = yield* HttpServerRequest; + const request = yield* HttpServerRequest.HttpServerRequest; const url = new URL(request.url); const issuer = `${url.protocol}//${url.host}/${envid}/as`; return { diff --git a/e2e/mock-api-v2/src/handlers/revoke.handler.ts b/e2e/mock-api-v2/src/handlers/revoke.handler.ts index f58384dd6ae..a1fa8159606 100644 --- a/e2e/mock-api-v2/src/handlers/revoke.handler.ts +++ b/e2e/mock-api-v2/src/handlers/revoke.handler.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder } from '@effect/platform'; import { Effect } from 'effect'; +import { HttpApiBuilder } from 'effect/http-api'; import { Tokens } from '../services/tokens.service.js'; import { MockApi } from '../spec.js'; diff --git a/e2e/mock-api-v2/src/handlers/token.handler.ts b/e2e/mock-api-v2/src/handlers/token.handler.ts index 0f3805b5102..4106889b3c1 100644 --- a/e2e/mock-api-v2/src/handlers/token.handler.ts +++ b/e2e/mock-api-v2/src/handlers/token.handler.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder } from '@effect/platform'; import { Effect } from 'effect'; +import { HttpApiBuilder } from 'effect/http-api'; import { Tokens } from '../services/tokens.service.js'; import { MockApi } from '../spec.js'; diff --git a/e2e/mock-api-v2/src/handlers/userinfo.handler.ts b/e2e/mock-api-v2/src/handlers/userinfo.handler.ts index 9c94bcb4b0b..779a496d5b3 100644 --- a/e2e/mock-api-v2/src/handlers/userinfo.handler.ts +++ b/e2e/mock-api-v2/src/handlers/userinfo.handler.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiBuilder, HttpApiError } from '@effect/platform'; import { Effect } from 'effect'; +import { HttpApiBuilder, HttpApiError } from 'effect/http-api'; import { BearerToken } from '../middleware/Authorization.js'; import { UserInfo } from '../services/userinfo.service.js'; diff --git a/e2e/mock-api-v2/src/helpers/match.ts b/e2e/mock-api-v2/src/helpers/match.ts index bdbbd22798b..ad52a9d0ef5 100644 --- a/e2e/mock-api-v2/src/helpers/match.ts +++ b/e2e/mock-api-v2/src/helpers/match.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiError } from '@effect/platform'; import { Effect, Match } from 'effect'; +import { HttpApiError } from 'effect/http-api'; import type { Schema } from 'effect'; @@ -23,13 +23,11 @@ const validator = Match.type().pipe( Match.when( { parameters: { data: { formData: { username: Match.string, password: Match.string } } } }, ({ parameters }) => - Effect.if( + Effect.suspend(() => parameters.data.formData.username == 'testuser' && - parameters.data.formData.password === 'Password', - { - onFalse: () => Effect.fail(new HttpApiError.Unauthorized()), - onTrue: () => Effect.succeed(true), - }, + parameters.data.formData.password === 'Password' + ? Effect.succeed(true) + : Effect.fail(new HttpApiError.Unauthorized()), ), ), Match.orElse(() => Effect.succeed(true)), diff --git a/e2e/mock-api-v2/src/main.ts b/e2e/mock-api-v2/src/main.ts index 12e9ff05bd3..4724c5d6585 100644 --- a/e2e/mock-api-v2/src/main.ts +++ b/e2e/mock-api-v2/src/main.ts @@ -4,11 +4,20 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { NodeSdk } from '@effect/opentelemetry'; -import { HttpApiBuilder, HttpApiSwagger, HttpMiddleware, HttpServer } from '@effect/platform'; import { NodeHttpServer, NodeRuntime } from '@effect/platform-node'; -import { BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'; import { Layer } from 'effect'; +import { HttpMiddleware } from 'effect/http'; +import { HttpRouter } from 'effect/http'; +import { HttpServer } from 'effect/http'; +import { HttpApiBuilder, HttpApiSwagger } from 'effect/http-api'; + +import { MockApi } from './spec.js'; + +import type { Effect } from 'effect'; +import type { HttpServerError } from 'effect/http'; +type ServeError = HttpServerError.ServeError; +import { NodeSdk } from '@effect/opentelemetry'; +import { BatchSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'; import { createServer } from 'node:http'; import { AuthorizeHandlerMock } from './handlers/authorize.handler.js'; @@ -25,49 +34,64 @@ import { SessionMiddlewareMock } from './middleware/Session.js'; import { SessionStorage } from './services/session.service.js'; import { TokensMock } from './services/tokens.service.js'; import { UserInfoMockService } from './services/userinfo.service.js'; -import { MockApi } from './spec.js'; - -const Services = [ - Layer.provide(TokensMock), - Layer.provide(IncrementStepIndexMock), - Layer.provide(AuthorizationMock), - Layer.provide(UserInfoMockService), - Layer.provide(SessionMiddlewareMock), - Layer.provide(SessionStorage.Default), -] as const; const NodeSdkLive = NodeSdk.layer(() => ({ resource: { serviceName: 'Mock-Api' }, spanProcessor: new BatchSpanProcessor(new ConsoleSpanExporter()), })); -const APIMock = HttpApiBuilder.api(MockApi).pipe( - Layer.provide(HealthCheckLive), - Layer.provide(OpenidConfigMock), - Layer.provide(AuthorizeHandlerMock), - Layer.provide(TokensHandler), - Layer.provide(CapabilitiesHandlerMock), - Layer.provide(UserInfoMockHandler), - Layer.provide(EndSessionHandlerMock), - Layer.provide(RevokeTokenHandler), - ...Services, +// Wire SessionStorage into SessionMiddlewareMock +const SessionLayer = Layer.provide( + SessionMiddlewareMock, + Layer.effect(SessionStorage, SessionStorage.make), +); + +// Merge all group handlers +const HandlersLayer = Layer.mergeAll( + HealthCheckLive, + OpenidConfigMock, + AuthorizeHandlerMock, + TokensHandler, + CapabilitiesHandlerMock, + UserInfoMockHandler, + EndSessionHandlerMock, + RevokeTokenHandler, +); + +// Merge all services +const ServicesLayer = Layer.mergeAll( + TokensMock, + IncrementStepIndexMock, + AuthorizationMock, + UserInfoMockService, + SessionLayer, +); + +// Build application routes layer with all handlers and services provided in one step each +const AppLayer = HttpApiBuilder.layer(MockApi).pipe( + Layer.provide(HandlersLayer), + Layer.provide(ServicesLayer), ); -const ServerMock = HttpApiBuilder.serve(HttpMiddleware.logger).pipe( - Layer.provide(HttpApiSwagger.layer()), - Layer.provide( - HttpApiBuilder.middlewareCors({ +// Compose app + swagger, then provide the router service +const AppWithSwagger = Layer.merge(AppLayer, HttpApiSwagger.layer(MockApi)).pipe( + Layer.provide(HttpRouter.layer), +); + +const ServerMock = HttpRouter.serve(AppWithSwagger, { + middleware: (app) => + HttpMiddleware.cors({ allowedMethods: ['GET', 'PUT', 'POST', 'OPTIONS'], allowedOrigins: ['*'], credentials: true, maxAge: 3600, - }), - ), - Layer.provide(APIMock), - - Layer.provide(NodeSdkLive), + })(HttpMiddleware.logger(app)), +}).pipe( HttpServer.withLogAddress, + Layer.provide(NodeSdkLive), Layer.provide(NodeHttpServer.layer(createServer, { port: 9443, host: 'localhost' })), ); -Layer.launch(ServerMock).pipe(NodeRuntime.runMain); +// TypeScript cannot fully resolve complex Effect layer generic compositions; +// all requirements ARE satisfied at runtime — NodeHttpServer provides FileSystem, Path, HttpPlatform, Etag. +NodeRuntime.runMain(Layer.launch(ServerMock) as Effect.Effect); diff --git a/e2e/mock-api-v2/src/middleware/Authorization.ts b/e2e/mock-api-v2/src/middleware/Authorization.ts index 59cc8be7d43..2d8e9cd74f9 100644 --- a/e2e/mock-api-v2/src/middleware/Authorization.ts +++ b/e2e/mock-api-v2/src/middleware/Authorization.ts @@ -1,23 +1,20 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -import { HttpApiMiddleware, HttpApiSecurity, OpenApi } from '@effect/platform'; -import { Unauthorized } from '@effect/platform/HttpApiError'; import { Brand, Context, Effect, Layer, Redacted } from 'effect'; +import { HttpApiError, HttpApiMiddleware, HttpApiSecurity, OpenApi } from 'effect/http-api'; + +import type { Types } from 'effect'; +import type { HttpServerResponse } from 'effect/http/HttpServerResponse'; type BearerTokenValue = string & Brand.Brand<'BearerToken'>; const BearerTokenValue = Brand.nominal(); // Define a service that holds the bearer token -class BearerToken extends Context.Tag('BearerToken')() {} +class BearerToken extends Context.Service()('BearerToken') {} -class Authorization extends HttpApiMiddleware.Tag()('Authorization', { - failure: Unauthorized, - provides: BearerToken, +class Authorization extends HttpApiMiddleware.Service< + Authorization, + { provides: typeof BearerToken } +>()('Authorization', { + error: HttpApiError.Unauthorized, security: { myBearer: HttpApiSecurity.bearer.pipe( HttpApiSecurity.annotate(OpenApi.Description, 'Bearer token for API authentication'), @@ -31,20 +28,27 @@ const AuthorizationMock = Layer.effect( yield* Effect.log('creating Authorization middleware'); return { - myBearer: (bearerToken) => + myBearer: ( + httpEffect: Effect.Effect, + { + credential, + }: { credential: Redacted.Redacted; endpoint: unknown; group: unknown }, + ) => Effect.gen(function* () { - const tokenValue = Redacted.value(bearerToken); + const tokenValue = Redacted.value(credential); yield* Effect.log('checking bearer token', tokenValue); // Validation logic // 1. Check if token is empty // 2. Check if token has been revoked (has REVOKED_ prefix) if (!tokenValue || tokenValue.trim() === '' || tokenValue.startsWith('REVOKED_')) { - return yield* Effect.fail(new Unauthorized()); + return yield* Effect.fail(new HttpApiError.Unauthorized()); } - // Return the token value so routes can access it - return BearerTokenValue(tokenValue); + // Provide BearerToken and run the original effect + return yield* httpEffect.pipe( + Effect.provideService(BearerToken, BearerTokenValue(tokenValue)), + ); }), }; }), diff --git a/e2e/mock-api-v2/src/middleware/CookieMiddleware.ts b/e2e/mock-api-v2/src/middleware/CookieMiddleware.ts index 221709d57e7..81ff22a8d89 100644 --- a/e2e/mock-api-v2/src/middleware/CookieMiddleware.ts +++ b/e2e/mock-api-v2/src/middleware/CookieMiddleware.ts @@ -1,18 +1,14 @@ /** - * Copyright (c) 2025 Ping Identity Corporation. + * Copyright (c) 2025 - 2026 Ping Identity Corporation. * MIT License */ -import { - HttpApiMiddleware, - HttpApp, - HttpServerRequest, - HttpServerResponse, -} from '@effect/platform'; -import { ResponseError } from '@effect/platform/HttpServerError'; import { Console, Effect, Layer } from 'effect'; +import { HttpServerRequest } from 'effect/http'; +import { HttpServerResponse } from 'effect/http'; +import { HttpApiMiddleware } from 'effect/http-api'; // Export the tag so you can .middleware(IncrementStepIndex) in your spec if desired -export class IncrementStepIndex extends HttpApiMiddleware.Tag()( +export class IncrementStepIndex extends HttpApiMiddleware.Service()( 'IncrementStepIndex', ) {} @@ -21,60 +17,48 @@ export const IncrementStepIndexMock = Layer.effect( Effect.gen(function* () { yield* Console.log('IncrementStepIndex: init'); - return Effect.gen(function* () { - // Read cookies from the current request - const request = yield* HttpServerRequest.HttpServerRequest; + return (httpEffect: Effect.Effect) => + Effect.gen(function* () { + // Read cookies from the current request + const request = yield* HttpServerRequest.HttpServerRequest; - // Parse existing stepIndex cookie or default to 0 - const cookies = request.cookies; - const currentStepIndex = cookies.stepIndex ? parseInt(cookies.stepIndex, 10) : 0; + // Parse existing stepIndex cookie or default to 0 + const cookies = request.cookies; + const currentStepIndex = cookies.stepIndex ? parseInt(cookies.stepIndex, 10) : 0; - // Normalize URL (strip query) and detect special flows - const urlPath = request.url.split('?')[0] ?? ''; - const isEndSessionRequest = - urlPath.includes('/endSession') || urlPath.includes('/end_session'); - const isAuthFlowRequest = urlPath.includes('/authorize') || urlPath.includes('/authenticate'); + // Normalize URL (strip query) and detect special flows + const urlPath = request.url.split('?')[0] ?? ''; + const isEndSessionRequest = + urlPath.includes('/endSession') || urlPath.includes('/end_session'); + const isAuthFlowRequest = + urlPath.includes('/authorize') || urlPath.includes('/authenticate'); - // Decide next value - let newStepIndex = currentStepIndex; - if (isEndSessionRequest) { - newStepIndex = 0; - yield* Console.log( - `IncrementStepIndex: end-session detected → resetting stepIndex to ${newStepIndex}`, - ); - } else if (isAuthFlowRequest) { - newStepIndex = currentStepIndex + 1; - yield* Console.log( - `IncrementStepIndex: auth flow → ${currentStepIndex} -> ${newStepIndex}`, - ); - } else { - yield* Console.log( - `IncrementStepIndex: other route ${urlPath} → keeping stepIndex ${currentStepIndex}`, - ); - } + // Decide next value + let newStepIndex = currentStepIndex; + if (isEndSessionRequest) { + newStepIndex = 0; + yield* Console.log( + `IncrementStepIndex: end-session detected → resetting stepIndex to ${newStepIndex}`, + ); + } else if (isAuthFlowRequest) { + newStepIndex = currentStepIndex + 1; + yield* Console.log( + `IncrementStepIndex: auth flow → ${currentStepIndex} -> ${newStepIndex}`, + ); + } else { + yield* Console.log( + `IncrementStepIndex: other route ${urlPath} → keeping stepIndex ${currentStepIndex}`, + ); + } - // Write cookie just before the response is sent - yield* HttpApp.appendPreResponseHandler((req, res) => - HttpServerResponse.setCookie(res, 'stepIndex', String(newStepIndex), { - // NOTE: mock defaults; tighten in prod (httpOnly: true, secure: true, sameSite: 'lax') + // Run the original handler then set the step index cookie on the response + const response = yield* httpEffect; + return yield* HttpServerResponse.setCookie(response, 'stepIndex', String(newStepIndex), { httpOnly: false, secure: false, sameSite: 'strict', path: '/', - }).pipe( - // If cookie setting fails, convert to a typed ResponseError for consistent diagnostics - Effect.catchTag( - 'CookieError', - () => - new ResponseError({ - request: req, - response: res, - reason: 'Decode', - cause: 'error updating the stepIndex cookie', - }), - ), - ), - ); - }); + }).pipe(Effect.orDie); + }); }), ); diff --git a/e2e/mock-api-v2/src/middleware/Session.ts b/e2e/mock-api-v2/src/middleware/Session.ts index 8b8710528b2..b94fb36a44f 100644 --- a/e2e/mock-api-v2/src/middleware/Session.ts +++ b/e2e/mock-api-v2/src/middleware/Session.ts @@ -1,22 +1,20 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -import { HttpApiError, HttpApiMiddleware, HttpServerRequest } from '@effect/platform'; import { Context, Effect, Layer } from 'effect'; +import { HttpServerRequest } from 'effect/http'; +import { HttpApiError, HttpApiMiddleware } from 'effect/http-api'; import { SessionStorage } from '../services/session.service.js'; +import type { HttpServerResponse } from 'effect/http/HttpServerResponse'; + import type { SessionData } from '../services/session.service.js'; -class Session extends Context.Tag('Session')() {} +class Session extends Context.Service()('Session') {} -export class SessionMiddleware extends HttpApiMiddleware.Tag()('Session', { - failure: HttpApiError.Unauthorized, - provides: Session, +export class SessionMiddleware extends HttpApiMiddleware.Service< + SessionMiddleware, + { provides: typeof Session } +>()('Session', { + error: HttpApiError.Unauthorized, }) {} export const SessionMiddlewareMock = Layer.effect( @@ -24,27 +22,31 @@ export const SessionMiddlewareMock = Layer.effect( Effect.gen(function* () { const sessionStorage = yield* SessionStorage; - return Effect.gen(function* () { - const request = yield* HttpServerRequest.HttpServerRequest; - const sessionData = yield* sessionStorage - .getSession(request.cookies.sessionId) - .pipe(Effect.orDie); - if (!sessionData) { - const session = yield* sessionStorage.createSession({ - userId: request.cookies.userId, - createdAt: new Date(), - expiresAt: new Date(Date.now() + 60 * 60 * 1000), // 1 hour - data: {}, - }); - - return session; - } - - yield* sessionStorage - .refreshSession(request.cookies.sessionId, sessionData.expiresAt) - .pipe(Effect.orDie); - - return sessionData; - }); + return (httpEffect: Effect.Effect) => + Effect.gen(function* () { + const request = yield* HttpServerRequest.HttpServerRequest; + const sessionData = yield* sessionStorage + .getSession(request.cookies.sessionId) + .pipe(Effect.orDie); + + let session: SessionData; + if (!sessionData) { + session = yield* sessionStorage + .createSession({ + userId: request.cookies.userId, + createdAt: new Date(), + expiresAt: new Date(Date.now() + 60 * 60 * 1000), // 1 hour + data: {}, + }) + .pipe(Effect.orDie); + } else { + yield* sessionStorage + .refreshSession(request.cookies.sessionId, sessionData.expiresAt) + .pipe(Effect.orDie); + session = sessionData; + } + + return yield* httpEffect.pipe(Effect.provideService(Session, session)); + }); }), ); diff --git a/e2e/mock-api-v2/src/responses/index.ts b/e2e/mock-api-v2/src/responses/index.ts index 1448c102285..77e91a54eff 100644 --- a/e2e/mock-api-v2/src/responses/index.ts +++ b/e2e/mock-api-v2/src/responses/index.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/e2e/mock-api-v2/src/schemas/authorize.schema.ts b/e2e/mock-api-v2/src/schemas/authorize.schema.ts index 470217a5ff5..482e8387a5b 100644 --- a/e2e/mock-api-v2/src/schemas/authorize.schema.ts +++ b/e2e/mock-api-v2/src/schemas/authorize.schema.ts @@ -29,9 +29,8 @@ const _DavinciAuthorizeQuery = Schema.Struct({ acr_values: Schema.optional(Schema.String), // this should be optional }); -interface DavinciAuthorizeQuery extends Schema.Schema.Type {} -const DavinciAuthorizeQuery: Schema.Schema = - _DavinciAuthorizeQuery; +type DavinciAuthorizeQuery = Schema.Schema.Type; +const DavinciAuthorizeQuery: Schema.Schema = _DavinciAuthorizeQuery; const DavinciAuthorizeFailure = Schema.Struct({ error: Schema.String, diff --git a/e2e/mock-api-v2/src/schemas/capabilities/capabilities.request.schema.ts b/e2e/mock-api-v2/src/schemas/capabilities/capabilities.request.schema.ts index 83f4c0a0f64..dcb1638258d 100644 --- a/e2e/mock-api-v2/src/schemas/capabilities/capabilities.request.schema.ts +++ b/e2e/mock-api-v2/src/schemas/capabilities/capabilities.request.schema.ts @@ -21,7 +21,7 @@ const CapabilitiesRequestBody = Schema.Struct({ interactionId: Schema.String, parameters: Schema.Struct({ eventType: Schema.String, - data: Schema.Union(UsernamePassword), + data: UsernamePassword, }), }); diff --git a/e2e/mock-api-v2/src/schemas/capabilities/capabilities.response.schema.ts b/e2e/mock-api-v2/src/schemas/capabilities/capabilities.response.schema.ts index 8630ef4a85a..1f318fcc6ca 100644 --- a/e2e/mock-api-v2/src/schemas/capabilities/capabilities.response.schema.ts +++ b/e2e/mock-api-v2/src/schemas/capabilities/capabilities.response.schema.ts @@ -19,7 +19,7 @@ const UsernamePasswordFormData = Schema.Struct({ }), }); -const FormData = Schema.Union(UsernamePasswordFormData, ProtectSDKRequestFormData); +const FormData = Schema.Union([UsernamePasswordFormData, ProtectSDKRequestFormData]); const CapabilitiesResponse = Schema.Struct({ interactionId: Schema.String, diff --git a/e2e/mock-api-v2/src/schemas/open-id-configuration/open-id-configuration-response.schema.ts b/e2e/mock-api-v2/src/schemas/open-id-configuration/open-id-configuration-response.schema.ts index 0768594b095..87c59ac43dd 100644 --- a/e2e/mock-api-v2/src/schemas/open-id-configuration/open-id-configuration-response.schema.ts +++ b/e2e/mock-api-v2/src/schemas/open-id-configuration/open-id-configuration-response.schema.ts @@ -37,13 +37,11 @@ const _openIdConfigurationResponseSchema = Schema.Struct({ code_challenge_methods_supported: Schema.Array(Schema.String), }); -interface openIdConfigurationResponseSchema extends Schema.Schema.Type< +type openIdConfigurationResponseSchema = Schema.Schema.Type< typeof _openIdConfigurationResponseSchema -> {} +>; -const openIdConfigurationResponseSchema: Schema.Schema< - openIdConfigurationResponseSchema, - openIdConfigurationResponseSchema -> = _openIdConfigurationResponseSchema; +const openIdConfigurationResponseSchema: Schema.Schema = + _openIdConfigurationResponseSchema; export { _openIdConfigurationResponseSchema, openIdConfigurationResponseSchema }; diff --git a/e2e/mock-api-v2/src/schemas/return-success-response-redirect.schema.ts b/e2e/mock-api-v2/src/schemas/return-success-response-redirect.schema.ts index 9b9294c8dc1..0b078fab91b 100644 --- a/e2e/mock-api-v2/src/schemas/return-success-response-redirect.schema.ts +++ b/e2e/mock-api-v2/src/schemas/return-success-response-redirect.schema.ts @@ -42,7 +42,6 @@ const _SuccessResponseRedirect = Schema.Struct({ }), }); -interface SuccessResponseRedirect extends Schema.Schema.Type {} -const SuccessResponseRedirect: Schema.Schema = - _SuccessResponseRedirect; +type SuccessResponseRedirect = Schema.Schema.Type; +const SuccessResponseRedirect: Schema.Schema = _SuccessResponseRedirect; export { SuccessResponseRedirect }; diff --git a/e2e/mock-api-v2/src/schemas/revoke/revoke.schema.ts b/e2e/mock-api-v2/src/schemas/revoke/revoke.schema.ts index 7e072bbebfb..b363c0bbd17 100644 --- a/e2e/mock-api-v2/src/schemas/revoke/revoke.schema.ts +++ b/e2e/mock-api-v2/src/schemas/revoke/revoke.schema.ts @@ -15,7 +15,7 @@ const RevokePath = Schema.Struct({ const RevokeRequestBody = Schema.Struct({ token: Schema.String, // The token to be revoked token_type_hint: Schema.optional( - Schema.Union(Schema.Literal('access_token'), Schema.Literal('refresh_token')), + Schema.Union([Schema.Literal('access_token'), Schema.Literal('refresh_token')]), ), // Hint about token type (access_token or refresh_token) client_id: Schema.optional(Schema.String), // OAuth 2.0 client identifier client_secret: Schema.optional(Schema.String), // OAuth 2.0 client secret diff --git a/e2e/mock-api-v2/src/schemas/token/token.schema.ts b/e2e/mock-api-v2/src/schemas/token/token.schema.ts index d5701e86f1d..b66ca0591b3 100644 --- a/e2e/mock-api-v2/src/schemas/token/token.schema.ts +++ b/e2e/mock-api-v2/src/schemas/token/token.schema.ts @@ -9,13 +9,13 @@ import { Schema } from 'effect'; const _TokenRequestBody = Schema.Struct({ client_id: Schema.String, code: Schema.String, - grant_type: Schema.Union(Schema.Literal('authorization_code')), + grant_type: Schema.Union([Schema.Literal('authorization_code')]), redirect_uri: Schema.String, code_verifier: Schema.String, }); -interface TokenRequestBody extends Schema.Schema.Type {} -const TokenRequestBody: Schema.Schema = _TokenRequestBody; +type TokenRequestBody = Schema.Schema.Type; +const TokenRequestBody: Schema.Schema = _TokenRequestBody; const _TokenResponseBody = Schema.Struct({ access_token: Schema.String, @@ -26,7 +26,7 @@ const _TokenResponseBody = Schema.Struct({ id_token: Schema.String, }); -interface TokenResponseBody extends Schema.Schema.Type {} -const TokenResponseBody: Schema.Schema = _TokenResponseBody; +type TokenResponseBody = Schema.Schema.Type; +const TokenResponseBody: Schema.Schema = _TokenResponseBody; export { TokenRequestBody, TokenResponseBody }; diff --git a/e2e/mock-api-v2/src/services/mock-env-helpers/index.ts b/e2e/mock-api-v2/src/services/mock-env-helpers/index.ts index b435ad59f39..58e552e93f2 100644 --- a/e2e/mock-api-v2/src/services/mock-env-helpers/index.ts +++ b/e2e/mock-api-v2/src/services/mock-env-helpers/index.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiError } from '@effect/platform'; import { Array, Effect, Option, pipe } from 'effect'; +import { HttpApiError } from 'effect/http-api'; import { UnableToFindNextStep } from '../../errors/index.js'; import { validator } from '../../helpers/match.js'; @@ -37,10 +37,9 @@ const getArrayFromResponseMap = (query: QueryTypes) => * to grab the array from the `responseMap`. */ const getNextStep = (bool: boolean, query: QueryTypes) => - Effect.if(bool, { - onTrue: () => getArrayFromResponseMap(query), - onFalse: () => Effect.fail(new UnableToFindNextStep()), - }); + Effect.suspend(() => + bool ? getArrayFromResponseMap(query) : Effect.fail(new UnableToFindNextStep()), + ); /** * Get the first element in the responseMap @@ -55,27 +54,25 @@ const getFirstElement = (arr: (typeof responseMap)[ResponseMapKeys]) => * */ const getFirstElementAndRespond = (query: QueryTypes) => - pipe( - Option.fromNullable(query?.acr_values), - Option.map((acr) => responseMap[acr as ResponseMapKeys]), - Effect.flatMap(getFirstElement), - Effect.catchTag('NoSuchElementException', () => new HttpApiError.NotFound()), - ); + Effect.gen(function* () { + const acr = query?.acr_values; + if (acr == null) return yield* Effect.fail(new HttpApiError.NotFound()); + const arr = responseMap[acr as ResponseMapKeys]; + if (!arr) return yield* Effect.fail(new HttpApiError.NotFound()); + return yield* getFirstElement(arr); + }); /** * helper function that dives into a request body for Capabilities Response * and will apply a validator function to ensure the request passes validation */ const validateCapabilitiesResponse = (body: any) => - pipe( - body, - Option.fromNullable, - Option.map((body) => body.parameters), - Option.map((parameters) => parameters.data), - Option.map((data) => data.formData), - Option.map((formData) => formData.value), - Effect.flatMap(validator), - ); + Effect.gen(function* () { + if (body == null) return yield* Effect.fail(new HttpApiError.InternalServerError()); + const value = body?.parameters?.data?.formData?.value; + if (value == null) return yield* Effect.fail(new HttpApiError.InternalServerError()); + return yield* validator(value); + }); export { getNextStep, diff --git a/e2e/mock-api-v2/src/services/session.service.ts b/e2e/mock-api-v2/src/services/session.service.ts index 26a3399cef9..e4ae3ce3170 100644 --- a/e2e/mock-api-v2/src/services/session.service.ts +++ b/e2e/mock-api-v2/src/services/session.service.ts @@ -1,4 +1,4 @@ -import { Effect } from 'effect'; +import { Context, Effect } from 'effect'; import { nanoid } from 'nanoid'; export type SessionData = { @@ -9,98 +9,104 @@ export type SessionData = { }; export interface SessionStorageApi { - createSession: (data: SessionData) => Effect.Effect; - getSession: (sessionId: string) => Effect.Effect; - deleteSession: (sessionId: string) => Effect.Effect; - updateSession: (sessionId: string, data: SessionData) => Effect.Effect; - refreshSession: (sessionId: string, expiryDate?: Date) => Effect.Effect; + createSession: (data: SessionData) => Effect.Effect; + getSession: (sessionId: string) => Effect.Effect; + deleteSession: (sessionId: string) => Effect.Effect; + updateSession: ( + sessionId: string, + data: SessionData, + ) => Effect.Effect; + refreshSession: (sessionId: string, expiryDate?: Date) => Effect.Effect; isSessionExpired: (sessionData: SessionData) => boolean; - cleanupExpiredSessions: () => Effect.Effect; + cleanupExpiredSessions: () => Effect.Effect; } -export class SessionStorage extends Effect.Service()('SessionStorage', { - sync: () => { - // In-memory session store - const _store = new Map(); - - // Check if a session is expired - const isSessionExpired = (sessionData: SessionData): boolean => { - const now = new Date(); - return sessionData.expiresAt < now; - }; - - return { - createSession: Effect.fn('CreateSessionMiddleware')(function* (data: SessionData) { - const sessionId = nanoid(); - _store.set(sessionId, data); - return data; - }), - - getSession: Effect.fn('GetSessionMiddleware')(function* (sessionId: string) { - const session = _store.get(sessionId); - - if (!session) { - return null; - } - - // Check if session is expired - if (isSessionExpired(session)) { - _store.delete(sessionId); - return null; - } - - return session; - }), - - deleteSession: Effect.fn('DeleteSessionMiddleware')(function* (sessionId: string) { - _store.delete(sessionId); - return undefined; - }), - - updateSession: Effect.fn('UpdateSessionMiddleware')(function* ( - sessionId: string, - data: SessionData, - ) { - if (!_store.has(sessionId)) { - return new Error('Session not found'); - } - _store.set(sessionId, data); - return data; - }), - - refreshSession: Effect.fn('RefreshSessionMiddleware')(function* ( - sessionId: string, - expiryDate?: Date, - ) { - const session = _store.get(sessionId); - - if (!session) { - return Effect.fail(new Error('Session not found')); - } - - if (isSessionExpired(session)) { - _store.delete(sessionId); - return new Error('Session has expired'); - } +export class SessionStorage extends Context.Service()( + 'SessionStorage', + { + make: Effect.sync(() => { + // In-memory session store + const _store = new Map(); + + // Check if a session is expired + const isSessionExpired = (sessionData: SessionData): boolean => { + const now = new Date(); + return sessionData.expiresAt < now; + }; + + return { + createSession: Effect.fn('CreateSessionMiddleware')(function* (data: SessionData) { + const sessionId = nanoid(); + _store.set(sessionId, data); + return data; + }), + + getSession: Effect.fn('GetSessionMiddleware')(function* (sessionId: string) { + const session = _store.get(sessionId); + + if (!session) { + return null; + } - // Update expiry date - const newExpiryDate = expiryDate || new Date(Date.now() + 24 * 60 * 60 * 1000); // Default: 24 hours from now - session.expiresAt = newExpiryDate; - _store.set(sessionId, session); + // Check if session is expired + if (isSessionExpired(session)) { + _store.delete(sessionId); + return null; + } - return session.data; - }), + return session; + }), - isSessionExpired, + deleteSession: Effect.fn('DeleteSessionMiddleware')(function* (sessionId: string) { + _store.delete(sessionId); + return undefined; + }), + + updateSession: Effect.fn('UpdateSessionMiddleware')(function* ( + sessionId: string, + data: SessionData, + ) { + if (!_store.has(sessionId)) { + return new Error('Session not found'); + } + _store.set(sessionId, data); + return data; + }), + + refreshSession: Effect.fn('RefreshSessionMiddleware')(function* ( + sessionId: string, + expiryDate?: Date, + ) { + const session = _store.get(sessionId); + + if (!session) { + return Effect.fail(new Error('Session not found')); + } - cleanupExpiredSessions: Effect.fn('CleanupExpiredSessionsMiddleware')(function* () { - for (const [sessionId, session] of _store.entries()) { if (isSessionExpired(session)) { _store.delete(sessionId); + return new Error('Session has expired'); + } + + // Update expiry date + const newExpiryDate = expiryDate || new Date(Date.now() + 24 * 60 * 60 * 1000); // Default: 24 hours from now + session.expiresAt = newExpiryDate; + _store.set(sessionId, session); + + return session.data; + }), + + isSessionExpired, + + cleanupExpiredSessions: Effect.fn('CleanupExpiredSessionsMiddleware')(function* () { + for (const [sessionId, session] of _store.entries()) { + if (isSessionExpired(session)) { + _store.delete(sessionId); + } } - } - return undefined; - }), - }; + return undefined; + }), + }; + }), }, -}) {} +) {} diff --git a/e2e/mock-api-v2/src/services/tokens.service.ts b/e2e/mock-api-v2/src/services/tokens.service.ts index acd15c4c2d2..994573fea35 100644 --- a/e2e/mock-api-v2/src/services/tokens.service.ts +++ b/e2e/mock-api-v2/src/services/tokens.service.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiError } from '@effect/platform'; import { Context, Effect, Layer } from 'effect'; +import { HttpApiError } from 'effect/http-api'; import { revokeResponseBody } from '../responses/revoke/revoke.js'; import { tokenResponseBody } from '../responses/token/token.js'; @@ -19,7 +19,7 @@ import type { HeaderTypes } from '../types/index.js'; type TokensResponseBody = Schema.Schema.Type; type RevokeTokenResponseBody = Schema.Schema.Type; -class Tokens extends Context.Tag('@services/Tokens')< +class Tokens extends Context.Service< Tokens, { getTokens: ( @@ -30,31 +30,28 @@ class Tokens extends Context.Tag('@services/Tokens')< tokenTypeHint?: string, ) => Effect.Effect; } ->() {} - -const TokensMock = Layer.succeed( - Tokens, - Tokens.of({ - getTokens: () => - Effect.gen(function* () { - const response = yield* Effect.tryPromise({ - try: () => Promise.resolve(tokenResponseBody), - catch: () => new HttpApiError.Unauthorized(), - }); - return response; - }), - revokeToken: (token) => - Effect.gen(function* () { - // Apply the REVOKED_ prefix to the token - // This is a simple way to mark tokens as revoked without maintaining state - // The Authorization middleware will check for this prefix - yield* Effect.log('Revoking token', { token, newToken: `REVOKED_${token}` }); - - // In a real implementation, we might store the token in a revocation list - // or update it in a database. For this mock, we'll just return success. - return revokeResponseBody; - }), - }), -); +>()('@services/Tokens') {} + +const TokensMock = Layer.succeed(Tokens, { + getTokens: () => + Effect.gen(function* () { + const response = yield* Effect.tryPromise({ + try: () => Promise.resolve(tokenResponseBody), + catch: () => new HttpApiError.Unauthorized(), + }); + return response; + }), + revokeToken: (token) => + Effect.gen(function* () { + // Apply the REVOKED_ prefix to the token + // This is a simple way to mark tokens as revoked without maintaining state + // The Authorization middleware will check for this prefix + yield* Effect.log('Revoking token', { token, newToken: `REVOKED_${token}` }); + + // In a real implementation, we might store the token in a revocation list + // or update it in a database. For this mock, we'll just return success. + return revokeResponseBody; + }), +}); export { TokensMock, Tokens }; diff --git a/e2e/mock-api-v2/src/services/userinfo.service.ts b/e2e/mock-api-v2/src/services/userinfo.service.ts index 015619e3a2a..d9162219053 100644 --- a/e2e/mock-api-v2/src/services/userinfo.service.ts +++ b/e2e/mock-api-v2/src/services/userinfo.service.ts @@ -4,9 +4,9 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApiError } from '@effect/platform'; -import { Layer } from 'effect'; -import { Context, Effect } from 'effect'; +import { Context, Layer } from 'effect'; +import { Effect } from 'effect'; +import { HttpApiError } from 'effect/http-api'; import { userInfoResponse } from '../responses/userinfo/userinfo.js'; @@ -20,25 +20,22 @@ import type { UserInfoSchema } from '../schemas/userinfo/userinfo.schema.js'; type UserInfoResponse = Schema.Schema.Type; -class UserInfo extends Context.Tag('@services/userinfo')< +class UserInfo extends Context.Service< UserInfo, { getUserInfo: ( token: string, ) => Effect.Effect; } ->() {} - -const UserInfoMockService = Layer.succeed( - UserInfo, - UserInfo.of({ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - getUserInfo: (_: string) => - Effect.tryPromise({ - try: () => Promise.resolve(userInfoResponse), - catch: () => new HttpApiError.Unauthorized(), - }), - }), -); +>()('@services/userinfo') {} + +const UserInfoMockService = Layer.succeed(UserInfo, { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + getUserInfo: (_: string) => + Effect.tryPromise({ + try: () => Promise.resolve(userInfoResponse), + catch: () => new HttpApiError.Unauthorized(), + }), +}); export { UserInfo, UserInfoMockService }; diff --git a/e2e/mock-api-v2/src/spec.ts b/e2e/mock-api-v2/src/spec.ts index d8fc3e14ba8..72abb429773 100644 --- a/e2e/mock-api-v2/src/spec.ts +++ b/e2e/mock-api-v2/src/spec.ts @@ -4,8 +4,8 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from '@effect/platform'; import { Schema } from 'effect'; +import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from 'effect/http-api'; import { addStepCookie } from './addStepCookie.openapi.js'; import { Authorization } from './middleware/Authorization.js'; @@ -45,8 +45,9 @@ const MockApi = HttpApi.make('MyApi') // Healthcheck .add( HttpApiGroup.make('Healthcheck').add( - HttpApiEndpoint.get('HealthCheck')`/healthcheck` - .addSuccess(Schema.String) + HttpApiEndpoint.get('HealthCheck', '/healthcheck', { + success: Schema.String, + }) .annotate(OpenApi.Summary, 'Server Health Check') .annotate( OpenApi.Description, @@ -57,13 +58,13 @@ const MockApi = HttpApi.make('MyApi') // Authorization .add( HttpApiGroup.make('Authorization').add( - HttpApiEndpoint.get('authorize', `/:envid/davinci/authorize`) - .setPath(Schema.Struct({ envid: Schema.String })) - .setHeaders(DavinciAuthorizeHeaders) - .setUrlParams(DavinciAuthorizeQuery) - .addSuccess(CapabilitiesResponse) - .addError(HttpApiError.NotFound) - .addError(HttpApiError.InternalServerError) + HttpApiEndpoint.get('authorize', `/:envid/davinci/authorize`, { + params: Schema.Struct({ envid: Schema.String }), + headers: DavinciAuthorizeHeaders, + query: DavinciAuthorizeQuery, + success: CapabilitiesResponse, + error: [HttpApiError.NotFound, HttpApiError.InternalServerError], + }) .annotate(OpenApi.Summary, 'Authorization Endpoint') .annotate( OpenApi.Description, @@ -78,23 +79,27 @@ const MockApi = HttpApi.make('MyApi') HttpApiEndpoint.post( 'capabilities', `/:envid/davinci/connections/:connectionID/capabilities/:capabilityName`, - ) - .setPayload(CapabilitiesRequestBody) - .setPath(CapabilitiesPathParams) - - .setHeaders(CapabilitiesHeaders) - .addSuccess(CapabilitiesResponse) - .addError(HttpApiError.NotFound) - .addError(HttpApiError.Unauthorized) - .addError(HttpApiError.InternalServerError), + { + payload: CapabilitiesRequestBody, + params: CapabilitiesPathParams, + headers: CapabilitiesHeaders, + success: CapabilitiesResponse, + error: [ + HttpApiError.NotFound, + HttpApiError.Unauthorized, + HttpApiError.InternalServerError, + ], + }, + ), ) .middleware(IncrementStepIndex), ) .add( HttpApiGroup.make('OpenIDConfig').add( - HttpApiEndpoint.get('openid', `/:envid/as/.well-known/openid-configuration`) - .setPath(Schema.Struct({ envid: Schema.String })) - .addSuccess(openIdConfigurationResponseSchema) + HttpApiEndpoint.get('openid', `/:envid/as/.well-known/openid-configuration`, { + params: Schema.Struct({ envid: Schema.String }), + success: openIdConfigurationResponseSchema, + }) .annotate(OpenApi.Summary, 'OIDC Configuration') .annotate( OpenApi.Description, @@ -106,10 +111,11 @@ const MockApi = HttpApi.make('MyApi') .add( HttpApiGroup.make('Tokens') .add( - HttpApiEndpoint.post('Tokens', `/:envid/as/token`) - .addSuccess(TokenResponseBody) - .addError(HttpApiError.Unauthorized) - .setPath(Schema.Struct({ envid: Schema.String })) + HttpApiEndpoint.post('Tokens', `/:envid/as/token`, { + params: Schema.Struct({ envid: Schema.String }), + success: TokenResponseBody, + error: HttpApiError.Unauthorized, + }) .annotate(OpenApi.Summary, 'Token Endpoint') .annotate( OpenApi.Description, @@ -123,10 +129,11 @@ const MockApi = HttpApi.make('MyApi') .add( HttpApiGroup.make('ProtectedRequests') .add( - HttpApiEndpoint.get('UserInfo', `/:envid/as/userinfo`) - .setPath(Schema.Struct({ envid: Schema.String })) - .addSuccess(UserInfoSchema) - .addError(HttpApiError.Unauthorized) + HttpApiEndpoint.get('UserInfo', `/:envid/as/userinfo`, { + params: Schema.Struct({ envid: Schema.String }), + success: UserInfoSchema, + error: HttpApiError.Unauthorized, + }) .annotate(OpenApi.Summary, 'UserInfo Endpoint') .annotate( OpenApi.Description, @@ -140,21 +147,20 @@ const MockApi = HttpApi.make('MyApi') .add( HttpApiGroup.make('SessionManagement') .add( - HttpApiEndpoint.get('EndSession', `/:envid/as/endSession`) - .setPath(EndSessionPath) - .setUrlParams(EndSessionQuery) - .setHeaders(EndSessionHeaders) - .addSuccess( - Schema.Union( - Schema.String, - Schema.Struct({ - status: Schema.Number, - headers: Schema.Record({ key: Schema.String, value: Schema.String }), - body: Schema.String, - }), - ), - ) - .addError(HttpApiError.Unauthorized) + HttpApiEndpoint.get('EndSession', `/:envid/as/endSession`, { + params: EndSessionPath, + query: EndSessionQuery, + headers: EndSessionHeaders, + success: Schema.Union([ + Schema.String, + Schema.Struct({ + status: Schema.Number, + headers: Schema.Record(Schema.String, Schema.String), + body: Schema.String, + }), + ]), + error: HttpApiError.Unauthorized, + }) .annotate(OpenApi.Summary, 'End Session Endpoint') .annotate( OpenApi.Description, @@ -164,31 +170,15 @@ const MockApi = HttpApi.make('MyApi') .middleware(Authorization) .middleware(SessionMiddleware), ) - // Protected Requests - .add( - HttpApiGroup.make('ProtectedRequests') - .add( - HttpApiEndpoint.get('UserInfo', `/:envid/as/userinfo`) - .setPath(Schema.Struct({ envid: Schema.String })) - .addSuccess(UserInfoSchema) - .addError(HttpApiError.Unauthorized) - .annotate(OpenApi.Summary, 'UserInfo Endpoint') - .annotate( - OpenApi.Description, - 'Returns claims about the authenticated end-user. Requires a valid access token.', - ), - ) - .middleware(Authorization) - .middleware(SessionMiddleware), - ) .add( HttpApiGroup.make('Revoke') .add( - HttpApiEndpoint.post('RevokeToken', `/:envid/as/revoke`) - .setPath(RevokePath) - .setPayload(RevokeRequestBody) - .addSuccess(RevokeResponseBody) - .addError(HttpApiError.Unauthorized) + HttpApiEndpoint.post('RevokeToken', `/:envid/as/revoke`, { + params: RevokePath, + payload: RevokeRequestBody, + success: RevokeResponseBody, + error: HttpApiError.Unauthorized, + }) .annotate(OpenApi.Summary, 'Token Revocation Endpoint') .annotate( OpenApi.Description, @@ -196,7 +186,7 @@ const MockApi = HttpApi.make('MyApi') ), ) .middleware(Authorization) - .middleware(SessionMiddleware), // Applies to token, end session, revoke + .middleware(SessionMiddleware), ) // Middlewares for relevant endpoints .annotate( diff --git a/e2e/mock-api-v2/src/types/index.ts b/e2e/mock-api-v2/src/types/index.ts index 7d0974462d6..23cc017a7a6 100644 --- a/e2e/mock-api-v2/src/types/index.ts +++ b/e2e/mock-api-v2/src/types/index.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/package.json b/package.json index a9616558b08..de65cb1b0fa 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,6 @@ "@commitlint/cli": "^20.0.0", "@commitlint/config-conventional": "^20.0.0", "@commitlint/prompt": "^20.0.0", - "@effect/cli": "catalog:effect", "@eslint/eslintrc": "^3.0.0", "@eslint/js": "~9.39.0", "@evilmartians/lefthook": "^2.1.4", @@ -86,7 +85,7 @@ "@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/utils": "^8.13.0", "@vitest/coverage-v8": "catalog:vitest", - "@vitest/ui": "4.1.11", + "@vitest/ui": "catalog:vitest", "conventional-changelog-conventionalcommits": "^8.0.0", "cz-conventional-changelog": "^3.3.0", "cz-git": "^1.6.1", diff --git a/packages/davinci-client/api-report/davinci-client.api.md b/packages/davinci-client/api-report/davinci-client.api.md index f324e08d857..bf95755edd4 100644 --- a/packages/davinci-client/api-report/davinci-client.api.md +++ b/packages/davinci-client/api-report/davinci-client.api.md @@ -1,2443 +1,2021 @@ -## API Report File for "@forgerock/davinci-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import type { DaVinciConfig } from '@forgerock/sdk-types'; -import { FetchBaseQueryError } from '@reduxjs/toolkit/query'; -import type { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; -import type { GenericError } from '@forgerock/sdk-types'; -import { LogLevel } from '@forgerock/sdk-logger'; -import { makeDavinciConfig } from '@forgerock/sdk-utilities'; -import type { MutationResultSelectorResult } from '@reduxjs/toolkit/query'; -import { QueryStatus } from '@reduxjs/toolkit/query'; -import { Reducer } from '@reduxjs/toolkit'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { SerializedError } from '@reduxjs/toolkit'; -import { Unsubscribe } from '@reduxjs/toolkit'; - -// @public (undocumented) -export type ActionCollector = - | ActionCollectorNoUrl - | ActionCollectorWithUrl; - -// @public (undocumented) -export interface ActionCollectorNoUrl { - // (undocumented) - category: 'ActionCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ActionCollectors = - | ActionCollectorWithUrl<'IdpCollector'> - | ActionCollectorNoUrl<'ActionCollector'> - | ActionCollectorNoUrl<'FlowCollector'> - | ActionCollectorNoUrl<'SubmitCollector'>; - -// @public -export type ActionCollectorTypes = - | 'FlowCollector' - | 'SubmitCollector' - | 'IdpCollector' - | 'ActionCollector'; - -// @public (undocumented) -export interface ActionCollectorWithUrl { - // (undocumented) - category: 'ActionCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - url?: string | null; - }; - // (undocumented) - type: T; -} - -export { ActionTypes }; - -// @public (undocumented) -export type AgreementField = { - type: 'AGREEMENT'; - key: string; - content: string; - titleEnabled: boolean; - title?: string; - agreement: { - id: string; - useDynamicAgreement: boolean; - }; - enabled: boolean; -}; - -// @public (undocumented) -export interface AssertionValue extends Omit< - PublicKeyCredential, - 'rawId' | 'response' | 'getClientExtensionResults' | 'toJSON' -> { - // (undocumented) - rawId: string; - // (undocumented) - response: { - clientDataJSON: string; - authenticatorData: string; - signature: string; - userHandle: string | null; - }; -} - -// @public (undocumented) -export interface AttestationValue extends Omit< - PublicKeyCredential, - 'rawId' | 'response' | 'getClientExtensionResults' | 'toJSON' -> { - // (undocumented) - rawId: string; - // (undocumented) - response: { - clientDataJSON: string; - attestationObject: string; - }; -} - -// @public (undocumented) -export interface AutoCollector< - C extends AutoCollectorCategories, - T extends AutoCollectorTypes, - IV = string, - OV = Record, -> { - // (undocumented) - category: C; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: IV; - type: string; - validation?: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - type: string; - config: OV; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type AutoCollectorCategories = 'SingleValueAutoCollector' | 'ObjectValueAutoCollector'; - -// @public (undocumented) -export type AutoCollectors = - | ProtectCollector - | FidoRegistrationCollector - | FidoAuthenticationCollector - | MetadataCollector - | PollingCollector - | SingleValueAutoCollector - | ObjectValueAutoCollector; - -// @public (undocumented) -export type AutoCollectorTypes = SingleValueAutoCollectorTypes | ObjectValueAutoCollectorTypes; - -// @public (undocumented) -export interface BooleanCollector extends SingleValueCollectorWithValue< - 'BooleanCollector', - boolean -> { - // (undocumented) - output: SingleValueCollectorWithValue<'BooleanCollector', boolean>['output'] & { - appearance: string; - richContent?: CollectorRichContent; - }; -} - -// @public (undocumented) -export type CollectorCategory = Collectors['category']; - -// @public (undocumented) -export interface CollectorErrors { - // (undocumented) - code: string; - // (undocumented) - message: string; - // (undocumented) - target: string; -} - -// @public -export interface CollectorRichContent { - // (undocumented) - content: string; - // (undocumented) - replacements: RichContentLink[]; -} - -// @public (undocumented) -export type Collectors = - | FlowCollector - | MetadataCollector - | PasswordCollector - | ValidatedPasswordCollector - | TextCollector - | BooleanCollector - | ValidatedBooleanCollector - | SingleSelectCollector - | IdpCollector - | SubmitCollector - | ActionCollector<'ActionCollector'> - | SingleValueCollector<'SingleValueCollector'> - | MultiSelectCollector - | DeviceAuthenticationCollector - | DeviceRegistrationCollector - | PhoneNumberCollector - | PhoneNumberExtensionCollector - | ReadOnlyCollector - | RichTextCollector - | ValidatedTextCollector - | ProtectCollector - | PollingCollector - | FidoRegistrationCollector - | FidoAuthenticationCollector - | QrCodeCollector - | ImageCollector - | UnknownCollector; - -// @public -export type CollectorValueType = T extends - | { - type: 'PasswordCollector'; - } - | { - type: 'ValidatedPasswordCollector'; - } - | { - type: 'SingleSelectCollector'; - } - | { - type: 'DeviceRegistrationCollector'; - } - | { - type: 'DeviceAuthenticationCollector'; - } - | { - type: 'ProtectCollector'; - } - | { - type: 'PollingCollector'; - } - ? string - : T extends { - type: 'TextCollector'; - category: 'SingleValueCollector'; - } - ? string - : T extends { - type: 'TextCollector'; - category: 'ValidatedSingleValueCollector'; - } - ? string - : T extends - | { - type: 'BooleanCollector'; - } - | { - type: 'ValidatedBooleanCollector'; - } - ? boolean - : T extends { - type: 'MultiSelectCollector'; - } - ? string | string[] - : T extends { - type: 'PhoneNumberCollector'; - } - ? PhoneNumberInputValue - : T extends { - type: 'PhoneNumberExtensionCollector'; - } - ? PhoneNumberExtensionInputValue - : T extends { - type: 'FidoRegistrationCollector'; - } - ? FidoRegistrationInputValue | GenericError - : T extends { - type: 'FidoAuthenticationCollector'; - } - ? FidoAuthenticationInputValue | GenericError - : T extends { - type: 'MetadataCollector'; - } - ? Record | MetadataError - : T extends { - category: 'SingleValueCollector'; - } - ? string - : T extends { - category: 'ValidatedSingleValueCollector'; - } - ? string - : T extends { - category: 'SingleValueAutoCollector'; - } - ? string - : T extends { - category: 'MultiValueCollector'; - } - ? string | string[] - : T extends { - category: 'ActionCollector'; - } - ? never - : T extends { - category: 'NoValueCollector'; - } - ? never - : CollectorValueTypes; - -// @public -export type CollectorValueTypes = - | string - | string[] - | boolean - | PhoneNumberInputValue - | PhoneNumberExtensionInputValue - | FidoRegistrationInputValue - | FidoAuthenticationInputValue - | MetadataError - | GenericError; - -// @public (undocumented) -export type ComplexValueFields = - | DeviceAuthenticationField - | DeviceRegistrationField - | PhoneNumberField - | PhoneNumberExtensionField - | FidoRegistrationField - | FidoAuthenticationField - | PollingField - | MetadataField; - -// @public (undocumented) -export interface ContinueNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'continue'; - }; - // (undocumented) - error: null; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - eventName?: string; - status: 'continue'; - }; - // (undocumented) - status: 'continue'; -} - -export { CustomLogger }; - -// @public -export type CustomPollingStatus = string & {}; - -// @public -export function davinci(input: { - config: DaVinciConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; -}): Promise<{ - subscribe: (listener: () => void) => Unsubscribe; - externalIdp: () => () => Promise; - flow: (action: DaVinciAction) => InitFlow; - next: (args?: DaVinciRequest) => Promise; - resume: (input: { continueToken: string }) => Promise; - start: ( - options?: StartOptions | undefined, - ) => Promise; - update: (collector: T) => Updater; - validate: ( - collector: - | SingleValueCollectors - | ObjectValueCollectors - | MultiValueCollectors - | AutoCollectors, - ) => Validator; - pollStatus: (collector: PollingCollector) => Poller; - getClient: () => - | { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'continue'; - } - | { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'error'; - } - | { - status: 'failure'; - } - | { - status: 'start'; - } - | { - authorization?: { - code?: string; - state?: string; - }; - status: 'success'; - } - | null; - getCollectors: () => Collectors[]; - getError: () => DaVinciError | null; - getErrorCollectors: () => CollectorErrors[]; - getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode; - getServer: () => - | { - _links?: Links; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - eventName?: string; - status: 'continue'; - } - | { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'error'; - } - | { - _links?: Links; - eventName?: string; - href?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'failure'; - } - | { - status: 'start'; - } - | { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - session?: string; - status: 'success'; - } - | null; - cache: { - getLatestResponse: () => - | ({ - status: QueryStatus.fulfilled; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > - > & { - error: undefined; - } & { - status: QueryStatus.fulfilled; - isUninitialized: false; - isLoading: false; - isSuccess: true; - isError: false; - }) - | ({ - status: QueryStatus.rejected; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > - > & { - status: QueryStatus.rejected; - isUninitialized: false; - isLoading: false; - isSuccess: false; - isError: true; - }) - | { - error: { - message: string; - type: string; - }; - }; - getResponseWithId: (requestId: string) => - | ({ - status: QueryStatus.fulfilled; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > - > & { - error: undefined; - } & { - status: QueryStatus.fulfilled; - isUninitialized: false; - isLoading: false; - isSuccess: true; - isError: false; - }) - | ({ - status: QueryStatus.rejected; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > - > & { - status: QueryStatus.rejected; - isUninitialized: false; - isLoading: false; - isSuccess: false; - isError: true; - }) - | { - error: { - message: string; - type: string; - }; - }; - }; -}>; - -// @public -export interface DaVinciAction { - // (undocumented) - action: string; -} - -// @public -export interface DaVinciBaseResponse { - // (undocumented) - capabilityName?: string; - // (undocumented) - companyId?: string; - // (undocumented) - connectionId?: string; - // (undocumented) - connectorId?: string; - // (undocumented) - id?: string; - // (undocumented) - interactionId?: string; - // (undocumented) - interactionToken?: string; - // (undocumented) - isResponseCompatibleWithMobileAndWebSdks?: boolean; - // (undocumented) - status?: string; -} - -// @public -export type DaVinciCacheEntry = { - data?: DaVinciBaseResponse; - error?: { - data: DaVinciBaseResponse; - status: number; - }; -} & { - data?: any; - error?: any; -} & MutationResultSelectorResult; - -// @public (undocumented) -export type DavinciClient = Awaited>; - -export { DaVinciConfig }; - -// @public (undocumented) -export interface DaVinciError extends Omit { - // (undocumented) - collectors?: CollectorErrors[]; - // (undocumented) - internalHttpStatus?: number; - // (undocumented) - message: string; - // (undocumented) - status: 'error' | 'failure' | 'unknown'; -} - -// @public (undocumented) -export interface DaVinciErrorCacheEntry { - // (undocumented) - endpointName: 'next' | 'flow' | 'start'; - // (undocumented) - error: { - data: T; - }; - // (undocumented) - fulfilledTimeStamp: number; - // (undocumented) - isError: boolean; - // (undocumented) - isLoading: boolean; - // (undocumented) - isSuccess: boolean; - // (undocumented) - isUninitialized: boolean; - // (undocumented) - requestId: string; - // (undocumented) - startedTimeStamp: number; - // (undocumented) - status: 'fulfilled' | 'pending' | 'rejected'; -} - -// @public (undocumented) -export interface DavinciErrorResponse extends DaVinciBaseResponse { - // (undocumented) - cause?: string | null; - // (undocumented) - code: string | number; - // (undocumented) - details?: ErrorDetail[]; - // (undocumented) - doNotSendToOE?: boolean; - // (undocumented) - error?: { - code?: string; - message?: string; - }; - // (undocumented) - errorCategory?: string; - // (undocumented) - errorMessage?: string; - // (undocumented) - expected?: boolean; - // (undocumented) - httpResponseCode: number; - // (undocumented) - isErrorCustomized?: boolean; - // (undocumented) - message: string; - // (undocumented) - metricAttributes?: { - [key: string]: unknown; - }; -} - -// @public (undocumented) -export interface DaVinciFailureResponse extends DaVinciBaseResponse { - // (undocumented) - error?: { - code?: string; - message?: string; - [key: string]: unknown; - }; -} - -// @public (undocumented) -export type DaVinciField = - | ComplexValueFields - | MultiValueFields - | ReadOnlyFields - | RedirectFields - | SingleValueFields; - -// @public -export interface DaVinciNextResponse extends DaVinciBaseResponse { - // (undocumented) - eventName?: string; - // (undocumented) - form?: { - name?: string; - description?: string; - components?: { - fields?: DaVinciField[]; - }; - }; - // (undocumented) - formData?: { - value?: { - [key: string]: string; - }; - }; - // (undocumented) - _links?: Links; -} - -// @public -export interface DaVinciPollResponse extends DaVinciBaseResponse { - // (undocumented) - eventName?: string; - // (undocumented) - _links?: Links; - // (undocumented) - success?: boolean; -} - -// @public (undocumented) -export interface DaVinciRequest { - // (undocumented) - eventName: string; - // (undocumented) - id: string; - // (undocumented) - interactionId: string; - // (undocumented) - parameters: { - eventType: 'submit' | 'action' | 'polling'; - data: { - actionKey: string; - formData?: Record; - }; - }; -} - -// @public -export type DaVinciRequestValueTypes = - | string - | number - | boolean - | (string | number | boolean)[] - | DeviceValue - | PhoneNumberInputValue - | FidoRegistrationInputValue - | FidoAuthenticationInputValue - | MetadataError - | GenericError; - -// @public (undocumented) -export interface DaVinciSuccessResponse extends DaVinciBaseResponse { - // (undocumented) - authorizeResponse?: OAuthDetails; - // (undocumented) - environment: { - id: string; - [key: string]: unknown; - }; - // (undocumented) - _links?: Links; - // (undocumented) - resetCookie?: boolean; - // (undocumented) - session?: { - id?: string; - [key: string]: unknown; - }; - // (undocumented) - sessionToken?: string; - // (undocumented) - sessionTokenMaxAge?: number; - // (undocumented) - status: string; - // (undocumented) - subFlowSettings?: { - cssLinks?: unknown[]; - cssUrl?: unknown; - jsLinks?: unknown[]; - loadingScreenSettings?: unknown; - reactSkUrl?: unknown; - }; - // (undocumented) - success: true; -} - -// @public (undocumented) -export type DeviceAuthenticationCollector = ObjectOptionsCollectorWithObjectValue< - 'DeviceAuthenticationCollector', - DeviceValue ->; - -// @public (undocumented) -export type DeviceAuthenticationField = { - type: 'DEVICE_AUTHENTICATION'; - key: string; - label: string; - options: { - type: string; - iconSrc: string; - title: string; - id: string; - default: boolean; - description: string; - }[]; - required: boolean; -}; - -// @public (undocumented) -export interface DeviceOptionNoDefault { - // (undocumented) - content: string; - // (undocumented) - key: string; - // (undocumented) - label: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export interface DeviceOptionWithDefault { - // (undocumented) - content: string; - // (undocumented) - default: boolean; - // (undocumented) - key: string; - // (undocumented) - label: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export type DeviceRegistrationCollector = ObjectOptionsCollectorWithStringValue< - 'DeviceRegistrationCollector', - string ->; - -// @public (undocumented) -export type DeviceRegistrationField = { - type: 'DEVICE_REGISTRATION'; - key: string; - label: string; - options: { - type: string; - iconSrc: string; - title: string; - description: string; - }[]; - required: boolean; -}; - -// @public (undocumented) -export interface DeviceValue { - // (undocumented) - id: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export interface ErrorDetail { - // (undocumented) - message?: string; - // (undocumented) - rawResponse?: { - _embedded?: { - users?: Array; - }; - code?: string; - count?: number; - details?: NestedErrorDetails[]; - id?: string; - message?: string; - size?: number; - userFilter?: string; - [key: string]: unknown; - }; - // (undocumented) - statusCode?: number; -} - -// @public (undocumented) -export interface ErrorNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'error'; - }; - // (undocumented) - error: DaVinciError; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'error'; - } | null; - // (undocumented) - status: 'error'; -} - -// @public (undocumented) -export interface FailureNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - status: 'failure'; - }; - // (undocumented) - error: DaVinciError; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - href?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'failure'; - } | null; - // (undocumented) - status: 'failure'; -} - -// @public -export function fido(): FidoClient; - -// @public (undocumented) -export type FidoAuthenticationCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'FidoAuthenticationCollector', - FidoAuthenticationInputValue | GenericError, - FidoAuthenticationOutputValue ->; - -// @public (undocumented) -export type FidoAuthenticationField = { - type: 'FIDO2'; - key: string; - label: string; - publicKeyCredentialRequestOptions: FidoAuthenticationOptions; - action: 'AUTHENTICATE'; - trigger: string; - required: boolean; -}; - -// @public (undocumented) -export interface FidoAuthenticationInputValue { - // (undocumented) - assertionValue?: AssertionValue; -} - -// @public (undocumented) -export interface FidoAuthenticationOptions extends Omit< - PublicKeyCredentialRequestOptions, - 'challenge' | 'allowCredentials' -> { - // (undocumented) - allowCredentials?: { - id: number[]; - transports?: AuthenticatorTransport[]; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - challenge: number[]; -} - -// @public (undocumented) -export interface FidoAuthenticationOutputValue { - // (undocumented) - action: 'AUTHENTICATE'; - // (undocumented) - publicKeyCredentialRequestOptions: FidoAuthenticationOptions; - // (undocumented) - trigger: string; -} - -// @public (undocumented) -export interface FidoClient { - authenticate: ( - options: FidoAuthenticationOptions, - ) => Promise; - register: ( - options: FidoRegistrationOptions, - ) => Promise; -} - -// @public -export type FidoErrorCode = - | 'NotAllowedError' - | 'AbortError' - | 'InvalidStateError' - | 'NotSupportedError' - | 'SecurityError' - | 'TimeoutError' - | 'UnknownError'; - -// @public (undocumented) -export type FidoRegistrationCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'FidoRegistrationCollector', - FidoRegistrationInputValue | GenericError, - FidoRegistrationOutputValue ->; - -// @public (undocumented) -export type FidoRegistrationField = { - type: 'FIDO2'; - key: string; - label: string; - publicKeyCredentialCreationOptions: FidoRegistrationOptions; - action: 'REGISTER'; - trigger: string; - required: boolean; -}; - -// @public (undocumented) -export interface FidoRegistrationInputValue { - // (undocumented) - attestationValue?: AttestationValue; -} - -// @public (undocumented) -export interface FidoRegistrationOptions extends Omit< - PublicKeyCredentialCreationOptions, - 'challenge' | 'user' | 'pubKeyCredParams' | 'excludeCredentials' -> { - // (undocumented) - challenge: number[]; - // (undocumented) - excludeCredentials?: { - id: number[]; - transports?: AuthenticatorTransport[]; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - pubKeyCredParams: { - alg: string | number; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - user: { - id: number[]; - name: string; - displayName: string; - }; -} - -// @public (undocumented) -export interface FidoRegistrationOutputValue { - // (undocumented) - action: 'REGISTER'; - // (undocumented) - publicKeyCredentialCreationOptions: FidoRegistrationOptions; - // (undocumented) - trigger: string; -} - -// @public (undocumented) -export type FlowCollector = ActionCollectorNoUrl<'FlowCollector'>; - -// @public (undocumented) -export type FlowNode = ContinueNode | ErrorNode | StartNode | SuccessNode | FailureNode; - -// @public -export type GetClient = - | StartNode['client'] - | ContinueNode['client'] - | ErrorNode['client'] - | SuccessNode['client'] - | FailureNode['client']; - -// @public (undocumented) -export type IdpCollector = ActionCollectorWithUrl<'IdpCollector'>; - -// @public -export interface ImageCollector extends NoValueCollectorBase<'ImageCollector'> { - // (undocumented) - output: NoValueCollectorBase<'ImageCollector'>['output'] & { - src: string; - alt: string; - href?: string; - }; -} - -// @public (undocumented) -export type ImageField = { - type: 'IMAGE'; - key: string; - description: string; - imageUrl: string; - hyperlinkUrl?: string; -}; - -// @public (undocumented) -export type InferActionCollectorType = T extends 'IdpCollector' - ? IdpCollector - : T extends 'SubmitCollector' - ? SubmitCollector - : T extends 'FlowCollector' - ? FlowCollector - : ActionCollectorWithUrl<'ActionCollector'> | ActionCollectorNoUrl<'ActionCollector'>; - -// @public -export type InferAutoCollectorType = T extends 'ProtectCollector' - ? ProtectCollector - : T extends 'PollingCollector' - ? PollingCollector - : T extends 'FidoRegistrationCollector' - ? FidoRegistrationCollector - : T extends 'FidoAuthenticationCollector' - ? FidoAuthenticationCollector - : T extends 'MetadataCollector' - ? MetadataCollector - : T extends 'ObjectValueAutoCollector' - ? ObjectValueAutoCollector - : SingleValueAutoCollector; - -// @public -export type InferMultiValueCollectorType = - T extends 'MultiSelectCollector' - ? MultiValueCollectorWithValue<'MultiSelectCollector'> - : - | MultiValueCollectorWithValue<'MultiValueCollector'> - | MultiValueCollectorNoValue<'MultiValueCollector'>; - -// @public -export type InferNoValueCollectorType = - T extends 'ReadOnlyCollector' - ? ReadOnlyCollector - : T extends 'RichTextCollector' - ? RichTextCollector - : T extends 'QrCodeCollector' - ? QrCodeCollector - : T extends 'ImageCollector' - ? ImageCollector - : NoValueCollectorBase<'NoValueCollector'>; - -// @public -export type InferSingleValueCollectorType = - T extends 'TextCollector' - ? TextCollector - : T extends 'SingleSelectCollector' - ? SingleSelectCollector - : T extends 'ValidatedTextCollector' - ? ValidatedTextCollector - : T extends 'PasswordCollector' - ? PasswordCollector - : T extends 'ValidatedPasswordCollector' - ? ValidatedPasswordCollector - : T extends 'BooleanCollector' - ? BooleanCollector - : T extends 'ValidatedBooleanCollector' - ? ValidatedBooleanCollector - : - | SingleValueCollectorWithValue<'SingleValueCollector'> - | SingleValueCollectorNoValue<'SingleValueCollector'>; - -// @public (undocumented) -export type InferValueObjectCollectorType = - T extends 'DeviceAuthenticationCollector' - ? DeviceAuthenticationCollector - : T extends 'DeviceRegistrationCollector' - ? DeviceRegistrationCollector - : T extends 'PhoneNumberCollector' - ? PhoneNumberCollector - : T extends 'PhoneNumberExtensionCollector' - ? PhoneNumberExtensionCollector - : - | ObjectOptionsCollectorWithObjectValue<'ObjectValueCollector'> - | ObjectOptionsCollectorWithStringValue<'ObjectValueCollector'>; - -// @public (undocumented) -export type InitFlow = () => Promise; - -// @public (undocumented) -export interface InternalErrorResponse { - // (undocumented) - error: Omit & { - message: string; - }; - // (undocumented) - type: 'internal_error'; -} - -// @public (undocumented) -export interface Links { - // (undocumented) - [key: string]: { - href?: string; - }; -} - -export { LogLevel }; - -export { makeDavinciConfig }; - -// @public (undocumented) -export type MetadataCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'MetadataCollector', - MetadataCollectorInputValue, - Record ->; - -// @public (undocumented) -export type MetadataCollectorInputValue = Record | MetadataError; - -// @public -export interface MetadataError { - // (undocumented) - code: string; - // (undocumented) - message: string; -} - -// @public (undocumented) -export type MetadataField = { - type: 'METADATA'; - key: string; - payload: Record; -}; - -// @public (undocumented) -export type MultiSelectCollector = MultiValueCollectorWithValue<'MultiSelectCollector'>; - -// @public (undocumented) -export type MultiSelectField = { - inputType: 'MULTI_SELECT'; - key: string; - label: string; - options: { - label: string; - value: string; - }[]; - required?: boolean; - type: 'CHECKBOX' | 'COMBOBOX'; -}; - -// @public (undocumented) -export type MultiValueCollector = - | MultiValueCollectorWithValue - | MultiValueCollectorNoValue; - -// @public (undocumented) -export interface MultiValueCollectorNoValue { - // (undocumented) - category: 'MultiValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string[]; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type MultiValueCollectors = - | MultiValueCollectorWithValue<'MultiValueCollector'> - | MultiValueCollectorWithValue<'MultiSelectCollector'>; - -// @public -export type MultiValueCollectorTypes = 'MultiSelectCollector' | 'MultiValueCollector'; - -// @public (undocumented) -export interface MultiValueCollectorWithValue { - // (undocumented) - category: 'MultiValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string[]; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: string[]; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type MultiValueFields = MultiSelectField; - -// @public -export interface NestedErrorDetails { - // (undocumented) - code?: string; - // (undocumented) - innerError?: { - history?: string; - unsatisfiedRequirements?: string[]; - failuresRemaining?: number; - }; - // (undocumented) - message?: string; - // (undocumented) - target?: string; -} - -// @public -export const nextCollectorValues: ActionCreatorWithPayload< - { - fields: DaVinciField[]; - formData: { - value: Record; - }; - }, - string ->; - -// @public -export const nodeCollectorReducer: Reducer & { - getInitialState: () => Collectors[]; -}; - -// @public (undocumented) -export type NodeStates = StartNode | ContinueNode | ErrorNode | SuccessNode | FailureNode; - -// @public (undocumented) -export type NoValueCollector = InferNoValueCollectorType; - -// @public (undocumented) -export interface NoValueCollectorBase { - // (undocumented) - category: 'NoValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type NoValueCollectors = - | NoValueCollectorBase<'NoValueCollector'> - | ReadOnlyCollector - | RichTextCollector - | QrCodeCollector - | ImageCollector; - -// @public -export type NoValueCollectorTypes = - | 'ReadOnlyCollector' - | 'RichTextCollector' - | 'NoValueCollector' - | 'QrCodeCollector' - | 'ImageCollector'; - -// @public -export interface OAuthDetails { - // (undocumented) - [key: string]: unknown; - // (undocumented) - code?: string; - // (undocumented) - state?: string; -} - -// @public (undocumented) -export interface ObjectOptionsCollectorWithObjectValue< - T extends ObjectValueCollectorTypes, - V = Record, - D = Record, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: DeviceOptionWithDefault[]; - value?: D | null; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface ObjectOptionsCollectorWithStringValue< - T extends ObjectValueCollectorTypes, - V = string, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: DeviceOptionNoDefault[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ObjectValueAutoCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'ObjectValueAutoCollector', - Record ->; - -// @public (undocumented) -export type ObjectValueAutoCollectorTypes = - | 'ObjectValueAutoCollector' - | 'FidoRegistrationCollector' - | 'FidoAuthenticationCollector' - | 'MetadataCollector'; - -// @public (undocumented) -export type ObjectValueCollector = - | ObjectOptionsCollectorWithObjectValue - | ObjectOptionsCollectorWithStringValue - | ObjectValueCollectorWithObjectValue; - -// @public (undocumented) -export type ObjectValueCollectors = - | DeviceAuthenticationCollector - | DeviceRegistrationCollector - | PhoneNumberCollector - | PhoneNumberExtensionCollector - | ObjectOptionsCollectorWithObjectValue<'ObjectSelectCollector'> - | ObjectOptionsCollectorWithStringValue<'ObjectSelectCollector'>; - -// @public -export type ObjectValueCollectorTypes = - | 'DeviceAuthenticationCollector' - | 'DeviceRegistrationCollector' - | 'PhoneNumberCollector' - | 'PhoneNumberExtensionCollector' - | 'ObjectOptionsCollector' - | 'ObjectValueCollector' - | 'ObjectSelectCollector'; - -// @public (undocumented) -export interface ObjectValueCollectorWithObjectValue< - T extends ObjectValueCollectorTypes, - IV = Record, - OV = Record, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: IV; - type: string; - validation: (ValidationRequired | ValidationPhoneNumber)[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value?: OV | null; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface OutgoingQueryParams { - // (undocumented) - [key: string]: string | string[]; -} - -// @public (undocumented) -export interface PasswordCollector { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - verify: boolean; - }; - // (undocumented) - type: 'PasswordCollector'; -} - -// @public -export type PasswordField = { - type: 'PASSWORD' | 'PASSWORD_VERIFY'; - key: string; - label: string; - required?: boolean; - verify?: boolean; - passwordPolicy?: PasswordPolicy; -}; - -// @public -export interface PasswordPolicy { - // (undocumented) - createdAt?: string; - // (undocumented) - default?: boolean; - // (undocumented) - description?: string; - // (undocumented) - excludesCommonlyUsed?: boolean; - // (undocumented) - excludesProfileData?: boolean; - // (undocumented) - history?: { - count?: number; - retentionDays?: number; - }; - // (undocumented) - id?: string; - // (undocumented) - length?: { - min?: number; - max?: number; - }; - // (undocumented) - lockout?: { - failureCount?: number; - durationSeconds?: number; - }; - // (undocumented) - maxAgeDays?: number; - // (undocumented) - maxRepeatedCharacters?: number; - // (undocumented) - minAgeDays?: number; - // (undocumented) - minCharacters?: Record; - // (undocumented) - minUniqueCharacters?: number; - // (undocumented) - name?: string; - // (undocumented) - notSimilarToCurrent?: boolean; - // (undocumented) - populationCount?: number; - // (undocumented) - updatedAt?: string; -} - -// @public (undocumented) -export type PhoneNumberCollector = ObjectValueCollectorWithObjectValue< - 'PhoneNumberCollector', - PhoneNumberInputValue, - PhoneNumberOutputValue ->; - -// @public (undocumented) -export interface PhoneNumberExtensionCollector { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: PhoneNumberExtensionInputValue; - type: string; - validation: (ValidationRequired | ValidationPhoneNumber)[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - extensionLabel: string; - value: PhoneNumberExtensionOutputValue; - }; - // (undocumented) - type: 'PhoneNumberExtensionCollector'; -} - -// @public (undocumented) -export type PhoneNumberExtensionField = PhoneNumberField & { - showExtension: boolean; - extensionLabel: string; -}; - -// @public (undocumented) -export interface PhoneNumberExtensionInputValue { - // (undocumented) - countryCode: string; - // (undocumented) - extension: string; - // (undocumented) - phoneNumber: string; -} - -// @public (undocumented) -export interface PhoneNumberExtensionOutputValue { - // (undocumented) - countryCode?: string; - // (undocumented) - extension?: string; - // (undocumented) - phoneNumber?: string; -} - -// @public (undocumented) -export type PhoneNumberField = { - type: 'PHONE_NUMBER'; - key: string; - label: string; - required: boolean; - defaultCountryCode: string | null; - validatePhoneNumber: boolean; -}; - -// @public (undocumented) -export interface PhoneNumberInputValue { - // (undocumented) - countryCode: string; - // (undocumented) - phoneNumber: string; -} - -// @public (undocumented) -export interface PhoneNumberOutputValue { - // (undocumented) - countryCode?: string; - // (undocumented) - phoneNumber?: string; -} - -// @public -export type Poller = () => Promise; - -// @public (undocumented) -export type PollingCollector = AutoCollector< - 'SingleValueAutoCollector', - 'PollingCollector', - string, - PollingOutputValue ->; - -// @public (undocumented) -export type PollingField = { - type: 'POLLING'; - key: string; - pollInterval: number; - pollRetries: number; - pollChallengeStatus?: boolean; - challenge?: string; -}; - -// @public (undocumented) -export interface PollingOutputValue { - // (undocumented) - challenge?: string; - // (undocumented) - pollChallengeStatus?: boolean; - // (undocumented) - pollInterval: number; - // (undocumented) - pollRetries: number; - // (undocumented) - retriesRemaining?: number; -} - -// @public (undocumented) -export type PollingStatus = PollingStatusContinue | PollingStatusChallenge; - -// @public (undocumented) -export type PollingStatusChallenge = - | PollingStatusChallengeComplete - | 'expired' - | 'timedOut' - | 'error'; - -// @public (undocumented) -export type PollingStatusChallengeComplete = - | 'approved' - | 'denied' - | 'continue' - | CustomPollingStatus; - -// @public (undocumented) -export type PollingStatusContinue = 'continue' | 'timedOut'; - -// @public (undocumented) -export type ProtectCollector = AutoCollector< - 'SingleValueAutoCollector', - 'ProtectCollector', - string, - ProtectOutputValue ->; - -// @public (undocumented) -export type ProtectField = { - type: 'PROTECT'; - key: string; - behavioralDataCollection: boolean; - universalDeviceIdentification: boolean; -}; - -// @public -export interface ProtectOutputValue { - // (undocumented) - behavioralDataCollection: boolean; - // (undocumented) - universalDeviceIdentification: boolean; -} - -// @public -export interface QrCodeCollector extends NoValueCollectorBase<'QrCodeCollector'> { - // (undocumented) - output: NoValueCollectorBase<'QrCodeCollector'>['output'] & { - src: string; - }; -} - -// @public (undocumented) -export type QrCodeField = { - type: 'QR_CODE'; - key: string; - content: string; - fallbackText?: string; -}; - -// @public -export interface ReadOnlyCollector extends NoValueCollectorBase<'ReadOnlyCollector'> { - // (undocumented) - output: NoValueCollectorBase<'ReadOnlyCollector'>['output'] & { - content: string; - title?: string; - }; -} - -// @public (undocumented) -export type ReadOnlyField = { - type: 'LABEL'; - content: string; - richContent?: RichContent; - key?: string; -}; - -// @public (undocumented) -export type ReadOnlyFields = ReadOnlyField | QrCodeField | AgreementField | ImageField; - -// @public (undocumented) -export type RedirectField = { - type: 'SOCIAL_LOGIN_BUTTON'; - key: string; - label: string; - links: Links; -}; - -// @public (undocumented) -export type RedirectFields = RedirectField; - -export { RequestMiddleware }; - -// @public -export type RichContent = { - content: string; - replacements?: Record; -}; - -// @public -export interface RichContentLink { - // (undocumented) - href: string; - // (undocumented) - key: string; - // (undocumented) - target?: '_self' | '_blank'; - // (undocumented) - type: 'link'; - // (undocumented) - value: string; -} - -// @public -export type RichContentReplacement = { - type: 'link'; - value: string; - href: string; - target?: '_self' | '_blank'; -}; - -// @public -export interface RichTextCollector extends NoValueCollectorBase<'RichTextCollector'> { - // (undocumented) - output: NoValueCollectorBase<'RichTextCollector'>['output'] & { - content: string; - richContent: CollectorRichContent; - }; -} - -// @public (undocumented) -export interface SelectorOption { - // (undocumented) - label: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export type SingleCheckboxField = { - type: 'SINGLE_CHECKBOX'; - inputType: 'BOOLEAN'; - key: string; - label: string; - required?: boolean; - errorMessage?: string; - appearance: string; - richContent?: RichContent; -}; - -// @public (undocumented) -export type SingleSelectCollector = SingleSelectCollectorWithValue<'SingleSelectCollector'>; - -// @public (undocumented) -export interface SingleSelectCollectorNoValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface SingleSelectCollectorWithValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: string | number | boolean; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleSelectField = { - inputType: 'SINGLE_SELECT'; - key: string; - label: string; - options: { - label: string; - value: string; - }[]; - required?: boolean; - type: 'RADIO' | 'DROPDOWN'; -}; - -// @public (undocumented) -export type SingleValueAutoCollector = AutoCollector< - 'SingleValueAutoCollector', - 'SingleValueAutoCollector', - string ->; - -// @public (undocumented) -export type SingleValueAutoCollectorTypes = - | 'SingleValueAutoCollector' - | 'ProtectCollector' - | 'PollingCollector'; - -// @public -export type SingleValueCollector = - | SingleValueCollectorWithValue - | SingleValueCollectorNoValue; - -// @public (undocumented) -export interface SingleValueCollectorNoValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleValueCollectors = - | PasswordCollector - | ValidatedPasswordCollector - | SingleSelectCollector - | TextCollector - | ValidatedTextCollector - | BooleanCollector - | ValidatedBooleanCollector - | SingleValueCollectorWithValue<'SingleValueCollector'>; - -// @public -export type SingleValueCollectorTypes = - | 'PasswordCollector' - | 'ValidatedPasswordCollector' - | 'BooleanCollector' - | 'ValidatedBooleanCollector' - | 'SingleValueCollector' - | 'SingleSelectCollector' - | 'SingleSelectObjectCollector' - | 'TextCollector' - | 'ValidatedTextCollector'; - -// @public (undocumented) -export interface SingleValueCollectorWithValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: V; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleValueFields = - | StandardField - | PasswordField - | ValidatedField - | SingleCheckboxField - | SingleSelectField - | ProtectField; - -// @public (undocumented) -export type StandardField = { - type: 'TEXT' | 'SUBMIT_BUTTON' | 'FLOW_BUTTON' | 'FLOW_LINK' | 'BUTTON'; - key: string; - label: string; - required?: boolean; -}; - -// @public (undocumented) -export interface StartNode { - // (undocumented) - cache: null; - // (undocumented) - client: { - status: 'start'; - }; - // (undocumented) - error: DaVinciError | null; - // (undocumented) - server: { - status: 'start'; - }; - // (undocumented) - status: 'start'; -} - -// @public (undocumented) -export interface StartOptions { - // (undocumented) - query: Query; -} - -// @public (undocumented) -export type SubmitCollector = ActionCollectorNoUrl<'SubmitCollector'>; - -// @public (undocumented) -export interface SuccessNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - authorization?: { - code?: string; - state?: string; - }; - status: 'success'; - } | null; - // (undocumented) - error: null; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - session?: string; - status: 'success'; - }; - // (undocumented) - status: 'success'; -} - -// @public (undocumented) -export type TextCollector = SingleValueCollectorWithValue<'TextCollector'>; - -// @public (undocumented) -export interface ThrownQueryError { - // (undocumented) - error: FetchBaseQueryError; - // (undocumented) - isHandledError: boolean; - // (undocumented) - meta: FetchBaseQueryMeta; -} - -// @public -export type UnknownCollector = { - category: 'UnknownCollector'; - error: string | null; - type: 'UnknownCollector'; - id: string; - name: string; - output: { - key: string; - label: string; - type: string; - }; -}; - -// @public (undocumented) -export type UnknownField = Record; - -// @public -export type UpdatableCollectors = - | SingleValueCollectors - | MultiSelectCollector - | ObjectValueCollectors - | AutoCollectors; - -// @public (undocumented) -export const updateCollectorValues: ActionCreatorWithPayload< - { - id: string; - value: CollectorValueTypes; - index?: number; - }, - string ->; - -// @public -export type Updater = ( - value: CollectorValueType, - index?: number, -) => InternalErrorResponse | null; - -// @public (undocumented) -export interface ValidatedBooleanCollector extends ValidatedSingleValueCollectorWithValue< - 'ValidatedBooleanCollector', - boolean -> { - // (undocumented) - output: ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean>['output'] & { - appearance: string; - richContent?: CollectorRichContent; - }; -} - -// @public -export type ValidatedCollectors = - | ValidatedTextCollector - | ValidatedBooleanCollector - | ValidatedPasswordCollector - | ObjectValueCollectors - | MultiValueCollectors - | AutoCollectors; - -// @public (undocumented) -export type ValidatedField = { - type: 'TEXT'; - key: string; - label: string; - required: boolean; - validation: { - regex: string; - errorMessage: string; - }; -}; - -// @public (undocumented) -export interface ValidatedPasswordCollector { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - validation: PasswordPolicy; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - verify: boolean; - }; - // (undocumented) - type: 'ValidatedPasswordCollector'; -} - -// @public (undocumented) -export interface ValidatedSingleValueCollectorWithValue< - T extends SingleValueCollectorTypes, - V = string, -> { - // (undocumented) - category: 'ValidatedSingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - type: string; - validation: (ValidationRequired | ValidationRegex)[]; - value: V; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: V; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ValidatedTextCollector = ValidatedSingleValueCollectorWithValue<'TextCollector'>; - -// @public (undocumented) -export interface ValidationPhoneNumber { - // (undocumented) - message: string; - // (undocumented) - rule: boolean; - // (undocumented) - type: 'validatePhoneNumber'; -} - -// @public (undocumented) -export interface ValidationRegex { - // (undocumented) - message: string; - // (undocumented) - rule: string; - // (undocumented) - type: 'regex'; -} - -// @public (undocumented) -export interface ValidationRequired { - // (undocumented) - message: string; - // (undocumented) - rule: boolean; - // (undocumented) - type: 'required'; -} - -// @public -export type Validator = ( - value: CollectorValueType, -) => - | string[] - | { - error: { - message: string; - type: string; - }; - type: string; - }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/davinci-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import type { DaVinciConfig } from '@forgerock/sdk-types'; +import { FetchBaseQueryError } from '@reduxjs/toolkit/query'; +import type { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; +import { GenericError } from '@forgerock/sdk-types'; +import { LogLevel } from '@forgerock/sdk-logger'; +import { makeDavinciConfig } from '@forgerock/sdk-utilities'; +import type { MutationResultSelectorResult } from '@reduxjs/toolkit/query'; +import { QueryStatus } from '@reduxjs/toolkit/query'; +import { Reducer } from '@reduxjs/toolkit'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { SerializedError } from '@reduxjs/toolkit'; +import { Unsubscribe } from '@reduxjs/toolkit'; + +// @public (undocumented) +export type ActionCollector = ActionCollectorNoUrl | ActionCollectorWithUrl; + +// @public (undocumented) +export interface ActionCollectorNoUrl { + // (undocumented) + category: 'ActionCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ActionCollectors = ActionCollectorWithUrl<'IdpCollector'> | ActionCollectorNoUrl<'ActionCollector'> | ActionCollectorNoUrl<'FlowCollector'> | ActionCollectorNoUrl<'SubmitCollector'>; + +// @public +export type ActionCollectorTypes = 'FlowCollector' | 'SubmitCollector' | 'IdpCollector' | 'ActionCollector'; + +// @public (undocumented) +export interface ActionCollectorWithUrl { + // (undocumented) + category: 'ActionCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + url?: string | null; + }; + // (undocumented) + type: T; +} + +export { ActionTypes } + +// @public (undocumented) +export type AgreementField = { + type: 'AGREEMENT'; + key: string; + content: string; + titleEnabled: boolean; + title?: string; + agreement: { + id: string; + useDynamicAgreement: boolean; + }; + enabled: boolean; +}; + +// @public (undocumented) +export interface AssertionValue extends Omit { + // (undocumented) + rawId: string; + // (undocumented) + response: { + clientDataJSON: string; + authenticatorData: string; + signature: string; + userHandle: string | null; + }; +} + +// @public (undocumented) +export interface AttestationValue extends Omit { + // (undocumented) + rawId: string; + // (undocumented) + response: { + clientDataJSON: string; + attestationObject: string; + }; +} + +// @public (undocumented) +export interface AutoCollector> { + // (undocumented) + category: C; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: IV; + type: string; + validation?: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + type: string; + config: OV; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type AutoCollectorCategories = 'SingleValueAutoCollector' | 'ObjectValueAutoCollector'; + +// @public (undocumented) +export type AutoCollectors = ProtectCollector | FidoRegistrationCollector | FidoAuthenticationCollector | MetadataCollector | PollingCollector | SingleValueAutoCollector | ObjectValueAutoCollector; + +// @public (undocumented) +export type AutoCollectorTypes = SingleValueAutoCollectorTypes | ObjectValueAutoCollectorTypes; + +// @public (undocumented) +export interface BooleanCollector extends SingleValueCollectorWithValue<'BooleanCollector', boolean> { + // (undocumented) + output: SingleValueCollectorWithValue<'BooleanCollector', boolean>['output'] & { + appearance: string; + richContent?: CollectorRichContent; + }; +} + +// @public (undocumented) +export type CollectorCategory = Collectors['category']; + +// @public (undocumented) +export interface CollectorErrors { + // (undocumented) + code: string; + // (undocumented) + message: string; + // (undocumented) + target: string; +} + +// @public +export interface CollectorRichContent { + // (undocumented) + content: string; + // (undocumented) + replacements: RichContentLink[]; +} + +// @public (undocumented) +export type Collectors = FlowCollector | MetadataCollector | PasswordCollector | ValidatedPasswordCollector | TextCollector | BooleanCollector | ValidatedBooleanCollector | SingleSelectCollector | IdpCollector | SubmitCollector | ActionCollector<'ActionCollector'> | SingleValueCollector<'SingleValueCollector'> | MultiSelectCollector | DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | PhoneNumberExtensionCollector | ReadOnlyCollector | RichTextCollector | ValidatedTextCollector | ProtectCollector | PollingCollector | FidoRegistrationCollector | FidoAuthenticationCollector | QrCodeCollector | ImageCollector | UnknownCollector; + +// @public +export type CollectorValueType = T extends { + type: 'PasswordCollector'; +} | { + type: 'ValidatedPasswordCollector'; +} | { + type: 'SingleSelectCollector'; +} | { + type: 'DeviceRegistrationCollector'; +} | { + type: 'DeviceAuthenticationCollector'; +} | { + type: 'ProtectCollector'; +} | { + type: 'PollingCollector'; +} ? string : T extends { + type: 'TextCollector'; + category: 'SingleValueCollector'; +} ? string : T extends { + type: 'TextCollector'; + category: 'ValidatedSingleValueCollector'; +} ? string : T extends { + type: 'BooleanCollector'; +} | { + type: 'ValidatedBooleanCollector'; +} ? boolean : T extends { + type: 'MultiSelectCollector'; +} ? string | string[] : T extends { + type: 'PhoneNumberCollector'; +} ? PhoneNumberInputValue : T extends { + type: 'PhoneNumberExtensionCollector'; +} ? PhoneNumberExtensionInputValue : T extends { + type: 'FidoRegistrationCollector'; +} ? FidoRegistrationInputValue | GenericError : T extends { + type: 'FidoAuthenticationCollector'; +} ? FidoAuthenticationInputValue | GenericError : T extends { + type: 'MetadataCollector'; +} ? Record | MetadataError : T extends { + category: 'SingleValueCollector'; +} ? string : T extends { + category: 'ValidatedSingleValueCollector'; +} ? string : T extends { + category: 'SingleValueAutoCollector'; +} ? string : T extends { + category: 'MultiValueCollector'; +} ? string | string[] : T extends { + category: 'ActionCollector'; +} ? never : T extends { + category: 'NoValueCollector'; +} ? never : CollectorValueTypes; + +// @public +export type CollectorValueTypes = string | string[] | boolean | PhoneNumberInputValue | PhoneNumberExtensionInputValue | FidoRegistrationInputValue | FidoAuthenticationInputValue | MetadataError | GenericError; + +// @public (undocumented) +export type ComplexValueFields = DeviceAuthenticationField | DeviceRegistrationField | PhoneNumberField | PhoneNumberExtensionField | FidoRegistrationField | FidoAuthenticationField | PollingField | MetadataField; + +// @public (undocumented) +export interface ContinueNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: 'continue'; + }; + // (undocumented) + error: null; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + eventName?: string; + status: 'continue'; + }; + // (undocumented) + status: 'continue'; +} + +export { CustomLogger } + +// @public +export type CustomPollingStatus = string & {}; + +// @public +export function davinci(input: { + config: DaVinciConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; +}): Promise<{ + store: SdkStore; + subscribe: (listener: () => void) => Unsubscribe; + externalIdp: () => (() => Promise); + flow: (action: DaVinciAction) => InitFlow; + next: (args?: DaVinciRequest) => Promise; + resume: (input: { + continueToken: string; + }) => Promise; + start: (options?: StartOptions | undefined) => Promise; + update: (collector: T) => Updater; + validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator; + pollStatus: (collector: PollingCollector) => Poller; + getClient: () => { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: "continue"; + } | { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: "error"; + } | { + status: "failure"; + } | { + status: "start"; + } | { + authorization?: { + code?: string; + state?: string; + }; + status: "success"; + } | null; + getCollectors: () => Collectors[]; + getError: () => DaVinciError | null; + getErrorCollectors: () => CollectorErrors[]; + getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode; + getServer: () => { + _links?: Links; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + eventName?: string; + status: "continue"; + } | { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: "error"; + } | { + _links?: Links; + eventName?: string; + href?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: "failure"; + } | { + status: "start"; + } | { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + session?: string; + status: "success"; + } | null; + cache: { + getLatestResponse: () => ({ + status: QueryStatus.fulfilled; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "data" | "fulfilledTimeStamp"> & Required> & { + error: undefined; + } & { + status: QueryStatus.fulfilled; + isUninitialized: false; + isLoading: false; + isSuccess: true; + isError: false; + }) | ({ + status: QueryStatus.rejected; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "error"> & Required> & { + status: QueryStatus.rejected; + isUninitialized: false; + isLoading: false; + isSuccess: false; + isError: true; + }) | { + error: { + message: string; + type: string; + }; + }; + getResponseWithId: (requestId: string) => ({ + status: QueryStatus.fulfilled; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "data" | "fulfilledTimeStamp"> & Required> & { + error: undefined; + } & { + status: QueryStatus.fulfilled; + isUninitialized: false; + isLoading: false; + isSuccess: true; + isError: false; + }) | ({ + status: QueryStatus.rejected; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "error"> & Required> & { + status: QueryStatus.rejected; + isUninitialized: false; + isLoading: false; + isSuccess: false; + isError: true; + }) | { + error: { + message: string; + type: string; + }; + }; + }; +}>; + +// @public +export interface DaVinciAction { + // (undocumented) + action: string; +} + +// @public +export interface DaVinciBaseResponse { + // (undocumented) + capabilityName?: string; + // (undocumented) + companyId?: string; + // (undocumented) + connectionId?: string; + // (undocumented) + connectorId?: string; + // (undocumented) + id?: string; + // (undocumented) + interactionId?: string; + // (undocumented) + interactionToken?: string; + // (undocumented) + isResponseCompatibleWithMobileAndWebSdks?: boolean; + // (undocumented) + status?: string; +} + +// @public +export type DaVinciCacheEntry = { + data?: DaVinciBaseResponse; + error?: { + data: DaVinciBaseResponse; + status: number; + }; +} & { + data?: any; + error?: any; +} & MutationResultSelectorResult; + +// @public (undocumented) +export type DavinciClient = Awaited>; + +export { DaVinciConfig } + +// @public (undocumented) +export interface DaVinciError extends Omit { + // (undocumented) + collectors?: CollectorErrors[]; + // (undocumented) + internalHttpStatus?: number; + // (undocumented) + message: string; + // (undocumented) + status: 'error' | 'failure' | 'unknown'; +} + +// @public (undocumented) +export interface DaVinciErrorCacheEntry { + // (undocumented) + endpointName: 'next' | 'flow' | 'start'; + // (undocumented) + error: { + data: T; + }; + // (undocumented) + fulfilledTimeStamp: number; + // (undocumented) + isError: boolean; + // (undocumented) + isLoading: boolean; + // (undocumented) + isSuccess: boolean; + // (undocumented) + isUninitialized: boolean; + // (undocumented) + requestId: string; + // (undocumented) + startedTimeStamp: number; + // (undocumented) + status: 'fulfilled' | 'pending' | 'rejected'; +} + +// @public (undocumented) +export interface DavinciErrorResponse extends DaVinciBaseResponse { + // (undocumented) + cause?: string | null; + // (undocumented) + code: string | number; + // (undocumented) + details?: ErrorDetail[]; + // (undocumented) + doNotSendToOE?: boolean; + // (undocumented) + error?: { + code?: string; + message?: string; + }; + // (undocumented) + errorCategory?: string; + // (undocumented) + errorMessage?: string; + // (undocumented) + expected?: boolean; + // (undocumented) + httpResponseCode: number; + // (undocumented) + isErrorCustomized?: boolean; + // (undocumented) + message: string; + // (undocumented) + metricAttributes?: { + [key: string]: unknown; + }; +} + +// @public (undocumented) +export interface DaVinciFailureResponse extends DaVinciBaseResponse { + // (undocumented) + error?: { + code?: string; + message?: string; + [key: string]: unknown; + }; +} + +// @public (undocumented) +export type DaVinciField = ComplexValueFields | MultiValueFields | ReadOnlyFields | RedirectFields | SingleValueFields; + +// @public +export interface DaVinciNextResponse extends DaVinciBaseResponse { + // (undocumented) + eventName?: string; + // (undocumented) + form?: { + name?: string; + description?: string; + components?: { + fields?: DaVinciField[]; + }; + }; + // (undocumented) + formData?: { + value?: { + [key: string]: string; + }; + }; + // (undocumented) + _links?: Links; +} + +// @public +export interface DaVinciPollResponse extends DaVinciBaseResponse { + // (undocumented) + eventName?: string; + // (undocumented) + _links?: Links; + // (undocumented) + success?: boolean; +} + +// @public (undocumented) +export interface DaVinciRequest { + // (undocumented) + eventName: string; + // (undocumented) + id: string; + // (undocumented) + interactionId: string; + // (undocumented) + parameters: { + eventType: 'submit' | 'action' | 'polling'; + data: { + actionKey: string; + formData?: Record; + }; + }; +} + +// @public +export type DaVinciRequestValueTypes = string | number | boolean | (string | number | boolean)[] | DeviceValue | PhoneNumberInputValue | FidoRegistrationInputValue | FidoAuthenticationInputValue | MetadataError | GenericError; + +// @public (undocumented) +export interface DaVinciSuccessResponse extends DaVinciBaseResponse { + // (undocumented) + authorizeResponse?: OAuthDetails; + // (undocumented) + environment: { + id: string; + [key: string]: unknown; + }; + // (undocumented) + _links?: Links; + // (undocumented) + resetCookie?: boolean; + // (undocumented) + session?: { + id?: string; + [key: string]: unknown; + }; + // (undocumented) + sessionToken?: string; + // (undocumented) + sessionTokenMaxAge?: number; + // (undocumented) + status: string; + // (undocumented) + subFlowSettings?: { + cssLinks?: unknown[]; + cssUrl?: unknown; + jsLinks?: unknown[]; + loadingScreenSettings?: unknown; + reactSkUrl?: unknown; + }; + // (undocumented) + success: true; +} + +// @public (undocumented) +export type DeviceAuthenticationCollector = ObjectOptionsCollectorWithObjectValue<'DeviceAuthenticationCollector', DeviceValue>; + +// @public (undocumented) +export type DeviceAuthenticationField = { + type: 'DEVICE_AUTHENTICATION'; + key: string; + label: string; + options: { + type: string; + iconSrc: string; + title: string; + id: string; + default: boolean; + description: string; + }[]; + required: boolean; +}; + +// @public (undocumented) +export interface DeviceOptionNoDefault { + // (undocumented) + content: string; + // (undocumented) + key: string; + // (undocumented) + label: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export interface DeviceOptionWithDefault { + // (undocumented) + content: string; + // (undocumented) + default: boolean; + // (undocumented) + key: string; + // (undocumented) + label: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export type DeviceRegistrationCollector = ObjectOptionsCollectorWithStringValue<'DeviceRegistrationCollector', string>; + +// @public (undocumented) +export type DeviceRegistrationField = { + type: 'DEVICE_REGISTRATION'; + key: string; + label: string; + options: { + type: string; + iconSrc: string; + title: string; + description: string; + }[]; + required: boolean; +}; + +// @public (undocumented) +export interface DeviceValue { + // (undocumented) + id: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export interface ErrorDetail { + // (undocumented) + message?: string; + // (undocumented) + rawResponse?: { + _embedded?: { + users?: Array; + }; + code?: string; + count?: number; + details?: NestedErrorDetails[]; + id?: string; + message?: string; + size?: number; + userFilter?: string; + [key: string]: unknown; + }; + // (undocumented) + statusCode?: number; +} + +// @public (undocumented) +export interface ErrorNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: 'error'; + }; + // (undocumented) + error: DaVinciError; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: 'error'; + } | null; + // (undocumented) + status: 'error'; +} + +// @public (undocumented) +export interface FailureNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + status: 'failure'; + }; + // (undocumented) + error: DaVinciError; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + href?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: 'failure'; + } | null; + // (undocumented) + status: 'failure'; +} + +// @public +export function fido(): FidoClient; + +// @public (undocumented) +export type FidoAuthenticationCollector = AutoCollector<'ObjectValueAutoCollector', 'FidoAuthenticationCollector', FidoAuthenticationInputValue | GenericError, FidoAuthenticationOutputValue>; + +// @public (undocumented) +export type FidoAuthenticationField = { + type: 'FIDO2'; + key: string; + label: string; + publicKeyCredentialRequestOptions: FidoAuthenticationOptions; + action: 'AUTHENTICATE'; + trigger: string; + required: boolean; +}; + +// @public (undocumented) +export interface FidoAuthenticationInputValue { + // (undocumented) + assertionValue?: AssertionValue; +} + +// @public (undocumented) +export interface FidoAuthenticationOptions extends Omit { + // (undocumented) + allowCredentials?: { + id: number[]; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + challenge: number[]; +} + +// @public (undocumented) +export interface FidoAuthenticationOutputValue { + // (undocumented) + action: 'AUTHENTICATE'; + // (undocumented) + publicKeyCredentialRequestOptions: FidoAuthenticationOptions; + // (undocumented) + trigger: string; +} + +// @public (undocumented) +export interface FidoClient { + authenticate: (options: FidoAuthenticationOptions) => Promise; + register: (options: FidoRegistrationOptions) => Promise; +} + +// @public +export type FidoErrorCode = 'NotAllowedError' | 'AbortError' | 'InvalidStateError' | 'NotSupportedError' | 'SecurityError' | 'TimeoutError' | 'UnknownError'; + +// @public (undocumented) +export type FidoRegistrationCollector = AutoCollector<'ObjectValueAutoCollector', 'FidoRegistrationCollector', FidoRegistrationInputValue | GenericError, FidoRegistrationOutputValue>; + +// @public (undocumented) +export type FidoRegistrationField = { + type: 'FIDO2'; + key: string; + label: string; + publicKeyCredentialCreationOptions: FidoRegistrationOptions; + action: 'REGISTER'; + trigger: string; + required: boolean; +}; + +// @public (undocumented) +export interface FidoRegistrationInputValue { + // (undocumented) + attestationValue?: AttestationValue; +} + +// @public (undocumented) +export interface FidoRegistrationOptions extends Omit { + // (undocumented) + challenge: number[]; + // (undocumented) + excludeCredentials?: { + id: number[]; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + pubKeyCredParams: { + alg: string | number; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + user: { + id: number[]; + name: string; + displayName: string; + }; +} + +// @public (undocumented) +export interface FidoRegistrationOutputValue { + // (undocumented) + action: 'REGISTER'; + // (undocumented) + publicKeyCredentialCreationOptions: FidoRegistrationOptions; + // (undocumented) + trigger: string; +} + +// @public (undocumented) +export type FlowCollector = ActionCollectorNoUrl<'FlowCollector'>; + +// @public (undocumented) +export type FlowNode = ContinueNode | ErrorNode | StartNode | SuccessNode | FailureNode; + +// @public +export type GetClient = StartNode['client'] | ContinueNode['client'] | ErrorNode['client'] | SuccessNode['client'] | FailureNode['client']; + +// @public (undocumented) +export type IdpCollector = ActionCollectorWithUrl<'IdpCollector'>; + +// @public +export interface ImageCollector extends NoValueCollectorBase<'ImageCollector'> { + // (undocumented) + output: NoValueCollectorBase<'ImageCollector'>['output'] & { + src: string; + alt: string; + href?: string; + }; +} + +// @public (undocumented) +export type ImageField = { + type: 'IMAGE'; + key: string; + description: string; + imageUrl: string; + hyperlinkUrl?: string; +}; + +// @public (undocumented) +export type InferActionCollectorType = T extends 'IdpCollector' ? IdpCollector : T extends 'SubmitCollector' ? SubmitCollector : T extends 'FlowCollector' ? FlowCollector : ActionCollectorWithUrl<'ActionCollector'> | ActionCollectorNoUrl<'ActionCollector'>; + +// @public +export type InferAutoCollectorType = T extends 'ProtectCollector' ? ProtectCollector : T extends 'PollingCollector' ? PollingCollector : T extends 'FidoRegistrationCollector' ? FidoRegistrationCollector : T extends 'FidoAuthenticationCollector' ? FidoAuthenticationCollector : T extends 'MetadataCollector' ? MetadataCollector : T extends 'ObjectValueAutoCollector' ? ObjectValueAutoCollector : SingleValueAutoCollector; + +// @public +export type InferMultiValueCollectorType = T extends 'MultiSelectCollector' ? MultiValueCollectorWithValue<'MultiSelectCollector'> : MultiValueCollectorWithValue<'MultiValueCollector'> | MultiValueCollectorNoValue<'MultiValueCollector'>; + +// @public +export type InferNoValueCollectorType = T extends 'ReadOnlyCollector' ? ReadOnlyCollector : T extends 'RichTextCollector' ? RichTextCollector : T extends 'QrCodeCollector' ? QrCodeCollector : T extends 'ImageCollector' ? ImageCollector : NoValueCollectorBase<'NoValueCollector'>; + +// @public +export type InferSingleValueCollectorType = T extends 'TextCollector' ? TextCollector : T extends 'SingleSelectCollector' ? SingleSelectCollector : T extends 'ValidatedTextCollector' ? ValidatedTextCollector : T extends 'PasswordCollector' ? PasswordCollector : T extends 'ValidatedPasswordCollector' ? ValidatedPasswordCollector : T extends 'BooleanCollector' ? BooleanCollector : T extends 'ValidatedBooleanCollector' ? ValidatedBooleanCollector : SingleValueCollectorWithValue<'SingleValueCollector'> | SingleValueCollectorNoValue<'SingleValueCollector'>; + +// @public (undocumented) +export type InferValueObjectCollectorType = T extends 'DeviceAuthenticationCollector' ? DeviceAuthenticationCollector : T extends 'DeviceRegistrationCollector' ? DeviceRegistrationCollector : T extends 'PhoneNumberCollector' ? PhoneNumberCollector : T extends 'PhoneNumberExtensionCollector' ? PhoneNumberExtensionCollector : ObjectOptionsCollectorWithObjectValue<'ObjectValueCollector'> | ObjectOptionsCollectorWithStringValue<'ObjectValueCollector'>; + +// @public (undocumented) +export type InitFlow = () => Promise; + +// @public (undocumented) +export interface InternalErrorResponse { + // (undocumented) + error: Omit & { + message: string; + }; + // (undocumented) + type: 'internal_error'; +} + +// @public (undocumented) +export interface Links { + // (undocumented) + [key: string]: { + href?: string; + }; +} + +export { LogLevel } + +export { makeDavinciConfig } + +// @public (undocumented) +export type MetadataCollector = AutoCollector<'ObjectValueAutoCollector', 'MetadataCollector', MetadataCollectorInputValue, Record>; + +// @public (undocumented) +export type MetadataCollectorInputValue = Record | MetadataError; + +// @public +export interface MetadataError { + // (undocumented) + code: string; + // (undocumented) + message: string; +} + +// @public (undocumented) +export type MetadataField = { + type: 'METADATA'; + key: string; + payload: Record; +}; + +// @public (undocumented) +export type MultiSelectCollector = MultiValueCollectorWithValue<'MultiSelectCollector'>; + +// @public (undocumented) +export type MultiSelectField = { + inputType: 'MULTI_SELECT'; + key: string; + label: string; + options: { + label: string; + value: string; + }[]; + required?: boolean; + type: 'CHECKBOX' | 'COMBOBOX'; +}; + +// @public (undocumented) +export type MultiValueCollector = MultiValueCollectorWithValue | MultiValueCollectorNoValue; + +// @public (undocumented) +export interface MultiValueCollectorNoValue { + // (undocumented) + category: 'MultiValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string[]; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type MultiValueCollectors = MultiValueCollectorWithValue<'MultiValueCollector'> | MultiValueCollectorWithValue<'MultiSelectCollector'>; + +// @public +export type MultiValueCollectorTypes = 'MultiSelectCollector' | 'MultiValueCollector'; + +// @public (undocumented) +export interface MultiValueCollectorWithValue { + // (undocumented) + category: 'MultiValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string[]; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: string[]; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type MultiValueFields = MultiSelectField; + +// @public +export interface NestedErrorDetails { + // (undocumented) + code?: string; + // (undocumented) + innerError?: { + history?: string; + unsatisfiedRequirements?: string[]; + failuresRemaining?: number; + }; + // (undocumented) + message?: string; + // (undocumented) + target?: string; +} + +// @public +export const nextCollectorValues: ActionCreatorWithPayload< { +fields: DaVinciField[]; +formData: { +value: Record; +}; +}, string>; + +// @public +export const nodeCollectorReducer: Reducer & { + getInitialState: () => Collectors[]; +}; + +// @public (undocumented) +export type NodeStates = StartNode | ContinueNode | ErrorNode | SuccessNode | FailureNode; + +// @public (undocumented) +export type NoValueCollector = InferNoValueCollectorType; + +// @public (undocumented) +export interface NoValueCollectorBase { + // (undocumented) + category: 'NoValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type NoValueCollectors = NoValueCollectorBase<'NoValueCollector'> | ReadOnlyCollector | RichTextCollector | QrCodeCollector | ImageCollector; + +// @public +export type NoValueCollectorTypes = 'ReadOnlyCollector' | 'RichTextCollector' | 'NoValueCollector' | 'QrCodeCollector' | 'ImageCollector'; + +// @public +export interface OAuthDetails { + // (undocumented) + [key: string]: unknown; + // (undocumented) + code?: string; + // (undocumented) + state?: string; +} + +// @public (undocumented) +export interface ObjectOptionsCollectorWithObjectValue, D = Record> { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: DeviceOptionWithDefault[]; + value?: D | null; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface ObjectOptionsCollectorWithStringValue { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: DeviceOptionNoDefault[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ObjectValueAutoCollector = AutoCollector<'ObjectValueAutoCollector', 'ObjectValueAutoCollector', Record>; + +// @public (undocumented) +export type ObjectValueAutoCollectorTypes = 'ObjectValueAutoCollector' | 'FidoRegistrationCollector' | 'FidoAuthenticationCollector' | 'MetadataCollector'; + +// @public (undocumented) +export type ObjectValueCollector = ObjectOptionsCollectorWithObjectValue | ObjectOptionsCollectorWithStringValue | ObjectValueCollectorWithObjectValue; + +// @public (undocumented) +export type ObjectValueCollectors = DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | PhoneNumberExtensionCollector | ObjectOptionsCollectorWithObjectValue<'ObjectSelectCollector'> | ObjectOptionsCollectorWithStringValue<'ObjectSelectCollector'>; + +// @public +export type ObjectValueCollectorTypes = 'DeviceAuthenticationCollector' | 'DeviceRegistrationCollector' | 'PhoneNumberCollector' | 'PhoneNumberExtensionCollector' | 'ObjectOptionsCollector' | 'ObjectValueCollector' | 'ObjectSelectCollector'; + +// @public (undocumented) +export interface ObjectValueCollectorWithObjectValue, OV = Record> { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: IV; + type: string; + validation: (ValidationRequired | ValidationPhoneNumber)[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value?: OV | null; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface OutgoingQueryParams { + // (undocumented) + [key: string]: string | string[]; +} + +// @public (undocumented) +export interface PasswordCollector { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + verify: boolean; + }; + // (undocumented) + type: 'PasswordCollector'; +} + +// @public +export type PasswordField = { + type: 'PASSWORD' | 'PASSWORD_VERIFY'; + key: string; + label: string; + required?: boolean; + verify?: boolean; + passwordPolicy?: PasswordPolicy; +}; + +// @public +export interface PasswordPolicy { + // (undocumented) + createdAt?: string; + // (undocumented) + default?: boolean; + // (undocumented) + description?: string; + // (undocumented) + excludesCommonlyUsed?: boolean; + // (undocumented) + excludesProfileData?: boolean; + // (undocumented) + history?: { + count?: number; + retentionDays?: number; + }; + // (undocumented) + id?: string; + // (undocumented) + length?: { + min?: number; + max?: number; + }; + // (undocumented) + lockout?: { + failureCount?: number; + durationSeconds?: number; + }; + // (undocumented) + maxAgeDays?: number; + // (undocumented) + maxRepeatedCharacters?: number; + // (undocumented) + minAgeDays?: number; + // (undocumented) + minCharacters?: Record; + // (undocumented) + minUniqueCharacters?: number; + // (undocumented) + name?: string; + // (undocumented) + notSimilarToCurrent?: boolean; + // (undocumented) + populationCount?: number; + // (undocumented) + updatedAt?: string; +} + +// @public (undocumented) +export type PhoneNumberCollector = ObjectValueCollectorWithObjectValue<'PhoneNumberCollector', PhoneNumberInputValue, PhoneNumberOutputValue>; + +// @public (undocumented) +export interface PhoneNumberExtensionCollector { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: PhoneNumberExtensionInputValue; + type: string; + validation: (ValidationRequired | ValidationPhoneNumber)[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + extensionLabel: string; + value: PhoneNumberExtensionOutputValue; + }; + // (undocumented) + type: 'PhoneNumberExtensionCollector'; +} + +// @public (undocumented) +export type PhoneNumberExtensionField = PhoneNumberField & { + showExtension: boolean; + extensionLabel: string; +}; + +// @public (undocumented) +export interface PhoneNumberExtensionInputValue { + // (undocumented) + countryCode: string; + // (undocumented) + extension: string; + // (undocumented) + phoneNumber: string; +} + +// @public (undocumented) +export interface PhoneNumberExtensionOutputValue { + // (undocumented) + countryCode?: string; + // (undocumented) + extension?: string; + // (undocumented) + phoneNumber?: string; +} + +// @public (undocumented) +export type PhoneNumberField = { + type: 'PHONE_NUMBER'; + key: string; + label: string; + required: boolean; + defaultCountryCode: string | null; + validatePhoneNumber: boolean; +}; + +// @public (undocumented) +export interface PhoneNumberInputValue { + // (undocumented) + countryCode: string; + // (undocumented) + phoneNumber: string; +} + +// @public (undocumented) +export interface PhoneNumberOutputValue { + // (undocumented) + countryCode?: string; + // (undocumented) + phoneNumber?: string; +} + +// @public +export type Poller = () => Promise; + +// @public (undocumented) +export type PollingCollector = AutoCollector<'SingleValueAutoCollector', 'PollingCollector', string, PollingOutputValue>; + +// @public (undocumented) +export type PollingField = { + type: 'POLLING'; + key: string; + pollInterval: number; + pollRetries: number; + pollChallengeStatus?: boolean; + challenge?: string; +}; + +// @public (undocumented) +export interface PollingOutputValue { + // (undocumented) + challenge?: string; + // (undocumented) + pollChallengeStatus?: boolean; + // (undocumented) + pollInterval: number; + // (undocumented) + pollRetries: number; + // (undocumented) + retriesRemaining?: number; +} + +// @public (undocumented) +export type PollingStatus = PollingStatusContinue | PollingStatusChallenge; + +// @public (undocumented) +export type PollingStatusChallenge = PollingStatusChallengeComplete | 'expired' | 'timedOut' | 'error'; + +// @public (undocumented) +export type PollingStatusChallengeComplete = 'approved' | 'denied' | 'continue' | CustomPollingStatus; + +// @public (undocumented) +export type PollingStatusContinue = 'continue' | 'timedOut'; + +// @public (undocumented) +export type ProtectCollector = AutoCollector<'SingleValueAutoCollector', 'ProtectCollector', string, ProtectOutputValue>; + +// @public (undocumented) +export type ProtectField = { + type: 'PROTECT'; + key: string; + behavioralDataCollection: boolean; + universalDeviceIdentification: boolean; +}; + +// @public +export interface ProtectOutputValue { + // (undocumented) + behavioralDataCollection: boolean; + // (undocumented) + universalDeviceIdentification: boolean; +} + +// @public +export interface QrCodeCollector extends NoValueCollectorBase<'QrCodeCollector'> { + // (undocumented) + output: NoValueCollectorBase<'QrCodeCollector'>['output'] & { + src: string; + }; +} + +// @public (undocumented) +export type QrCodeField = { + type: 'QR_CODE'; + key: string; + content: string; + fallbackText?: string; +}; + +// @public +export interface ReadOnlyCollector extends NoValueCollectorBase<'ReadOnlyCollector'> { + // (undocumented) + output: NoValueCollectorBase<'ReadOnlyCollector'>['output'] & { + content: string; + title?: string; + }; +} + +// @public (undocumented) +export type ReadOnlyField = { + type: 'LABEL'; + content: string; + richContent?: RichContent; + key?: string; +}; + +// @public (undocumented) +export type ReadOnlyFields = ReadOnlyField | QrCodeField | AgreementField | ImageField; + +// @public (undocumented) +export type RedirectField = { + type: 'SOCIAL_LOGIN_BUTTON'; + key: string; + label: string; + links: Links; +}; + +// @public (undocumented) +export type RedirectFields = RedirectField; + +export { RequestMiddleware } + +// @public +export type RichContent = { + content: string; + replacements?: Record; +}; + +// @public +export interface RichContentLink { + // (undocumented) + href: string; + // (undocumented) + key: string; + // (undocumented) + target?: '_self' | '_blank'; + // (undocumented) + type: 'link'; + // (undocumented) + value: string; +} + +// @public +export type RichContentReplacement = { + type: 'link'; + value: string; + href: string; + target?: '_self' | '_blank'; +}; + +// @public +export interface RichTextCollector extends NoValueCollectorBase<'RichTextCollector'> { + // (undocumented) + output: NoValueCollectorBase<'RichTextCollector'>['output'] & { + content: string; + richContent: CollectorRichContent; + }; +} + +// @public (undocumented) +export interface SelectorOption { + // (undocumented) + label: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export type SingleCheckboxField = { + type: 'SINGLE_CHECKBOX'; + inputType: 'BOOLEAN'; + key: string; + label: string; + required?: boolean; + errorMessage?: string; + appearance: string; + richContent?: RichContent; +}; + +// @public (undocumented) +export type SingleSelectCollector = SingleSelectCollectorWithValue<'SingleSelectCollector'>; + +// @public (undocumented) +export interface SingleSelectCollectorNoValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface SingleSelectCollectorWithValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: string | number | boolean; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleSelectField = { + inputType: 'SINGLE_SELECT'; + key: string; + label: string; + options: { + label: string; + value: string; + }[]; + required?: boolean; + type: 'RADIO' | 'DROPDOWN'; +}; + +// @public (undocumented) +export type SingleValueAutoCollector = AutoCollector<'SingleValueAutoCollector', 'SingleValueAutoCollector', string>; + +// @public (undocumented) +export type SingleValueAutoCollectorTypes = 'SingleValueAutoCollector' | 'ProtectCollector' | 'PollingCollector'; + +// @public +export type SingleValueCollector = SingleValueCollectorWithValue | SingleValueCollectorNoValue; + +// @public (undocumented) +export interface SingleValueCollectorNoValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleValueCollectors = PasswordCollector | ValidatedPasswordCollector | SingleSelectCollector | TextCollector | ValidatedTextCollector | BooleanCollector | ValidatedBooleanCollector | SingleValueCollectorWithValue<'SingleValueCollector'>; + +// @public +export type SingleValueCollectorTypes = 'PasswordCollector' | 'ValidatedPasswordCollector' | 'BooleanCollector' | 'ValidatedBooleanCollector' | 'SingleValueCollector' | 'SingleSelectCollector' | 'SingleSelectObjectCollector' | 'TextCollector' | 'ValidatedTextCollector'; + +// @public (undocumented) +export interface SingleValueCollectorWithValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: V; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleValueFields = StandardField | PasswordField | ValidatedField | SingleCheckboxField | SingleSelectField | ProtectField; + +// @public (undocumented) +export type StandardField = { + type: 'TEXT' | 'SUBMIT_BUTTON' | 'FLOW_BUTTON' | 'FLOW_LINK' | 'BUTTON'; + key: string; + label: string; + required?: boolean; +}; + +// @public (undocumented) +export interface StartNode { + // (undocumented) + cache: null; + // (undocumented) + client: { + status: 'start'; + }; + // (undocumented) + error: DaVinciError | null; + // (undocumented) + server: { + status: 'start'; + }; + // (undocumented) + status: 'start'; +} + +// @public (undocumented) +export interface StartOptions { + // (undocumented) + query: Query; +} + +// @public (undocumented) +export type SubmitCollector = ActionCollectorNoUrl<'SubmitCollector'>; + +// @public (undocumented) +export interface SuccessNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + authorization?: { + code?: string; + state?: string; + }; + status: 'success'; + } | null; + // (undocumented) + error: null; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + session?: string; + status: 'success'; + }; + // (undocumented) + status: 'success'; +} + +// @public (undocumented) +export type TextCollector = SingleValueCollectorWithValue<'TextCollector'>; + +// @public (undocumented) +export interface ThrownQueryError { + // (undocumented) + error: FetchBaseQueryError; + // (undocumented) + isHandledError: boolean; + // (undocumented) + meta: FetchBaseQueryMeta; +} + +// @public +export type UnknownCollector = { + category: 'UnknownCollector'; + error: string | null; + type: 'UnknownCollector'; + id: string; + name: string; + output: { + key: string; + label: string; + type: string; + }; +}; + +// @public (undocumented) +export type UnknownField = Record; + +// @public +export type UpdatableCollectors = SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors; + +// @public (undocumented) +export const updateCollectorValues: ActionCreatorWithPayload< { +id: string; +value: CollectorValueTypes; +index?: number; +}, string>; + +// @public +export type Updater = (value: CollectorValueType, index?: number) => InternalErrorResponse | null; + +// @public (undocumented) +export interface ValidatedBooleanCollector extends ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean> { + // (undocumented) + output: ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean>['output'] & { + appearance: string; + richContent?: CollectorRichContent; + }; +} + +// @public +export type ValidatedCollectors = ValidatedTextCollector | ValidatedBooleanCollector | ValidatedPasswordCollector | ObjectValueCollectors | MultiValueCollectors | AutoCollectors; + +// @public (undocumented) +export type ValidatedField = { + type: 'TEXT'; + key: string; + label: string; + required: boolean; + validation: { + regex: string; + errorMessage: string; + }; +}; + +// @public (undocumented) +export interface ValidatedPasswordCollector { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + validation: PasswordPolicy; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + verify: boolean; + }; + // (undocumented) + type: 'ValidatedPasswordCollector'; +} + +// @public (undocumented) +export interface ValidatedSingleValueCollectorWithValue { + // (undocumented) + category: 'ValidatedSingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + type: string; + validation: (ValidationRequired | ValidationRegex)[]; + value: V; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: V; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ValidatedTextCollector = ValidatedSingleValueCollectorWithValue<'TextCollector'>; + +// @public (undocumented) +export interface ValidationPhoneNumber { + // (undocumented) + message: string; + // (undocumented) + rule: boolean; + // (undocumented) + type: 'validatePhoneNumber'; +} + +// @public (undocumented) +export interface ValidationRegex { + // (undocumented) + message: string; + // (undocumented) + rule: string; + // (undocumented) + type: 'regex'; +} + +// @public (undocumented) +export interface ValidationRequired { + // (undocumented) + message: string; + // (undocumented) + rule: boolean; + // (undocumented) + type: 'required'; +} + +// @public +export type Validator = (value: CollectorValueType) => string[] | { + error: { + message: string; + type: string; + }; + type: string; +}; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/davinci-client/api-report/davinci-client.types.api.md b/packages/davinci-client/api-report/davinci-client.types.api.md index cfece3b8487..a2639c1e693 100644 --- a/packages/davinci-client/api-report/davinci-client.types.api.md +++ b/packages/davinci-client/api-report/davinci-client.types.api.md @@ -1,2437 +1,2015 @@ -## API Report File for "@forgerock/davinci-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import type { DaVinciConfig } from '@forgerock/sdk-types'; -import { FetchBaseQueryError } from '@reduxjs/toolkit/query'; -import type { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; -import type { GenericError } from '@forgerock/sdk-types'; -import { LogLevel } from '@forgerock/sdk-logger'; -import type { MutationResultSelectorResult } from '@reduxjs/toolkit/query'; -import { QueryStatus } from '@reduxjs/toolkit/query'; -import { Reducer } from '@reduxjs/toolkit'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { SerializedError } from '@reduxjs/toolkit'; -import { Unsubscribe } from '@reduxjs/toolkit'; - -// @public (undocumented) -export type ActionCollector = - | ActionCollectorNoUrl - | ActionCollectorWithUrl; - -// @public (undocumented) -export interface ActionCollectorNoUrl { - // (undocumented) - category: 'ActionCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ActionCollectors = - | ActionCollectorWithUrl<'IdpCollector'> - | ActionCollectorNoUrl<'ActionCollector'> - | ActionCollectorNoUrl<'FlowCollector'> - | ActionCollectorNoUrl<'SubmitCollector'>; - -// @public -export type ActionCollectorTypes = - | 'FlowCollector' - | 'SubmitCollector' - | 'IdpCollector' - | 'ActionCollector'; - -// @public (undocumented) -export interface ActionCollectorWithUrl { - // (undocumented) - category: 'ActionCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - url?: string | null; - }; - // (undocumented) - type: T; -} - -export { ActionTypes }; - -// @public (undocumented) -export type AgreementField = { - type: 'AGREEMENT'; - key: string; - content: string; - titleEnabled: boolean; - title?: string; - agreement: { - id: string; - useDynamicAgreement: boolean; - }; - enabled: boolean; -}; - -// @public (undocumented) -export interface AssertionValue extends Omit< - PublicKeyCredential, - 'rawId' | 'response' | 'getClientExtensionResults' | 'toJSON' -> { - // (undocumented) - rawId: string; - // (undocumented) - response: { - clientDataJSON: string; - authenticatorData: string; - signature: string; - userHandle: string | null; - }; -} - -// @public (undocumented) -export interface AttestationValue extends Omit< - PublicKeyCredential, - 'rawId' | 'response' | 'getClientExtensionResults' | 'toJSON' -> { - // (undocumented) - rawId: string; - // (undocumented) - response: { - clientDataJSON: string; - attestationObject: string; - }; -} - -// @public (undocumented) -export interface AutoCollector< - C extends AutoCollectorCategories, - T extends AutoCollectorTypes, - IV = string, - OV = Record, -> { - // (undocumented) - category: C; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: IV; - type: string; - validation?: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - type: string; - config: OV; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type AutoCollectorCategories = 'SingleValueAutoCollector' | 'ObjectValueAutoCollector'; - -// @public (undocumented) -export type AutoCollectors = - | ProtectCollector - | FidoRegistrationCollector - | FidoAuthenticationCollector - | MetadataCollector - | PollingCollector - | SingleValueAutoCollector - | ObjectValueAutoCollector; - -// @public (undocumented) -export type AutoCollectorTypes = SingleValueAutoCollectorTypes | ObjectValueAutoCollectorTypes; - -// @public (undocumented) -export interface BooleanCollector extends SingleValueCollectorWithValue< - 'BooleanCollector', - boolean -> { - // (undocumented) - output: SingleValueCollectorWithValue<'BooleanCollector', boolean>['output'] & { - appearance: string; - richContent?: CollectorRichContent; - }; -} - -// @public (undocumented) -export type CollectorCategory = Collectors['category']; - -// @public (undocumented) -export interface CollectorErrors { - // (undocumented) - code: string; - // (undocumented) - message: string; - // (undocumented) - target: string; -} - -// @public -export interface CollectorRichContent { - // (undocumented) - content: string; - // (undocumented) - replacements: RichContentLink[]; -} - -// @public (undocumented) -export type Collectors = - | FlowCollector - | MetadataCollector - | PasswordCollector - | ValidatedPasswordCollector - | TextCollector - | BooleanCollector - | ValidatedBooleanCollector - | SingleSelectCollector - | IdpCollector - | SubmitCollector - | ActionCollector<'ActionCollector'> - | SingleValueCollector<'SingleValueCollector'> - | MultiSelectCollector - | DeviceAuthenticationCollector - | DeviceRegistrationCollector - | PhoneNumberCollector - | PhoneNumberExtensionCollector - | ReadOnlyCollector - | RichTextCollector - | ValidatedTextCollector - | ProtectCollector - | PollingCollector - | FidoRegistrationCollector - | FidoAuthenticationCollector - | QrCodeCollector - | ImageCollector - | UnknownCollector; - -// @public -export type CollectorValueType = T extends - | { - type: 'PasswordCollector'; - } - | { - type: 'ValidatedPasswordCollector'; - } - | { - type: 'SingleSelectCollector'; - } - | { - type: 'DeviceRegistrationCollector'; - } - | { - type: 'DeviceAuthenticationCollector'; - } - | { - type: 'ProtectCollector'; - } - | { - type: 'PollingCollector'; - } - ? string - : T extends { - type: 'TextCollector'; - category: 'SingleValueCollector'; - } - ? string - : T extends { - type: 'TextCollector'; - category: 'ValidatedSingleValueCollector'; - } - ? string - : T extends - | { - type: 'BooleanCollector'; - } - | { - type: 'ValidatedBooleanCollector'; - } - ? boolean - : T extends { - type: 'MultiSelectCollector'; - } - ? string | string[] - : T extends { - type: 'PhoneNumberCollector'; - } - ? PhoneNumberInputValue - : T extends { - type: 'PhoneNumberExtensionCollector'; - } - ? PhoneNumberExtensionInputValue - : T extends { - type: 'FidoRegistrationCollector'; - } - ? FidoRegistrationInputValue | GenericError - : T extends { - type: 'FidoAuthenticationCollector'; - } - ? FidoAuthenticationInputValue | GenericError - : T extends { - type: 'MetadataCollector'; - } - ? Record | MetadataError - : T extends { - category: 'SingleValueCollector'; - } - ? string - : T extends { - category: 'ValidatedSingleValueCollector'; - } - ? string - : T extends { - category: 'SingleValueAutoCollector'; - } - ? string - : T extends { - category: 'MultiValueCollector'; - } - ? string | string[] - : T extends { - category: 'ActionCollector'; - } - ? never - : T extends { - category: 'NoValueCollector'; - } - ? never - : CollectorValueTypes; - -// @public -export type CollectorValueTypes = - | string - | string[] - | boolean - | PhoneNumberInputValue - | PhoneNumberExtensionInputValue - | FidoRegistrationInputValue - | FidoAuthenticationInputValue - | MetadataError - | GenericError; - -// @public (undocumented) -export type ComplexValueFields = - | DeviceAuthenticationField - | DeviceRegistrationField - | PhoneNumberField - | PhoneNumberExtensionField - | FidoRegistrationField - | FidoAuthenticationField - | PollingField - | MetadataField; - -// @public (undocumented) -export interface ContinueNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'continue'; - }; - // (undocumented) - error: null; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - eventName?: string; - status: 'continue'; - }; - // (undocumented) - status: 'continue'; -} - -export { CustomLogger }; - -// @public -export type CustomPollingStatus = string & {}; - -// @public -export function davinci(input: { - config: DaVinciConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; -}): Promise<{ - subscribe: (listener: () => void) => Unsubscribe; - externalIdp: () => () => Promise; - flow: (action: DaVinciAction) => InitFlow; - next: (args?: DaVinciRequest) => Promise; - resume: (input: { continueToken: string }) => Promise; - start: ( - options?: StartOptions | undefined, - ) => Promise; - update: (collector: T) => Updater; - validate: ( - collector: - | SingleValueCollectors - | ObjectValueCollectors - | MultiValueCollectors - | AutoCollectors, - ) => Validator; - pollStatus: (collector: PollingCollector) => Poller; - getClient: () => - | { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'continue'; - } - | { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'error'; - } - | { - status: 'failure'; - } - | { - status: 'start'; - } - | { - authorization?: { - code?: string; - state?: string; - }; - status: 'success'; - } - | null; - getCollectors: () => Collectors[]; - getError: () => DaVinciError | null; - getErrorCollectors: () => CollectorErrors[]; - getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode; - getServer: () => - | { - _links?: Links; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - eventName?: string; - status: 'continue'; - } - | { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'error'; - } - | { - _links?: Links; - eventName?: string; - href?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'failure'; - } - | { - status: 'start'; - } - | { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - session?: string; - status: 'success'; - } - | null; - cache: { - getLatestResponse: () => - | ({ - status: QueryStatus.fulfilled; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > - > & { - error: undefined; - } & { - status: QueryStatus.fulfilled; - isUninitialized: false; - isLoading: false; - isSuccess: true; - isError: false; - }) - | ({ - status: QueryStatus.rejected; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > - > & { - status: QueryStatus.rejected; - isUninitialized: false; - isLoading: false; - isSuccess: false; - isError: true; - }) - | { - error: { - message: string; - type: string; - }; - }; - getResponseWithId: (requestId: string) => - | ({ - status: QueryStatus.fulfilled; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'data' | 'fulfilledTimeStamp' - > - > & { - error: undefined; - } & { - status: QueryStatus.fulfilled; - isUninitialized: false; - isLoading: false; - isSuccess: true; - isError: false; - }) - | ({ - status: QueryStatus.rejected; - } & Omit< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > & - Required< - Pick< - { - requestId: string; - data?: unknown; - error?: FetchBaseQueryError | SerializedError | undefined; - endpointName: string; - startedTimeStamp: number; - fulfilledTimeStamp?: number; - }, - 'error' - > - > & { - status: QueryStatus.rejected; - isUninitialized: false; - isLoading: false; - isSuccess: false; - isError: true; - }) - | { - error: { - message: string; - type: string; - }; - }; - }; -}>; - -// @public -export interface DaVinciAction { - // (undocumented) - action: string; -} - -// @public -export interface DaVinciBaseResponse { - // (undocumented) - capabilityName?: string; - // (undocumented) - companyId?: string; - // (undocumented) - connectionId?: string; - // (undocumented) - connectorId?: string; - // (undocumented) - id?: string; - // (undocumented) - interactionId?: string; - // (undocumented) - interactionToken?: string; - // (undocumented) - isResponseCompatibleWithMobileAndWebSdks?: boolean; - // (undocumented) - status?: string; -} - -// @public -export type DaVinciCacheEntry = { - data?: DaVinciBaseResponse; - error?: { - data: DaVinciBaseResponse; - status: number; - }; -} & { - data?: any; - error?: any; -} & MutationResultSelectorResult; - -// @public (undocumented) -export type DavinciClient = Awaited>; - -export { DaVinciConfig }; - -// @public (undocumented) -export interface DaVinciError extends Omit { - // (undocumented) - collectors?: CollectorErrors[]; - // (undocumented) - internalHttpStatus?: number; - // (undocumented) - message: string; - // (undocumented) - status: 'error' | 'failure' | 'unknown'; -} - -// @public (undocumented) -export interface DaVinciErrorCacheEntry { - // (undocumented) - endpointName: 'next' | 'flow' | 'start'; - // (undocumented) - error: { - data: T; - }; - // (undocumented) - fulfilledTimeStamp: number; - // (undocumented) - isError: boolean; - // (undocumented) - isLoading: boolean; - // (undocumented) - isSuccess: boolean; - // (undocumented) - isUninitialized: boolean; - // (undocumented) - requestId: string; - // (undocumented) - startedTimeStamp: number; - // (undocumented) - status: 'fulfilled' | 'pending' | 'rejected'; -} - -// @public (undocumented) -export interface DavinciErrorResponse extends DaVinciBaseResponse { - // (undocumented) - cause?: string | null; - // (undocumented) - code: string | number; - // (undocumented) - details?: ErrorDetail[]; - // (undocumented) - doNotSendToOE?: boolean; - // (undocumented) - error?: { - code?: string; - message?: string; - }; - // (undocumented) - errorCategory?: string; - // (undocumented) - errorMessage?: string; - // (undocumented) - expected?: boolean; - // (undocumented) - httpResponseCode: number; - // (undocumented) - isErrorCustomized?: boolean; - // (undocumented) - message: string; - // (undocumented) - metricAttributes?: { - [key: string]: unknown; - }; -} - -// @public (undocumented) -export interface DaVinciFailureResponse extends DaVinciBaseResponse { - // (undocumented) - error?: { - code?: string; - message?: string; - [key: string]: unknown; - }; -} - -// @public (undocumented) -export type DaVinciField = - | ComplexValueFields - | MultiValueFields - | ReadOnlyFields - | RedirectFields - | SingleValueFields; - -// @public -export interface DaVinciNextResponse extends DaVinciBaseResponse { - // (undocumented) - eventName?: string; - // (undocumented) - form?: { - name?: string; - description?: string; - components?: { - fields?: DaVinciField[]; - }; - }; - // (undocumented) - formData?: { - value?: { - [key: string]: string; - }; - }; - // (undocumented) - _links?: Links; -} - -// @public -export interface DaVinciPollResponse extends DaVinciBaseResponse { - // (undocumented) - eventName?: string; - // (undocumented) - _links?: Links; - // (undocumented) - success?: boolean; -} - -// @public (undocumented) -export interface DaVinciRequest { - // (undocumented) - eventName: string; - // (undocumented) - id: string; - // (undocumented) - interactionId: string; - // (undocumented) - parameters: { - eventType: 'submit' | 'action' | 'polling'; - data: { - actionKey: string; - formData?: Record; - }; - }; -} - -// @public -export type DaVinciRequestValueTypes = - | string - | number - | boolean - | (string | number | boolean)[] - | DeviceValue - | PhoneNumberInputValue - | FidoRegistrationInputValue - | FidoAuthenticationInputValue - | MetadataError - | GenericError; - -// @public (undocumented) -export interface DaVinciSuccessResponse extends DaVinciBaseResponse { - // (undocumented) - authorizeResponse?: OAuthDetails; - // (undocumented) - environment: { - id: string; - [key: string]: unknown; - }; - // (undocumented) - _links?: Links; - // (undocumented) - resetCookie?: boolean; - // (undocumented) - session?: { - id?: string; - [key: string]: unknown; - }; - // (undocumented) - sessionToken?: string; - // (undocumented) - sessionTokenMaxAge?: number; - // (undocumented) - status: string; - // (undocumented) - subFlowSettings?: { - cssLinks?: unknown[]; - cssUrl?: unknown; - jsLinks?: unknown[]; - loadingScreenSettings?: unknown; - reactSkUrl?: unknown; - }; - // (undocumented) - success: true; -} - -// @public (undocumented) -export type DeviceAuthenticationCollector = ObjectOptionsCollectorWithObjectValue< - 'DeviceAuthenticationCollector', - DeviceValue ->; - -// @public (undocumented) -export type DeviceAuthenticationField = { - type: 'DEVICE_AUTHENTICATION'; - key: string; - label: string; - options: { - type: string; - iconSrc: string; - title: string; - id: string; - default: boolean; - description: string; - }[]; - required: boolean; -}; - -// @public (undocumented) -export interface DeviceOptionNoDefault { - // (undocumented) - content: string; - // (undocumented) - key: string; - // (undocumented) - label: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export interface DeviceOptionWithDefault { - // (undocumented) - content: string; - // (undocumented) - default: boolean; - // (undocumented) - key: string; - // (undocumented) - label: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export type DeviceRegistrationCollector = ObjectOptionsCollectorWithStringValue< - 'DeviceRegistrationCollector', - string ->; - -// @public (undocumented) -export type DeviceRegistrationField = { - type: 'DEVICE_REGISTRATION'; - key: string; - label: string; - options: { - type: string; - iconSrc: string; - title: string; - description: string; - }[]; - required: boolean; -}; - -// @public (undocumented) -export interface DeviceValue { - // (undocumented) - id: string; - // (undocumented) - type: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export interface ErrorDetail { - // (undocumented) - message?: string; - // (undocumented) - rawResponse?: { - _embedded?: { - users?: Array; - }; - code?: string; - count?: number; - details?: NestedErrorDetails[]; - id?: string; - message?: string; - size?: number; - userFilter?: string; - [key: string]: unknown; - }; - // (undocumented) - statusCode?: number; -} - -// @public (undocumented) -export interface ErrorNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - action: string; - collectors: Collectors[]; - description?: string; - name?: string; - status: 'error'; - }; - // (undocumented) - error: DaVinciError; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'error'; - } | null; - // (undocumented) - status: 'error'; -} - -// @public (undocumented) -export interface FailureNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - status: 'failure'; - }; - // (undocumented) - error: DaVinciError; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - href?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - status: 'failure'; - } | null; - // (undocumented) - status: 'failure'; -} - -// @public (undocumented) -export type FidoAuthenticationCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'FidoAuthenticationCollector', - FidoAuthenticationInputValue | GenericError, - FidoAuthenticationOutputValue ->; - -// @public (undocumented) -export type FidoAuthenticationField = { - type: 'FIDO2'; - key: string; - label: string; - publicKeyCredentialRequestOptions: FidoAuthenticationOptions; - action: 'AUTHENTICATE'; - trigger: string; - required: boolean; -}; - -// @public (undocumented) -export interface FidoAuthenticationInputValue { - // (undocumented) - assertionValue?: AssertionValue; -} - -// @public (undocumented) -export interface FidoAuthenticationOptions extends Omit< - PublicKeyCredentialRequestOptions, - 'challenge' | 'allowCredentials' -> { - // (undocumented) - allowCredentials?: { - id: number[]; - transports?: AuthenticatorTransport[]; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - challenge: number[]; -} - -// @public (undocumented) -export interface FidoAuthenticationOutputValue { - // (undocumented) - action: 'AUTHENTICATE'; - // (undocumented) - publicKeyCredentialRequestOptions: FidoAuthenticationOptions; - // (undocumented) - trigger: string; -} - -// @public (undocumented) -export interface FidoClient { - authenticate: ( - options: FidoAuthenticationOptions, - ) => Promise; - register: ( - options: FidoRegistrationOptions, - ) => Promise; -} - -// @public -export type FidoErrorCode = - | 'NotAllowedError' - | 'AbortError' - | 'InvalidStateError' - | 'NotSupportedError' - | 'SecurityError' - | 'TimeoutError' - | 'UnknownError'; - -// @public (undocumented) -export type FidoRegistrationCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'FidoRegistrationCollector', - FidoRegistrationInputValue | GenericError, - FidoRegistrationOutputValue ->; - -// @public (undocumented) -export type FidoRegistrationField = { - type: 'FIDO2'; - key: string; - label: string; - publicKeyCredentialCreationOptions: FidoRegistrationOptions; - action: 'REGISTER'; - trigger: string; - required: boolean; -}; - -// @public (undocumented) -export interface FidoRegistrationInputValue { - // (undocumented) - attestationValue?: AttestationValue; -} - -// @public (undocumented) -export interface FidoRegistrationOptions extends Omit< - PublicKeyCredentialCreationOptions, - 'challenge' | 'user' | 'pubKeyCredParams' | 'excludeCredentials' -> { - // (undocumented) - challenge: number[]; - // (undocumented) - excludeCredentials?: { - id: number[]; - transports?: AuthenticatorTransport[]; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - pubKeyCredParams: { - alg: string | number; - type: PublicKeyCredentialType; - }[]; - // (undocumented) - user: { - id: number[]; - name: string; - displayName: string; - }; -} - -// @public (undocumented) -export interface FidoRegistrationOutputValue { - // (undocumented) - action: 'REGISTER'; - // (undocumented) - publicKeyCredentialCreationOptions: FidoRegistrationOptions; - // (undocumented) - trigger: string; -} - -// @public (undocumented) -export type FlowCollector = ActionCollectorNoUrl<'FlowCollector'>; - -// @public (undocumented) -export type FlowNode = ContinueNode | ErrorNode | StartNode | SuccessNode | FailureNode; - -// @public -export type GetClient = - | StartNode['client'] - | ContinueNode['client'] - | ErrorNode['client'] - | SuccessNode['client'] - | FailureNode['client']; - -// @public (undocumented) -export type IdpCollector = ActionCollectorWithUrl<'IdpCollector'>; - -// @public -export interface ImageCollector extends NoValueCollectorBase<'ImageCollector'> { - // (undocumented) - output: NoValueCollectorBase<'ImageCollector'>['output'] & { - src: string; - alt: string; - href?: string; - }; -} - -// @public (undocumented) -export type ImageField = { - type: 'IMAGE'; - key: string; - description: string; - imageUrl: string; - hyperlinkUrl?: string; -}; - -// @public (undocumented) -export type InferActionCollectorType = T extends 'IdpCollector' - ? IdpCollector - : T extends 'SubmitCollector' - ? SubmitCollector - : T extends 'FlowCollector' - ? FlowCollector - : ActionCollectorWithUrl<'ActionCollector'> | ActionCollectorNoUrl<'ActionCollector'>; - -// @public -export type InferAutoCollectorType = T extends 'ProtectCollector' - ? ProtectCollector - : T extends 'PollingCollector' - ? PollingCollector - : T extends 'FidoRegistrationCollector' - ? FidoRegistrationCollector - : T extends 'FidoAuthenticationCollector' - ? FidoAuthenticationCollector - : T extends 'MetadataCollector' - ? MetadataCollector - : T extends 'ObjectValueAutoCollector' - ? ObjectValueAutoCollector - : SingleValueAutoCollector; - -// @public -export type InferMultiValueCollectorType = - T extends 'MultiSelectCollector' - ? MultiValueCollectorWithValue<'MultiSelectCollector'> - : - | MultiValueCollectorWithValue<'MultiValueCollector'> - | MultiValueCollectorNoValue<'MultiValueCollector'>; - -// @public -export type InferNoValueCollectorType = - T extends 'ReadOnlyCollector' - ? ReadOnlyCollector - : T extends 'RichTextCollector' - ? RichTextCollector - : T extends 'QrCodeCollector' - ? QrCodeCollector - : T extends 'ImageCollector' - ? ImageCollector - : NoValueCollectorBase<'NoValueCollector'>; - -// @public -export type InferSingleValueCollectorType = - T extends 'TextCollector' - ? TextCollector - : T extends 'SingleSelectCollector' - ? SingleSelectCollector - : T extends 'ValidatedTextCollector' - ? ValidatedTextCollector - : T extends 'PasswordCollector' - ? PasswordCollector - : T extends 'ValidatedPasswordCollector' - ? ValidatedPasswordCollector - : T extends 'BooleanCollector' - ? BooleanCollector - : T extends 'ValidatedBooleanCollector' - ? ValidatedBooleanCollector - : - | SingleValueCollectorWithValue<'SingleValueCollector'> - | SingleValueCollectorNoValue<'SingleValueCollector'>; - -// @public (undocumented) -export type InferValueObjectCollectorType = - T extends 'DeviceAuthenticationCollector' - ? DeviceAuthenticationCollector - : T extends 'DeviceRegistrationCollector' - ? DeviceRegistrationCollector - : T extends 'PhoneNumberCollector' - ? PhoneNumberCollector - : T extends 'PhoneNumberExtensionCollector' - ? PhoneNumberExtensionCollector - : - | ObjectOptionsCollectorWithObjectValue<'ObjectValueCollector'> - | ObjectOptionsCollectorWithStringValue<'ObjectValueCollector'>; - -// @public (undocumented) -export type InitFlow = () => Promise; - -// @public (undocumented) -export interface InternalErrorResponse { - // (undocumented) - error: Omit & { - message: string; - }; - // (undocumented) - type: 'internal_error'; -} - -// @public (undocumented) -export interface Links { - // (undocumented) - [key: string]: { - href?: string; - }; -} - -export { LogLevel }; - -// @public (undocumented) -export type MetadataCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'MetadataCollector', - MetadataCollectorInputValue, - Record ->; - -// @public (undocumented) -export type MetadataCollectorInputValue = Record | MetadataError; - -// @public -export interface MetadataError { - // (undocumented) - code: string; - // (undocumented) - message: string; -} - -// @public (undocumented) -export type MetadataField = { - type: 'METADATA'; - key: string; - payload: Record; -}; - -// @public (undocumented) -export type MultiSelectCollector = MultiValueCollectorWithValue<'MultiSelectCollector'>; - -// @public (undocumented) -export type MultiSelectField = { - inputType: 'MULTI_SELECT'; - key: string; - label: string; - options: { - label: string; - value: string; - }[]; - required?: boolean; - type: 'CHECKBOX' | 'COMBOBOX'; -}; - -// @public (undocumented) -export type MultiValueCollector = - | MultiValueCollectorWithValue - | MultiValueCollectorNoValue; - -// @public (undocumented) -export interface MultiValueCollectorNoValue { - // (undocumented) - category: 'MultiValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string[]; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type MultiValueCollectors = - | MultiValueCollectorWithValue<'MultiValueCollector'> - | MultiValueCollectorWithValue<'MultiSelectCollector'>; - -// @public -export type MultiValueCollectorTypes = 'MultiSelectCollector' | 'MultiValueCollector'; - -// @public (undocumented) -export interface MultiValueCollectorWithValue { - // (undocumented) - category: 'MultiValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string[]; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: string[]; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type MultiValueFields = MultiSelectField; - -// @public -export interface NestedErrorDetails { - // (undocumented) - code?: string; - // (undocumented) - innerError?: { - history?: string; - unsatisfiedRequirements?: string[]; - failuresRemaining?: number; - }; - // (undocumented) - message?: string; - // (undocumented) - target?: string; -} - -// @public -export const nextCollectorValues: ActionCreatorWithPayload< - { - fields: DaVinciField[]; - formData: { - value: Record; - }; - }, - string ->; - -// @public -export const nodeCollectorReducer: Reducer & { - getInitialState: () => Collectors[]; -}; - -// @public (undocumented) -export type NodeStates = StartNode | ContinueNode | ErrorNode | SuccessNode | FailureNode; - -// @public (undocumented) -export type NoValueCollector = InferNoValueCollectorType; - -// @public (undocumented) -export interface NoValueCollectorBase { - // (undocumented) - category: 'NoValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type NoValueCollectors = - | NoValueCollectorBase<'NoValueCollector'> - | ReadOnlyCollector - | RichTextCollector - | QrCodeCollector - | ImageCollector; - -// @public -export type NoValueCollectorTypes = - | 'ReadOnlyCollector' - | 'RichTextCollector' - | 'NoValueCollector' - | 'QrCodeCollector' - | 'ImageCollector'; - -// @public -export interface OAuthDetails { - // (undocumented) - [key: string]: unknown; - // (undocumented) - code?: string; - // (undocumented) - state?: string; -} - -// @public (undocumented) -export interface ObjectOptionsCollectorWithObjectValue< - T extends ObjectValueCollectorTypes, - V = Record, - D = Record, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: DeviceOptionWithDefault[]; - value?: D | null; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface ObjectOptionsCollectorWithStringValue< - T extends ObjectValueCollectorTypes, - V = string, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - validation: ValidationRequired[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: DeviceOptionNoDefault[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ObjectValueAutoCollector = AutoCollector< - 'ObjectValueAutoCollector', - 'ObjectValueAutoCollector', - Record ->; - -// @public (undocumented) -export type ObjectValueAutoCollectorTypes = - | 'ObjectValueAutoCollector' - | 'FidoRegistrationCollector' - | 'FidoAuthenticationCollector' - | 'MetadataCollector'; - -// @public (undocumented) -export type ObjectValueCollector = - | ObjectOptionsCollectorWithObjectValue - | ObjectOptionsCollectorWithStringValue - | ObjectValueCollectorWithObjectValue; - -// @public (undocumented) -export type ObjectValueCollectors = - | DeviceAuthenticationCollector - | DeviceRegistrationCollector - | PhoneNumberCollector - | PhoneNumberExtensionCollector - | ObjectOptionsCollectorWithObjectValue<'ObjectSelectCollector'> - | ObjectOptionsCollectorWithStringValue<'ObjectSelectCollector'>; - -// @public -export type ObjectValueCollectorTypes = - | 'DeviceAuthenticationCollector' - | 'DeviceRegistrationCollector' - | 'PhoneNumberCollector' - | 'PhoneNumberExtensionCollector' - | 'ObjectOptionsCollector' - | 'ObjectValueCollector' - | 'ObjectSelectCollector'; - -// @public (undocumented) -export interface ObjectValueCollectorWithObjectValue< - T extends ObjectValueCollectorTypes, - IV = Record, - OV = Record, -> { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: IV; - type: string; - validation: (ValidationRequired | ValidationPhoneNumber)[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value?: OV | null; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface OutgoingQueryParams { - // (undocumented) - [key: string]: string | string[]; -} - -// @public (undocumented) -export interface PasswordCollector { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - verify: boolean; - }; - // (undocumented) - type: 'PasswordCollector'; -} - -// @public -export type PasswordField = { - type: 'PASSWORD' | 'PASSWORD_VERIFY'; - key: string; - label: string; - required?: boolean; - verify?: boolean; - passwordPolicy?: PasswordPolicy; -}; - -// @public -export interface PasswordPolicy { - // (undocumented) - createdAt?: string; - // (undocumented) - default?: boolean; - // (undocumented) - description?: string; - // (undocumented) - excludesCommonlyUsed?: boolean; - // (undocumented) - excludesProfileData?: boolean; - // (undocumented) - history?: { - count?: number; - retentionDays?: number; - }; - // (undocumented) - id?: string; - // (undocumented) - length?: { - min?: number; - max?: number; - }; - // (undocumented) - lockout?: { - failureCount?: number; - durationSeconds?: number; - }; - // (undocumented) - maxAgeDays?: number; - // (undocumented) - maxRepeatedCharacters?: number; - // (undocumented) - minAgeDays?: number; - // (undocumented) - minCharacters?: Record; - // (undocumented) - minUniqueCharacters?: number; - // (undocumented) - name?: string; - // (undocumented) - notSimilarToCurrent?: boolean; - // (undocumented) - populationCount?: number; - // (undocumented) - updatedAt?: string; -} - -// @public (undocumented) -export type PhoneNumberCollector = ObjectValueCollectorWithObjectValue< - 'PhoneNumberCollector', - PhoneNumberInputValue, - PhoneNumberOutputValue ->; - -// @public (undocumented) -export interface PhoneNumberExtensionCollector { - // (undocumented) - category: 'ObjectValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: PhoneNumberExtensionInputValue; - type: string; - validation: (ValidationRequired | ValidationPhoneNumber)[] | null; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - extensionLabel: string; - value: PhoneNumberExtensionOutputValue; - }; - // (undocumented) - type: 'PhoneNumberExtensionCollector'; -} - -// @public (undocumented) -export type PhoneNumberExtensionField = PhoneNumberField & { - showExtension: boolean; - extensionLabel: string; -}; - -// @public (undocumented) -export interface PhoneNumberExtensionInputValue { - // (undocumented) - countryCode: string; - // (undocumented) - extension: string; - // (undocumented) - phoneNumber: string; -} - -// @public (undocumented) -export interface PhoneNumberExtensionOutputValue { - // (undocumented) - countryCode?: string; - // (undocumented) - extension?: string; - // (undocumented) - phoneNumber?: string; -} - -// @public (undocumented) -export type PhoneNumberField = { - type: 'PHONE_NUMBER'; - key: string; - label: string; - required: boolean; - defaultCountryCode: string | null; - validatePhoneNumber: boolean; -}; - -// @public (undocumented) -export interface PhoneNumberInputValue { - // (undocumented) - countryCode: string; - // (undocumented) - phoneNumber: string; -} - -// @public (undocumented) -export interface PhoneNumberOutputValue { - // (undocumented) - countryCode?: string; - // (undocumented) - phoneNumber?: string; -} - -// @public -export type Poller = () => Promise; - -// @public (undocumented) -export type PollingCollector = AutoCollector< - 'SingleValueAutoCollector', - 'PollingCollector', - string, - PollingOutputValue ->; - -// @public (undocumented) -export type PollingField = { - type: 'POLLING'; - key: string; - pollInterval: number; - pollRetries: number; - pollChallengeStatus?: boolean; - challenge?: string; -}; - -// @public (undocumented) -export interface PollingOutputValue { - // (undocumented) - challenge?: string; - // (undocumented) - pollChallengeStatus?: boolean; - // (undocumented) - pollInterval: number; - // (undocumented) - pollRetries: number; - // (undocumented) - retriesRemaining?: number; -} - -// @public (undocumented) -export type PollingStatus = PollingStatusContinue | PollingStatusChallenge; - -// @public (undocumented) -export type PollingStatusChallenge = - | PollingStatusChallengeComplete - | 'expired' - | 'timedOut' - | 'error'; - -// @public (undocumented) -export type PollingStatusChallengeComplete = - | 'approved' - | 'denied' - | 'continue' - | CustomPollingStatus; - -// @public (undocumented) -export type PollingStatusContinue = 'continue' | 'timedOut'; - -// @public (undocumented) -export type ProtectCollector = AutoCollector< - 'SingleValueAutoCollector', - 'ProtectCollector', - string, - ProtectOutputValue ->; - -// @public (undocumented) -export type ProtectField = { - type: 'PROTECT'; - key: string; - behavioralDataCollection: boolean; - universalDeviceIdentification: boolean; -}; - -// @public -export interface ProtectOutputValue { - // (undocumented) - behavioralDataCollection: boolean; - // (undocumented) - universalDeviceIdentification: boolean; -} - -// @public -export interface QrCodeCollector extends NoValueCollectorBase<'QrCodeCollector'> { - // (undocumented) - output: NoValueCollectorBase<'QrCodeCollector'>['output'] & { - src: string; - }; -} - -// @public (undocumented) -export type QrCodeField = { - type: 'QR_CODE'; - key: string; - content: string; - fallbackText?: string; -}; - -// @public -export interface ReadOnlyCollector extends NoValueCollectorBase<'ReadOnlyCollector'> { - // (undocumented) - output: NoValueCollectorBase<'ReadOnlyCollector'>['output'] & { - content: string; - title?: string; - }; -} - -// @public (undocumented) -export type ReadOnlyField = { - type: 'LABEL'; - content: string; - richContent?: RichContent; - key?: string; -}; - -// @public (undocumented) -export type ReadOnlyFields = ReadOnlyField | QrCodeField | AgreementField | ImageField; - -// @public (undocumented) -export type RedirectField = { - type: 'SOCIAL_LOGIN_BUTTON'; - key: string; - label: string; - links: Links; -}; - -// @public (undocumented) -export type RedirectFields = RedirectField; - -export { RequestMiddleware }; - -// @public -export type RichContent = { - content: string; - replacements?: Record; -}; - -// @public -export interface RichContentLink { - // (undocumented) - href: string; - // (undocumented) - key: string; - // (undocumented) - target?: '_self' | '_blank'; - // (undocumented) - type: 'link'; - // (undocumented) - value: string; -} - -// @public -export type RichContentReplacement = { - type: 'link'; - value: string; - href: string; - target?: '_self' | '_blank'; -}; - -// @public -export interface RichTextCollector extends NoValueCollectorBase<'RichTextCollector'> { - // (undocumented) - output: NoValueCollectorBase<'RichTextCollector'>['output'] & { - content: string; - richContent: CollectorRichContent; - }; -} - -// @public (undocumented) -export interface SelectorOption { - // (undocumented) - label: string; - // (undocumented) - value: string; -} - -// @public (undocumented) -export type SingleCheckboxField = { - type: 'SINGLE_CHECKBOX'; - inputType: 'BOOLEAN'; - key: string; - label: string; - required?: boolean; - errorMessage?: string; - appearance: string; - richContent?: RichContent; -}; - -// @public (undocumented) -export type SingleSelectCollector = SingleSelectCollectorWithValue<'SingleSelectCollector'>; - -// @public (undocumented) -export interface SingleSelectCollectorNoValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export interface SingleSelectCollectorWithValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: string | number | boolean; - options: SelectorOption[]; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleSelectField = { - inputType: 'SINGLE_SELECT'; - key: string; - label: string; - options: { - label: string; - value: string; - }[]; - required?: boolean; - type: 'RADIO' | 'DROPDOWN'; -}; - -// @public (undocumented) -export type SingleValueAutoCollector = AutoCollector< - 'SingleValueAutoCollector', - 'SingleValueAutoCollector', - string ->; - -// @public (undocumented) -export type SingleValueAutoCollectorTypes = - | 'SingleValueAutoCollector' - | 'ProtectCollector' - | 'PollingCollector'; - -// @public -export type SingleValueCollector = - | SingleValueCollectorWithValue - | SingleValueCollectorNoValue; - -// @public (undocumented) -export interface SingleValueCollectorNoValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleValueCollectors = - | PasswordCollector - | ValidatedPasswordCollector - | SingleSelectCollector - | TextCollector - | ValidatedTextCollector - | BooleanCollector - | ValidatedBooleanCollector - | SingleValueCollectorWithValue<'SingleValueCollector'>; - -// @public -export type SingleValueCollectorTypes = - | 'PasswordCollector' - | 'ValidatedPasswordCollector' - | 'BooleanCollector' - | 'ValidatedBooleanCollector' - | 'SingleValueCollector' - | 'SingleSelectCollector' - | 'SingleSelectObjectCollector' - | 'TextCollector' - | 'ValidatedTextCollector'; - -// @public (undocumented) -export interface SingleValueCollectorWithValue { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: V; - type: string; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: V; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type SingleValueFields = - | StandardField - | PasswordField - | ValidatedField - | SingleCheckboxField - | SingleSelectField - | ProtectField; - -// @public (undocumented) -export type StandardField = { - type: 'TEXT' | 'SUBMIT_BUTTON' | 'FLOW_BUTTON' | 'FLOW_LINK' | 'BUTTON'; - key: string; - label: string; - required?: boolean; -}; - -// @public (undocumented) -export interface StartNode { - // (undocumented) - cache: null; - // (undocumented) - client: { - status: 'start'; - }; - // (undocumented) - error: DaVinciError | null; - // (undocumented) - server: { - status: 'start'; - }; - // (undocumented) - status: 'start'; -} - -// @public (undocumented) -export interface StartOptions { - // (undocumented) - query: Query; -} - -// @public (undocumented) -export type SubmitCollector = ActionCollectorNoUrl<'SubmitCollector'>; - -// @public (undocumented) -export interface SuccessNode { - // (undocumented) - cache: { - key: string; - }; - // (undocumented) - client: { - authorization?: { - code?: string; - state?: string; - }; - status: 'success'; - } | null; - // (undocumented) - error: null; - // (undocumented) - httpStatus: number; - // (undocumented) - server: { - _links?: Links; - eventName?: string; - id?: string; - interactionId?: string; - interactionToken?: string; - href?: string; - session?: string; - status: 'success'; - }; - // (undocumented) - status: 'success'; -} - -// @public (undocumented) -export type TextCollector = SingleValueCollectorWithValue<'TextCollector'>; - -// @public (undocumented) -export interface ThrownQueryError { - // (undocumented) - error: FetchBaseQueryError; - // (undocumented) - isHandledError: boolean; - // (undocumented) - meta: FetchBaseQueryMeta; -} - -// @public -export type UnknownCollector = { - category: 'UnknownCollector'; - error: string | null; - type: 'UnknownCollector'; - id: string; - name: string; - output: { - key: string; - label: string; - type: string; - }; -}; - -// @public (undocumented) -export type UnknownField = Record; - -// @public -export type UpdatableCollectors = - | SingleValueCollectors - | MultiSelectCollector - | ObjectValueCollectors - | AutoCollectors; - -// @public (undocumented) -export const updateCollectorValues: ActionCreatorWithPayload< - { - id: string; - value: CollectorValueTypes; - index?: number; - }, - string ->; - -// @public -export type Updater = ( - value: CollectorValueType, - index?: number, -) => InternalErrorResponse | null; - -// @public (undocumented) -export interface ValidatedBooleanCollector extends ValidatedSingleValueCollectorWithValue< - 'ValidatedBooleanCollector', - boolean -> { - // (undocumented) - output: ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean>['output'] & { - appearance: string; - richContent?: CollectorRichContent; - }; -} - -// @public -export type ValidatedCollectors = - | ValidatedTextCollector - | ValidatedBooleanCollector - | ValidatedPasswordCollector - | ObjectValueCollectors - | MultiValueCollectors - | AutoCollectors; - -// @public (undocumented) -export type ValidatedField = { - type: 'TEXT'; - key: string; - label: string; - required: boolean; - validation: { - regex: string; - errorMessage: string; - }; -}; - -// @public (undocumented) -export interface ValidatedPasswordCollector { - // (undocumented) - category: 'SingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - value: string | number | boolean; - type: string; - validation: PasswordPolicy; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - verify: boolean; - }; - // (undocumented) - type: 'ValidatedPasswordCollector'; -} - -// @public (undocumented) -export interface ValidatedSingleValueCollectorWithValue< - T extends SingleValueCollectorTypes, - V = string, -> { - // (undocumented) - category: 'ValidatedSingleValueCollector'; - // (undocumented) - error: string | null; - // (undocumented) - id: string; - // (undocumented) - input: { - key: string; - type: string; - validation: (ValidationRequired | ValidationRegex)[]; - value: V; - }; - // (undocumented) - name: string; - // (undocumented) - output: { - key: string; - label: string; - type: string; - value: V; - }; - // (undocumented) - type: T; -} - -// @public (undocumented) -export type ValidatedTextCollector = ValidatedSingleValueCollectorWithValue<'TextCollector'>; - -// @public (undocumented) -export interface ValidationPhoneNumber { - // (undocumented) - message: string; - // (undocumented) - rule: boolean; - // (undocumented) - type: 'validatePhoneNumber'; -} - -// @public (undocumented) -export interface ValidationRegex { - // (undocumented) - message: string; - // (undocumented) - rule: string; - // (undocumented) - type: 'regex'; -} - -// @public (undocumented) -export interface ValidationRequired { - // (undocumented) - message: string; - // (undocumented) - rule: boolean; - // (undocumented) - type: 'required'; -} - -// @public -export type Validator = ( - value: CollectorValueType, -) => - | string[] - | { - error: { - message: string; - type: string; - }; - type: string; - }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/davinci-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionCreatorWithPayload } from '@reduxjs/toolkit'; +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import type { DaVinciConfig } from '@forgerock/sdk-types'; +import { FetchBaseQueryError } from '@reduxjs/toolkit/query'; +import type { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; +import { GenericError } from '@forgerock/sdk-types'; +import { LogLevel } from '@forgerock/sdk-logger'; +import type { MutationResultSelectorResult } from '@reduxjs/toolkit/query'; +import { QueryStatus } from '@reduxjs/toolkit/query'; +import { Reducer } from '@reduxjs/toolkit'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { SerializedError } from '@reduxjs/toolkit'; +import { Unsubscribe } from '@reduxjs/toolkit'; + +// @public (undocumented) +export type ActionCollector = ActionCollectorNoUrl | ActionCollectorWithUrl; + +// @public (undocumented) +export interface ActionCollectorNoUrl { + // (undocumented) + category: 'ActionCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ActionCollectors = ActionCollectorWithUrl<'IdpCollector'> | ActionCollectorNoUrl<'ActionCollector'> | ActionCollectorNoUrl<'FlowCollector'> | ActionCollectorNoUrl<'SubmitCollector'>; + +// @public +export type ActionCollectorTypes = 'FlowCollector' | 'SubmitCollector' | 'IdpCollector' | 'ActionCollector'; + +// @public (undocumented) +export interface ActionCollectorWithUrl { + // (undocumented) + category: 'ActionCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + url?: string | null; + }; + // (undocumented) + type: T; +} + +export { ActionTypes } + +// @public (undocumented) +export type AgreementField = { + type: 'AGREEMENT'; + key: string; + content: string; + titleEnabled: boolean; + title?: string; + agreement: { + id: string; + useDynamicAgreement: boolean; + }; + enabled: boolean; +}; + +// @public (undocumented) +export interface AssertionValue extends Omit { + // (undocumented) + rawId: string; + // (undocumented) + response: { + clientDataJSON: string; + authenticatorData: string; + signature: string; + userHandle: string | null; + }; +} + +// @public (undocumented) +export interface AttestationValue extends Omit { + // (undocumented) + rawId: string; + // (undocumented) + response: { + clientDataJSON: string; + attestationObject: string; + }; +} + +// @public (undocumented) +export interface AutoCollector> { + // (undocumented) + category: C; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: IV; + type: string; + validation?: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + type: string; + config: OV; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type AutoCollectorCategories = 'SingleValueAutoCollector' | 'ObjectValueAutoCollector'; + +// @public (undocumented) +export type AutoCollectors = ProtectCollector | FidoRegistrationCollector | FidoAuthenticationCollector | MetadataCollector | PollingCollector | SingleValueAutoCollector | ObjectValueAutoCollector; + +// @public (undocumented) +export type AutoCollectorTypes = SingleValueAutoCollectorTypes | ObjectValueAutoCollectorTypes; + +// @public (undocumented) +export interface BooleanCollector extends SingleValueCollectorWithValue<'BooleanCollector', boolean> { + // (undocumented) + output: SingleValueCollectorWithValue<'BooleanCollector', boolean>['output'] & { + appearance: string; + richContent?: CollectorRichContent; + }; +} + +// @public (undocumented) +export type CollectorCategory = Collectors['category']; + +// @public (undocumented) +export interface CollectorErrors { + // (undocumented) + code: string; + // (undocumented) + message: string; + // (undocumented) + target: string; +} + +// @public +export interface CollectorRichContent { + // (undocumented) + content: string; + // (undocumented) + replacements: RichContentLink[]; +} + +// @public (undocumented) +export type Collectors = FlowCollector | MetadataCollector | PasswordCollector | ValidatedPasswordCollector | TextCollector | BooleanCollector | ValidatedBooleanCollector | SingleSelectCollector | IdpCollector | SubmitCollector | ActionCollector<'ActionCollector'> | SingleValueCollector<'SingleValueCollector'> | MultiSelectCollector | DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | PhoneNumberExtensionCollector | ReadOnlyCollector | RichTextCollector | ValidatedTextCollector | ProtectCollector | PollingCollector | FidoRegistrationCollector | FidoAuthenticationCollector | QrCodeCollector | ImageCollector | UnknownCollector; + +// @public +export type CollectorValueType = T extends { + type: 'PasswordCollector'; +} | { + type: 'ValidatedPasswordCollector'; +} | { + type: 'SingleSelectCollector'; +} | { + type: 'DeviceRegistrationCollector'; +} | { + type: 'DeviceAuthenticationCollector'; +} | { + type: 'ProtectCollector'; +} | { + type: 'PollingCollector'; +} ? string : T extends { + type: 'TextCollector'; + category: 'SingleValueCollector'; +} ? string : T extends { + type: 'TextCollector'; + category: 'ValidatedSingleValueCollector'; +} ? string : T extends { + type: 'BooleanCollector'; +} | { + type: 'ValidatedBooleanCollector'; +} ? boolean : T extends { + type: 'MultiSelectCollector'; +} ? string | string[] : T extends { + type: 'PhoneNumberCollector'; +} ? PhoneNumberInputValue : T extends { + type: 'PhoneNumberExtensionCollector'; +} ? PhoneNumberExtensionInputValue : T extends { + type: 'FidoRegistrationCollector'; +} ? FidoRegistrationInputValue | GenericError : T extends { + type: 'FidoAuthenticationCollector'; +} ? FidoAuthenticationInputValue | GenericError : T extends { + type: 'MetadataCollector'; +} ? Record | MetadataError : T extends { + category: 'SingleValueCollector'; +} ? string : T extends { + category: 'ValidatedSingleValueCollector'; +} ? string : T extends { + category: 'SingleValueAutoCollector'; +} ? string : T extends { + category: 'MultiValueCollector'; +} ? string | string[] : T extends { + category: 'ActionCollector'; +} ? never : T extends { + category: 'NoValueCollector'; +} ? never : CollectorValueTypes; + +// @public +export type CollectorValueTypes = string | string[] | boolean | PhoneNumberInputValue | PhoneNumberExtensionInputValue | FidoRegistrationInputValue | FidoAuthenticationInputValue | MetadataError | GenericError; + +// @public (undocumented) +export type ComplexValueFields = DeviceAuthenticationField | DeviceRegistrationField | PhoneNumberField | PhoneNumberExtensionField | FidoRegistrationField | FidoAuthenticationField | PollingField | MetadataField; + +// @public (undocumented) +export interface ContinueNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: 'continue'; + }; + // (undocumented) + error: null; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + eventName?: string; + status: 'continue'; + }; + // (undocumented) + status: 'continue'; +} + +export { CustomLogger } + +// @public +export type CustomPollingStatus = string & {}; + +// @public +export function davinci(input: { + config: DaVinciConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; +}): Promise<{ + store: SdkStore; + subscribe: (listener: () => void) => Unsubscribe; + externalIdp: () => (() => Promise); + flow: (action: DaVinciAction) => InitFlow; + next: (args?: DaVinciRequest) => Promise; + resume: (input: { + continueToken: string; + }) => Promise; + start: (options?: StartOptions | undefined) => Promise; + update: (collector: T) => Updater; + validate: (collector: SingleValueCollectors | ObjectValueCollectors | MultiValueCollectors | AutoCollectors) => Validator; + pollStatus: (collector: PollingCollector) => Poller; + getClient: () => { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: "continue"; + } | { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: "error"; + } | { + status: "failure"; + } | { + status: "start"; + } | { + authorization?: { + code?: string; + state?: string; + }; + status: "success"; + } | null; + getCollectors: () => Collectors[]; + getError: () => DaVinciError | null; + getErrorCollectors: () => CollectorErrors[]; + getNode: () => ContinueNode | ErrorNode | FailureNode | StartNode | SuccessNode; + getServer: () => { + _links?: Links; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + eventName?: string; + status: "continue"; + } | { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: "error"; + } | { + _links?: Links; + eventName?: string; + href?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: "failure"; + } | { + status: "start"; + } | { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + session?: string; + status: "success"; + } | null; + cache: { + getLatestResponse: () => ({ + status: QueryStatus.fulfilled; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "data" | "fulfilledTimeStamp"> & Required> & { + error: undefined; + } & { + status: QueryStatus.fulfilled; + isUninitialized: false; + isLoading: false; + isSuccess: true; + isError: false; + }) | ({ + status: QueryStatus.rejected; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "error"> & Required> & { + status: QueryStatus.rejected; + isUninitialized: false; + isLoading: false; + isSuccess: false; + isError: true; + }) | { + error: { + message: string; + type: string; + }; + }; + getResponseWithId: (requestId: string) => ({ + status: QueryStatus.fulfilled; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "data" | "fulfilledTimeStamp"> & Required> & { + error: undefined; + } & { + status: QueryStatus.fulfilled; + isUninitialized: false; + isLoading: false; + isSuccess: true; + isError: false; + }) | ({ + status: QueryStatus.rejected; + } & Omit<{ + requestId: string; + data?: unknown; + error?: FetchBaseQueryError | SerializedError | undefined; + endpointName: string; + startedTimeStamp: number; + fulfilledTimeStamp?: number; + }, "error"> & Required> & { + status: QueryStatus.rejected; + isUninitialized: false; + isLoading: false; + isSuccess: false; + isError: true; + }) | { + error: { + message: string; + type: string; + }; + }; + }; +}>; + +// @public +export interface DaVinciAction { + // (undocumented) + action: string; +} + +// @public +export interface DaVinciBaseResponse { + // (undocumented) + capabilityName?: string; + // (undocumented) + companyId?: string; + // (undocumented) + connectionId?: string; + // (undocumented) + connectorId?: string; + // (undocumented) + id?: string; + // (undocumented) + interactionId?: string; + // (undocumented) + interactionToken?: string; + // (undocumented) + isResponseCompatibleWithMobileAndWebSdks?: boolean; + // (undocumented) + status?: string; +} + +// @public +export type DaVinciCacheEntry = { + data?: DaVinciBaseResponse; + error?: { + data: DaVinciBaseResponse; + status: number; + }; +} & { + data?: any; + error?: any; +} & MutationResultSelectorResult; + +// @public (undocumented) +export type DavinciClient = Awaited>; + +export { DaVinciConfig } + +// @public (undocumented) +export interface DaVinciError extends Omit { + // (undocumented) + collectors?: CollectorErrors[]; + // (undocumented) + internalHttpStatus?: number; + // (undocumented) + message: string; + // (undocumented) + status: 'error' | 'failure' | 'unknown'; +} + +// @public (undocumented) +export interface DaVinciErrorCacheEntry { + // (undocumented) + endpointName: 'next' | 'flow' | 'start'; + // (undocumented) + error: { + data: T; + }; + // (undocumented) + fulfilledTimeStamp: number; + // (undocumented) + isError: boolean; + // (undocumented) + isLoading: boolean; + // (undocumented) + isSuccess: boolean; + // (undocumented) + isUninitialized: boolean; + // (undocumented) + requestId: string; + // (undocumented) + startedTimeStamp: number; + // (undocumented) + status: 'fulfilled' | 'pending' | 'rejected'; +} + +// @public (undocumented) +export interface DavinciErrorResponse extends DaVinciBaseResponse { + // (undocumented) + cause?: string | null; + // (undocumented) + code: string | number; + // (undocumented) + details?: ErrorDetail[]; + // (undocumented) + doNotSendToOE?: boolean; + // (undocumented) + error?: { + code?: string; + message?: string; + }; + // (undocumented) + errorCategory?: string; + // (undocumented) + errorMessage?: string; + // (undocumented) + expected?: boolean; + // (undocumented) + httpResponseCode: number; + // (undocumented) + isErrorCustomized?: boolean; + // (undocumented) + message: string; + // (undocumented) + metricAttributes?: { + [key: string]: unknown; + }; +} + +// @public (undocumented) +export interface DaVinciFailureResponse extends DaVinciBaseResponse { + // (undocumented) + error?: { + code?: string; + message?: string; + [key: string]: unknown; + }; +} + +// @public (undocumented) +export type DaVinciField = ComplexValueFields | MultiValueFields | ReadOnlyFields | RedirectFields | SingleValueFields; + +// @public +export interface DaVinciNextResponse extends DaVinciBaseResponse { + // (undocumented) + eventName?: string; + // (undocumented) + form?: { + name?: string; + description?: string; + components?: { + fields?: DaVinciField[]; + }; + }; + // (undocumented) + formData?: { + value?: { + [key: string]: string; + }; + }; + // (undocumented) + _links?: Links; +} + +// @public +export interface DaVinciPollResponse extends DaVinciBaseResponse { + // (undocumented) + eventName?: string; + // (undocumented) + _links?: Links; + // (undocumented) + success?: boolean; +} + +// @public (undocumented) +export interface DaVinciRequest { + // (undocumented) + eventName: string; + // (undocumented) + id: string; + // (undocumented) + interactionId: string; + // (undocumented) + parameters: { + eventType: 'submit' | 'action' | 'polling'; + data: { + actionKey: string; + formData?: Record; + }; + }; +} + +// @public +export type DaVinciRequestValueTypes = string | number | boolean | (string | number | boolean)[] | DeviceValue | PhoneNumberInputValue | FidoRegistrationInputValue | FidoAuthenticationInputValue | MetadataError | GenericError; + +// @public (undocumented) +export interface DaVinciSuccessResponse extends DaVinciBaseResponse { + // (undocumented) + authorizeResponse?: OAuthDetails; + // (undocumented) + environment: { + id: string; + [key: string]: unknown; + }; + // (undocumented) + _links?: Links; + // (undocumented) + resetCookie?: boolean; + // (undocumented) + session?: { + id?: string; + [key: string]: unknown; + }; + // (undocumented) + sessionToken?: string; + // (undocumented) + sessionTokenMaxAge?: number; + // (undocumented) + status: string; + // (undocumented) + subFlowSettings?: { + cssLinks?: unknown[]; + cssUrl?: unknown; + jsLinks?: unknown[]; + loadingScreenSettings?: unknown; + reactSkUrl?: unknown; + }; + // (undocumented) + success: true; +} + +// @public (undocumented) +export type DeviceAuthenticationCollector = ObjectOptionsCollectorWithObjectValue<'DeviceAuthenticationCollector', DeviceValue>; + +// @public (undocumented) +export type DeviceAuthenticationField = { + type: 'DEVICE_AUTHENTICATION'; + key: string; + label: string; + options: { + type: string; + iconSrc: string; + title: string; + id: string; + default: boolean; + description: string; + }[]; + required: boolean; +}; + +// @public (undocumented) +export interface DeviceOptionNoDefault { + // (undocumented) + content: string; + // (undocumented) + key: string; + // (undocumented) + label: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export interface DeviceOptionWithDefault { + // (undocumented) + content: string; + // (undocumented) + default: boolean; + // (undocumented) + key: string; + // (undocumented) + label: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export type DeviceRegistrationCollector = ObjectOptionsCollectorWithStringValue<'DeviceRegistrationCollector', string>; + +// @public (undocumented) +export type DeviceRegistrationField = { + type: 'DEVICE_REGISTRATION'; + key: string; + label: string; + options: { + type: string; + iconSrc: string; + title: string; + description: string; + }[]; + required: boolean; +}; + +// @public (undocumented) +export interface DeviceValue { + // (undocumented) + id: string; + // (undocumented) + type: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export interface ErrorDetail { + // (undocumented) + message?: string; + // (undocumented) + rawResponse?: { + _embedded?: { + users?: Array; + }; + code?: string; + count?: number; + details?: NestedErrorDetails[]; + id?: string; + message?: string; + size?: number; + userFilter?: string; + [key: string]: unknown; + }; + // (undocumented) + statusCode?: number; +} + +// @public (undocumented) +export interface ErrorNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + action: string; + collectors: Collectors[]; + description?: string; + name?: string; + status: 'error'; + }; + // (undocumented) + error: DaVinciError; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: 'error'; + } | null; + // (undocumented) + status: 'error'; +} + +// @public (undocumented) +export interface FailureNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + status: 'failure'; + }; + // (undocumented) + error: DaVinciError; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + href?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + status: 'failure'; + } | null; + // (undocumented) + status: 'failure'; +} + +// @public (undocumented) +export type FidoAuthenticationCollector = AutoCollector<'ObjectValueAutoCollector', 'FidoAuthenticationCollector', FidoAuthenticationInputValue | GenericError, FidoAuthenticationOutputValue>; + +// @public (undocumented) +export type FidoAuthenticationField = { + type: 'FIDO2'; + key: string; + label: string; + publicKeyCredentialRequestOptions: FidoAuthenticationOptions; + action: 'AUTHENTICATE'; + trigger: string; + required: boolean; +}; + +// @public (undocumented) +export interface FidoAuthenticationInputValue { + // (undocumented) + assertionValue?: AssertionValue; +} + +// @public (undocumented) +export interface FidoAuthenticationOptions extends Omit { + // (undocumented) + allowCredentials?: { + id: number[]; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + challenge: number[]; +} + +// @public (undocumented) +export interface FidoAuthenticationOutputValue { + // (undocumented) + action: 'AUTHENTICATE'; + // (undocumented) + publicKeyCredentialRequestOptions: FidoAuthenticationOptions; + // (undocumented) + trigger: string; +} + +// @public (undocumented) +export interface FidoClient { + authenticate: (options: FidoAuthenticationOptions) => Promise; + register: (options: FidoRegistrationOptions) => Promise; +} + +// @public +export type FidoErrorCode = 'NotAllowedError' | 'AbortError' | 'InvalidStateError' | 'NotSupportedError' | 'SecurityError' | 'TimeoutError' | 'UnknownError'; + +// @public (undocumented) +export type FidoRegistrationCollector = AutoCollector<'ObjectValueAutoCollector', 'FidoRegistrationCollector', FidoRegistrationInputValue | GenericError, FidoRegistrationOutputValue>; + +// @public (undocumented) +export type FidoRegistrationField = { + type: 'FIDO2'; + key: string; + label: string; + publicKeyCredentialCreationOptions: FidoRegistrationOptions; + action: 'REGISTER'; + trigger: string; + required: boolean; +}; + +// @public (undocumented) +export interface FidoRegistrationInputValue { + // (undocumented) + attestationValue?: AttestationValue; +} + +// @public (undocumented) +export interface FidoRegistrationOptions extends Omit { + // (undocumented) + challenge: number[]; + // (undocumented) + excludeCredentials?: { + id: number[]; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + pubKeyCredParams: { + alg: string | number; + type: PublicKeyCredentialType; + }[]; + // (undocumented) + user: { + id: number[]; + name: string; + displayName: string; + }; +} + +// @public (undocumented) +export interface FidoRegistrationOutputValue { + // (undocumented) + action: 'REGISTER'; + // (undocumented) + publicKeyCredentialCreationOptions: FidoRegistrationOptions; + // (undocumented) + trigger: string; +} + +// @public (undocumented) +export type FlowCollector = ActionCollectorNoUrl<'FlowCollector'>; + +// @public (undocumented) +export type FlowNode = ContinueNode | ErrorNode | StartNode | SuccessNode | FailureNode; + +// @public +export type GetClient = StartNode['client'] | ContinueNode['client'] | ErrorNode['client'] | SuccessNode['client'] | FailureNode['client']; + +// @public (undocumented) +export type IdpCollector = ActionCollectorWithUrl<'IdpCollector'>; + +// @public +export interface ImageCollector extends NoValueCollectorBase<'ImageCollector'> { + // (undocumented) + output: NoValueCollectorBase<'ImageCollector'>['output'] & { + src: string; + alt: string; + href?: string; + }; +} + +// @public (undocumented) +export type ImageField = { + type: 'IMAGE'; + key: string; + description: string; + imageUrl: string; + hyperlinkUrl?: string; +}; + +// @public (undocumented) +export type InferActionCollectorType = T extends 'IdpCollector' ? IdpCollector : T extends 'SubmitCollector' ? SubmitCollector : T extends 'FlowCollector' ? FlowCollector : ActionCollectorWithUrl<'ActionCollector'> | ActionCollectorNoUrl<'ActionCollector'>; + +// @public +export type InferAutoCollectorType = T extends 'ProtectCollector' ? ProtectCollector : T extends 'PollingCollector' ? PollingCollector : T extends 'FidoRegistrationCollector' ? FidoRegistrationCollector : T extends 'FidoAuthenticationCollector' ? FidoAuthenticationCollector : T extends 'MetadataCollector' ? MetadataCollector : T extends 'ObjectValueAutoCollector' ? ObjectValueAutoCollector : SingleValueAutoCollector; + +// @public +export type InferMultiValueCollectorType = T extends 'MultiSelectCollector' ? MultiValueCollectorWithValue<'MultiSelectCollector'> : MultiValueCollectorWithValue<'MultiValueCollector'> | MultiValueCollectorNoValue<'MultiValueCollector'>; + +// @public +export type InferNoValueCollectorType = T extends 'ReadOnlyCollector' ? ReadOnlyCollector : T extends 'RichTextCollector' ? RichTextCollector : T extends 'QrCodeCollector' ? QrCodeCollector : T extends 'ImageCollector' ? ImageCollector : NoValueCollectorBase<'NoValueCollector'>; + +// @public +export type InferSingleValueCollectorType = T extends 'TextCollector' ? TextCollector : T extends 'SingleSelectCollector' ? SingleSelectCollector : T extends 'ValidatedTextCollector' ? ValidatedTextCollector : T extends 'PasswordCollector' ? PasswordCollector : T extends 'ValidatedPasswordCollector' ? ValidatedPasswordCollector : T extends 'BooleanCollector' ? BooleanCollector : T extends 'ValidatedBooleanCollector' ? ValidatedBooleanCollector : SingleValueCollectorWithValue<'SingleValueCollector'> | SingleValueCollectorNoValue<'SingleValueCollector'>; + +// @public (undocumented) +export type InferValueObjectCollectorType = T extends 'DeviceAuthenticationCollector' ? DeviceAuthenticationCollector : T extends 'DeviceRegistrationCollector' ? DeviceRegistrationCollector : T extends 'PhoneNumberCollector' ? PhoneNumberCollector : T extends 'PhoneNumberExtensionCollector' ? PhoneNumberExtensionCollector : ObjectOptionsCollectorWithObjectValue<'ObjectValueCollector'> | ObjectOptionsCollectorWithStringValue<'ObjectValueCollector'>; + +// @public (undocumented) +export type InitFlow = () => Promise; + +// @public (undocumented) +export interface InternalErrorResponse { + // (undocumented) + error: Omit & { + message: string; + }; + // (undocumented) + type: 'internal_error'; +} + +// @public (undocumented) +export interface Links { + // (undocumented) + [key: string]: { + href?: string; + }; +} + +export { LogLevel } + +// @public (undocumented) +export type MetadataCollector = AutoCollector<'ObjectValueAutoCollector', 'MetadataCollector', MetadataCollectorInputValue, Record>; + +// @public (undocumented) +export type MetadataCollectorInputValue = Record | MetadataError; + +// @public +export interface MetadataError { + // (undocumented) + code: string; + // (undocumented) + message: string; +} + +// @public (undocumented) +export type MetadataField = { + type: 'METADATA'; + key: string; + payload: Record; +}; + +// @public (undocumented) +export type MultiSelectCollector = MultiValueCollectorWithValue<'MultiSelectCollector'>; + +// @public (undocumented) +export type MultiSelectField = { + inputType: 'MULTI_SELECT'; + key: string; + label: string; + options: { + label: string; + value: string; + }[]; + required?: boolean; + type: 'CHECKBOX' | 'COMBOBOX'; +}; + +// @public (undocumented) +export type MultiValueCollector = MultiValueCollectorWithValue | MultiValueCollectorNoValue; + +// @public (undocumented) +export interface MultiValueCollectorNoValue { + // (undocumented) + category: 'MultiValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string[]; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type MultiValueCollectors = MultiValueCollectorWithValue<'MultiValueCollector'> | MultiValueCollectorWithValue<'MultiSelectCollector'>; + +// @public +export type MultiValueCollectorTypes = 'MultiSelectCollector' | 'MultiValueCollector'; + +// @public (undocumented) +export interface MultiValueCollectorWithValue { + // (undocumented) + category: 'MultiValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string[]; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: string[]; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type MultiValueFields = MultiSelectField; + +// @public +export interface NestedErrorDetails { + // (undocumented) + code?: string; + // (undocumented) + innerError?: { + history?: string; + unsatisfiedRequirements?: string[]; + failuresRemaining?: number; + }; + // (undocumented) + message?: string; + // (undocumented) + target?: string; +} + +// @public +export const nextCollectorValues: ActionCreatorWithPayload< { +fields: DaVinciField[]; +formData: { +value: Record; +}; +}, string>; + +// @public +export const nodeCollectorReducer: Reducer & { + getInitialState: () => Collectors[]; +}; + +// @public (undocumented) +export type NodeStates = StartNode | ContinueNode | ErrorNode | SuccessNode | FailureNode; + +// @public (undocumented) +export type NoValueCollector = InferNoValueCollectorType; + +// @public (undocumented) +export interface NoValueCollectorBase { + // (undocumented) + category: 'NoValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type NoValueCollectors = NoValueCollectorBase<'NoValueCollector'> | ReadOnlyCollector | RichTextCollector | QrCodeCollector | ImageCollector; + +// @public +export type NoValueCollectorTypes = 'ReadOnlyCollector' | 'RichTextCollector' | 'NoValueCollector' | 'QrCodeCollector' | 'ImageCollector'; + +// @public +export interface OAuthDetails { + // (undocumented) + [key: string]: unknown; + // (undocumented) + code?: string; + // (undocumented) + state?: string; +} + +// @public (undocumented) +export interface ObjectOptionsCollectorWithObjectValue, D = Record> { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: DeviceOptionWithDefault[]; + value?: D | null; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface ObjectOptionsCollectorWithStringValue { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + validation: ValidationRequired[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: DeviceOptionNoDefault[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ObjectValueAutoCollector = AutoCollector<'ObjectValueAutoCollector', 'ObjectValueAutoCollector', Record>; + +// @public (undocumented) +export type ObjectValueAutoCollectorTypes = 'ObjectValueAutoCollector' | 'FidoRegistrationCollector' | 'FidoAuthenticationCollector' | 'MetadataCollector'; + +// @public (undocumented) +export type ObjectValueCollector = ObjectOptionsCollectorWithObjectValue | ObjectOptionsCollectorWithStringValue | ObjectValueCollectorWithObjectValue; + +// @public (undocumented) +export type ObjectValueCollectors = DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | PhoneNumberExtensionCollector | ObjectOptionsCollectorWithObjectValue<'ObjectSelectCollector'> | ObjectOptionsCollectorWithStringValue<'ObjectSelectCollector'>; + +// @public +export type ObjectValueCollectorTypes = 'DeviceAuthenticationCollector' | 'DeviceRegistrationCollector' | 'PhoneNumberCollector' | 'PhoneNumberExtensionCollector' | 'ObjectOptionsCollector' | 'ObjectValueCollector' | 'ObjectSelectCollector'; + +// @public (undocumented) +export interface ObjectValueCollectorWithObjectValue, OV = Record> { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: IV; + type: string; + validation: (ValidationRequired | ValidationPhoneNumber)[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value?: OV | null; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface OutgoingQueryParams { + // (undocumented) + [key: string]: string | string[]; +} + +// @public (undocumented) +export interface PasswordCollector { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + verify: boolean; + }; + // (undocumented) + type: 'PasswordCollector'; +} + +// @public +export type PasswordField = { + type: 'PASSWORD' | 'PASSWORD_VERIFY'; + key: string; + label: string; + required?: boolean; + verify?: boolean; + passwordPolicy?: PasswordPolicy; +}; + +// @public +export interface PasswordPolicy { + // (undocumented) + createdAt?: string; + // (undocumented) + default?: boolean; + // (undocumented) + description?: string; + // (undocumented) + excludesCommonlyUsed?: boolean; + // (undocumented) + excludesProfileData?: boolean; + // (undocumented) + history?: { + count?: number; + retentionDays?: number; + }; + // (undocumented) + id?: string; + // (undocumented) + length?: { + min?: number; + max?: number; + }; + // (undocumented) + lockout?: { + failureCount?: number; + durationSeconds?: number; + }; + // (undocumented) + maxAgeDays?: number; + // (undocumented) + maxRepeatedCharacters?: number; + // (undocumented) + minAgeDays?: number; + // (undocumented) + minCharacters?: Record; + // (undocumented) + minUniqueCharacters?: number; + // (undocumented) + name?: string; + // (undocumented) + notSimilarToCurrent?: boolean; + // (undocumented) + populationCount?: number; + // (undocumented) + updatedAt?: string; +} + +// @public (undocumented) +export type PhoneNumberCollector = ObjectValueCollectorWithObjectValue<'PhoneNumberCollector', PhoneNumberInputValue, PhoneNumberOutputValue>; + +// @public (undocumented) +export interface PhoneNumberExtensionCollector { + // (undocumented) + category: 'ObjectValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: PhoneNumberExtensionInputValue; + type: string; + validation: (ValidationRequired | ValidationPhoneNumber)[] | null; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + extensionLabel: string; + value: PhoneNumberExtensionOutputValue; + }; + // (undocumented) + type: 'PhoneNumberExtensionCollector'; +} + +// @public (undocumented) +export type PhoneNumberExtensionField = PhoneNumberField & { + showExtension: boolean; + extensionLabel: string; +}; + +// @public (undocumented) +export interface PhoneNumberExtensionInputValue { + // (undocumented) + countryCode: string; + // (undocumented) + extension: string; + // (undocumented) + phoneNumber: string; +} + +// @public (undocumented) +export interface PhoneNumberExtensionOutputValue { + // (undocumented) + countryCode?: string; + // (undocumented) + extension?: string; + // (undocumented) + phoneNumber?: string; +} + +// @public (undocumented) +export type PhoneNumberField = { + type: 'PHONE_NUMBER'; + key: string; + label: string; + required: boolean; + defaultCountryCode: string | null; + validatePhoneNumber: boolean; +}; + +// @public (undocumented) +export interface PhoneNumberInputValue { + // (undocumented) + countryCode: string; + // (undocumented) + phoneNumber: string; +} + +// @public (undocumented) +export interface PhoneNumberOutputValue { + // (undocumented) + countryCode?: string; + // (undocumented) + phoneNumber?: string; +} + +// @public +export type Poller = () => Promise; + +// @public (undocumented) +export type PollingCollector = AutoCollector<'SingleValueAutoCollector', 'PollingCollector', string, PollingOutputValue>; + +// @public (undocumented) +export type PollingField = { + type: 'POLLING'; + key: string; + pollInterval: number; + pollRetries: number; + pollChallengeStatus?: boolean; + challenge?: string; +}; + +// @public (undocumented) +export interface PollingOutputValue { + // (undocumented) + challenge?: string; + // (undocumented) + pollChallengeStatus?: boolean; + // (undocumented) + pollInterval: number; + // (undocumented) + pollRetries: number; + // (undocumented) + retriesRemaining?: number; +} + +// @public (undocumented) +export type PollingStatus = PollingStatusContinue | PollingStatusChallenge; + +// @public (undocumented) +export type PollingStatusChallenge = PollingStatusChallengeComplete | 'expired' | 'timedOut' | 'error'; + +// @public (undocumented) +export type PollingStatusChallengeComplete = 'approved' | 'denied' | 'continue' | CustomPollingStatus; + +// @public (undocumented) +export type PollingStatusContinue = 'continue' | 'timedOut'; + +// @public (undocumented) +export type ProtectCollector = AutoCollector<'SingleValueAutoCollector', 'ProtectCollector', string, ProtectOutputValue>; + +// @public (undocumented) +export type ProtectField = { + type: 'PROTECT'; + key: string; + behavioralDataCollection: boolean; + universalDeviceIdentification: boolean; +}; + +// @public +export interface ProtectOutputValue { + // (undocumented) + behavioralDataCollection: boolean; + // (undocumented) + universalDeviceIdentification: boolean; +} + +// @public +export interface QrCodeCollector extends NoValueCollectorBase<'QrCodeCollector'> { + // (undocumented) + output: NoValueCollectorBase<'QrCodeCollector'>['output'] & { + src: string; + }; +} + +// @public (undocumented) +export type QrCodeField = { + type: 'QR_CODE'; + key: string; + content: string; + fallbackText?: string; +}; + +// @public +export interface ReadOnlyCollector extends NoValueCollectorBase<'ReadOnlyCollector'> { + // (undocumented) + output: NoValueCollectorBase<'ReadOnlyCollector'>['output'] & { + content: string; + title?: string; + }; +} + +// @public (undocumented) +export type ReadOnlyField = { + type: 'LABEL'; + content: string; + richContent?: RichContent; + key?: string; +}; + +// @public (undocumented) +export type ReadOnlyFields = ReadOnlyField | QrCodeField | AgreementField | ImageField; + +// @public (undocumented) +export type RedirectField = { + type: 'SOCIAL_LOGIN_BUTTON'; + key: string; + label: string; + links: Links; +}; + +// @public (undocumented) +export type RedirectFields = RedirectField; + +export { RequestMiddleware } + +// @public +export type RichContent = { + content: string; + replacements?: Record; +}; + +// @public +export interface RichContentLink { + // (undocumented) + href: string; + // (undocumented) + key: string; + // (undocumented) + target?: '_self' | '_blank'; + // (undocumented) + type: 'link'; + // (undocumented) + value: string; +} + +// @public +export type RichContentReplacement = { + type: 'link'; + value: string; + href: string; + target?: '_self' | '_blank'; +}; + +// @public +export interface RichTextCollector extends NoValueCollectorBase<'RichTextCollector'> { + // (undocumented) + output: NoValueCollectorBase<'RichTextCollector'>['output'] & { + content: string; + richContent: CollectorRichContent; + }; +} + +// @public (undocumented) +export interface SelectorOption { + // (undocumented) + label: string; + // (undocumented) + value: string; +} + +// @public (undocumented) +export type SingleCheckboxField = { + type: 'SINGLE_CHECKBOX'; + inputType: 'BOOLEAN'; + key: string; + label: string; + required?: boolean; + errorMessage?: string; + appearance: string; + richContent?: RichContent; +}; + +// @public (undocumented) +export type SingleSelectCollector = SingleSelectCollectorWithValue<'SingleSelectCollector'>; + +// @public (undocumented) +export interface SingleSelectCollectorNoValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export interface SingleSelectCollectorWithValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: string | number | boolean; + options: SelectorOption[]; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleSelectField = { + inputType: 'SINGLE_SELECT'; + key: string; + label: string; + options: { + label: string; + value: string; + }[]; + required?: boolean; + type: 'RADIO' | 'DROPDOWN'; +}; + +// @public (undocumented) +export type SingleValueAutoCollector = AutoCollector<'SingleValueAutoCollector', 'SingleValueAutoCollector', string>; + +// @public (undocumented) +export type SingleValueAutoCollectorTypes = 'SingleValueAutoCollector' | 'ProtectCollector' | 'PollingCollector'; + +// @public +export type SingleValueCollector = SingleValueCollectorWithValue | SingleValueCollectorNoValue; + +// @public (undocumented) +export interface SingleValueCollectorNoValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleValueCollectors = PasswordCollector | ValidatedPasswordCollector | SingleSelectCollector | TextCollector | ValidatedTextCollector | BooleanCollector | ValidatedBooleanCollector | SingleValueCollectorWithValue<'SingleValueCollector'>; + +// @public +export type SingleValueCollectorTypes = 'PasswordCollector' | 'ValidatedPasswordCollector' | 'BooleanCollector' | 'ValidatedBooleanCollector' | 'SingleValueCollector' | 'SingleSelectCollector' | 'SingleSelectObjectCollector' | 'TextCollector' | 'ValidatedTextCollector'; + +// @public (undocumented) +export interface SingleValueCollectorWithValue { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: V; + type: string; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: V; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type SingleValueFields = StandardField | PasswordField | ValidatedField | SingleCheckboxField | SingleSelectField | ProtectField; + +// @public (undocumented) +export type StandardField = { + type: 'TEXT' | 'SUBMIT_BUTTON' | 'FLOW_BUTTON' | 'FLOW_LINK' | 'BUTTON'; + key: string; + label: string; + required?: boolean; +}; + +// @public (undocumented) +export interface StartNode { + // (undocumented) + cache: null; + // (undocumented) + client: { + status: 'start'; + }; + // (undocumented) + error: DaVinciError | null; + // (undocumented) + server: { + status: 'start'; + }; + // (undocumented) + status: 'start'; +} + +// @public (undocumented) +export interface StartOptions { + // (undocumented) + query: Query; +} + +// @public (undocumented) +export type SubmitCollector = ActionCollectorNoUrl<'SubmitCollector'>; + +// @public (undocumented) +export interface SuccessNode { + // (undocumented) + cache: { + key: string; + }; + // (undocumented) + client: { + authorization?: { + code?: string; + state?: string; + }; + status: 'success'; + } | null; + // (undocumented) + error: null; + // (undocumented) + httpStatus: number; + // (undocumented) + server: { + _links?: Links; + eventName?: string; + id?: string; + interactionId?: string; + interactionToken?: string; + href?: string; + session?: string; + status: 'success'; + }; + // (undocumented) + status: 'success'; +} + +// @public (undocumented) +export type TextCollector = SingleValueCollectorWithValue<'TextCollector'>; + +// @public (undocumented) +export interface ThrownQueryError { + // (undocumented) + error: FetchBaseQueryError; + // (undocumented) + isHandledError: boolean; + // (undocumented) + meta: FetchBaseQueryMeta; +} + +// @public +export type UnknownCollector = { + category: 'UnknownCollector'; + error: string | null; + type: 'UnknownCollector'; + id: string; + name: string; + output: { + key: string; + label: string; + type: string; + }; +}; + +// @public (undocumented) +export type UnknownField = Record; + +// @public +export type UpdatableCollectors = SingleValueCollectors | MultiSelectCollector | ObjectValueCollectors | AutoCollectors; + +// @public (undocumented) +export const updateCollectorValues: ActionCreatorWithPayload< { +id: string; +value: CollectorValueTypes; +index?: number; +}, string>; + +// @public +export type Updater = (value: CollectorValueType, index?: number) => InternalErrorResponse | null; + +// @public (undocumented) +export interface ValidatedBooleanCollector extends ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean> { + // (undocumented) + output: ValidatedSingleValueCollectorWithValue<'ValidatedBooleanCollector', boolean>['output'] & { + appearance: string; + richContent?: CollectorRichContent; + }; +} + +// @public +export type ValidatedCollectors = ValidatedTextCollector | ValidatedBooleanCollector | ValidatedPasswordCollector | ObjectValueCollectors | MultiValueCollectors | AutoCollectors; + +// @public (undocumented) +export type ValidatedField = { + type: 'TEXT'; + key: string; + label: string; + required: boolean; + validation: { + regex: string; + errorMessage: string; + }; +}; + +// @public (undocumented) +export interface ValidatedPasswordCollector { + // (undocumented) + category: 'SingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + value: string | number | boolean; + type: string; + validation: PasswordPolicy; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + verify: boolean; + }; + // (undocumented) + type: 'ValidatedPasswordCollector'; +} + +// @public (undocumented) +export interface ValidatedSingleValueCollectorWithValue { + // (undocumented) + category: 'ValidatedSingleValueCollector'; + // (undocumented) + error: string | null; + // (undocumented) + id: string; + // (undocumented) + input: { + key: string; + type: string; + validation: (ValidationRequired | ValidationRegex)[]; + value: V; + }; + // (undocumented) + name: string; + // (undocumented) + output: { + key: string; + label: string; + type: string; + value: V; + }; + // (undocumented) + type: T; +} + +// @public (undocumented) +export type ValidatedTextCollector = ValidatedSingleValueCollectorWithValue<'TextCollector'>; + +// @public (undocumented) +export interface ValidationPhoneNumber { + // (undocumented) + message: string; + // (undocumented) + rule: boolean; + // (undocumented) + type: 'validatePhoneNumber'; +} + +// @public (undocumented) +export interface ValidationRegex { + // (undocumented) + message: string; + // (undocumented) + rule: string; + // (undocumented) + type: 'regex'; +} + +// @public (undocumented) +export interface ValidationRequired { + // (undocumented) + message: string; + // (undocumented) + rule: boolean; + // (undocumented) + type: 'required'; +} + +// @public +export type Validator = (value: CollectorValueType) => string[] | { + error: { + message: string; + type: string; + }; + type: string; +}; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/davinci-client/package.json b/packages/davinci-client/package.json index d91b800251e..815d9bfe71e 100644 --- a/packages/davinci-client/package.json +++ b/packages/davinci-client/package.json @@ -32,6 +32,7 @@ "@forgerock/sdk-request-middleware": "workspace:*", "@forgerock/sdk-types": "workspace:*", "@forgerock/sdk-utilities": "workspace:*", + "@forgerock/sdk-wellknown": "workspace:*", "@forgerock/storage": "workspace:*", "@reduxjs/toolkit": "catalog:", "effect": "catalog:effect", diff --git a/packages/davinci-client/src/lib/client.store.effects.test.ts b/packages/davinci-client/src/lib/client.store.effects.test.ts index 0714104d23c..9b9c91cfc13 100644 --- a/packages/davinci-client/src/lib/client.store.effects.test.ts +++ b/packages/davinci-client/src/lib/client.store.effects.test.ts @@ -6,7 +6,7 @@ */ import { it } from '@effect/vitest'; -import { Micro } from 'effect'; +import { Effect, Exit } from 'effect'; import { describe, expect, vi } from 'vitest'; import { @@ -186,7 +186,7 @@ describe('getPollingModeµ', () => { }; it.effect('succeeds with challenge mode when challenge and pollChallengeStatus are set', () => - Micro.gen(function* () { + Effect.gen(function* () { const collector: PollingCollector = { ...basePollingCollector, output: { @@ -207,7 +207,7 @@ describe('getPollingModeµ', () => { ); it.effect('succeeds with continue mode when no challenge is present', () => - Micro.gen(function* () { + Effect.gen(function* () { const result = yield* getPollingModeµ(basePollingCollector); expect(result).toStrictEqual({ @@ -219,7 +219,7 @@ describe('getPollingModeµ', () => { ); it.effect('succeeds with unknown mode for ambiguous configuration', () => - Micro.gen(function* () { + Effect.gen(function* () { const collector: PollingCollector = { ...basePollingCollector, output: { @@ -240,13 +240,13 @@ describe('getPollingModeµ', () => { ); it.effect('fails when collector type is not PollingCollector', () => - Micro.gen(function* () { + Effect.gen(function* () { const badCollector = { ...basePollingCollector, type: 'TextCollector' } as any; - const result = yield* Micro.exit(getPollingModeµ(badCollector)); + const result = yield* Effect.exit(getPollingModeµ(badCollector)); expect(result).toStrictEqual( - Micro.exitFail({ + Exit.fail({ error: { message: 'Collector provided to poll is not a PollingCollector', type: 'argument_error', @@ -258,7 +258,7 @@ describe('getPollingModeµ', () => { ); it.effect('fails when retriesRemaining is undefined in continue mode', () => - Micro.gen(function* () { + Effect.gen(function* () { const collector: PollingCollector = { ...basePollingCollector, output: { @@ -267,10 +267,10 @@ describe('getPollingModeµ', () => { }, }; - const result = yield* Micro.exit(getPollingModeµ(collector)); + const result = yield* Effect.exit(getPollingModeµ(collector)); expect(result).toStrictEqual( - Micro.exitFail({ + Exit.fail({ error: { message: 'No retries found on PollingCollector', type: 'argument_error', diff --git a/packages/davinci-client/src/lib/client.store.effects.ts b/packages/davinci-client/src/lib/client.store.effects.ts index 5828de19d70..7f130a7d6e0 100644 --- a/packages/davinci-client/src/lib/client.store.effects.ts +++ b/packages/davinci-client/src/lib/client.store.effects.ts @@ -5,7 +5,7 @@ * of the MIT license. See the LICENSE file for details. */ -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { createInternalError, isInternalError } from './client.store.utils.js'; import { davinciApi } from './davinci.api.js'; @@ -15,9 +15,21 @@ import type { logger as loggerFn } from '@forgerock/sdk-logger'; import type { FetchBaseQueryError } from '@reduxjs/toolkit/query/react'; import type { SerializedError } from '@reduxjs/toolkit/react'; -import type { ClientStore, RootState } from './client.store.utils.js'; +import type { DavinciStore, RootState } from './client.store.utils.js'; import type { InternalErrorResponse, PollingStatus } from './client.types.js'; import type { PollingCollector } from './collector.types.js'; +import type { ContinueNode } from './node.types.js'; + +/** + * Plain-`setTimeout` delay that bypasses Effect's ClockRef/withFiber chain. + * Required in Vite-bundled browser environments where Effect.sleep can hang + * due to the ClockRef scheduler not draining in a browser event loop. + */ +const delayMs = (ms: number): Effect.Effect => + Effect.callback((resume) => { + const handle = setTimeout(() => resume(Effect.void), ms); + return Effect.sync(() => clearTimeout(handle)); + }); /** * Shape returned by RTK Query's dispatch for the poll endpoint. @@ -55,9 +67,9 @@ const isRecord = (value: unknown): value is Record => */ export function getPollingModeµ( collector: PollingCollector, -): Micro.Micro { +): Effect.Effect { if (collector.type !== 'PollingCollector') { - return Micro.fail( + return Effect.fail( createInternalError('Collector provided to poll is not a PollingCollector', 'argument_error'), ); } @@ -66,23 +78,23 @@ export function getPollingModeµ( collector.output.config; if (challenge && pollChallengeStatus === true) { - return Micro.succeed({ _tag: 'challenge', challenge }); + return Effect.succeed({ _tag: 'challenge', challenge }); } if (!challenge && !pollChallengeStatus) { if (retriesRemaining === undefined) { - return Micro.fail( + return Effect.fail( createInternalError('No retries found on PollingCollector', 'argument_error'), ); } - return Micro.succeed({ + return Effect.succeed({ _tag: 'continue', retriesRemaining, pollInterval: pollInterval ?? 2000, }); } - return Micro.succeed({ _tag: 'unknown' }); + return Effect.succeed({ _tag: 'unknown' }); } /** @@ -114,16 +126,16 @@ export function buildChallengeEndpoint( } /** - * Lifts a selector result with { error, state } shape into a Micro. + * Lifts a selector result with { error, state } shape into an Effect. * Succeeds with state when error is null, fails with InternalErrorResponse otherwise. */ function fromSelectorµ(result: { error: { message: string } | null; state: T; -}): Micro.Micro, InternalErrorResponse> { +}): Effect.Effect, InternalErrorResponse> { return result.error - ? Micro.fail(createInternalError(result.error.message, 'state_error')) - : Micro.succeed(result.state as NonNullable); + ? Effect.fail(createInternalError(result.error.message, 'state_error')) + : Effect.succeed(result.state as NonNullable); } /** @@ -133,35 +145,35 @@ function fromSelectorµ(result: { export function validatePollingPrerequisitesµ( rootState: RootState, challenge: string, -): Micro.Micro { +): Effect.Effect { if (!challenge) { - return Micro.fail( + return Effect.fail( createInternalError('No challenge found on collector for poll operation', 'state_error'), ); } return fromSelectorµ(nodeSlice.selectors.selectContinueServer(rootState)).pipe( - Micro.filterOrFail( - (server) => !!server.interactionId, + Effect.filterOrFail( + (server: ContinueNode['server']) => !!server.interactionId, () => createInternalError( 'Missing interactionId in server info for challenge polling', 'state_error', ), ), - Micro.flatMap((server) => + Effect.flatMap((server: ContinueNode['server']) => fromSelectorµ(nodeSlice.selectors.selectSelfLink(rootState)).pipe( - Micro.map((selfLink) => ({ server, selfLink })), + Effect.map((selfLink) => ({ server, selfLink })), ), ), - Micro.flatMap(({ server, selfLink }) => { + Effect.flatMap(({ server, selfLink }: { server: ContinueNode['server']; selfLink: string }) => { const endpoint = buildChallengeEndpoint(selfLink, challenge); return typeof endpoint === 'string' - ? Micro.succeed({ + ? Effect.succeed({ interactionId: server.interactionId!, challengeEndpoint: endpoint, }) - : Micro.fail(endpoint); + : Effect.fail(endpoint); }), ); } @@ -222,14 +234,14 @@ export function interpretChallengeResponse( return pollStatus ? (pollStatus as PollingStatus) : 'error'; } - // If we reach here, Micro.repeat exhausted its schedule without the challenge completing + // If we reach here, the poll loop exhausted its retries without the challenge completing log.debug('Challenge polling timed out'); return 'timedOut'; } /** - * Builds a Micro effect for the challenge polling branch. - * validate → dispatch → repeat → interpret → lift errors + * Builds an Effect for the challenge polling branch. + * validate → dispatch initial → loop (sleep + re-dispatch) while pending → interpret */ function challengePollingµ({ collector, @@ -239,53 +251,62 @@ function challengePollingµ({ }: { collector: PollingCollector; challenge: string; - store: ReturnType; + store: DavinciStore; log: ReturnType; -}): Micro.Micro { +}): Effect.Effect { const maxRetries = collector.output.config.pollRetries ?? 60; const pollInterval = collector.output.config.pollInterval ?? 2000; - return validatePollingPrerequisitesµ(store.getState(), challenge).pipe( - Micro.flatMap(({ interactionId, challengeEndpoint }) => - Micro.promise(() => + return Effect.gen(function* () { + const { interactionId, challengeEndpoint } = yield* validatePollingPrerequisitesµ( + store.getState(), + challenge, + ); + + const doPoll = (): Effect.Effect => + Effect.promise(() => store.dispatch( davinciApi.endpoints.poll.initiate({ endpoint: challengeEndpoint, interactionId, }), ), - ), - ), - Micro.repeat({ - while: isChallengeStillPending, - // `times` tracks repetitions after the initial attempt, so decrement by one - times: maxRetries - 1, - schedule: Micro.scheduleSpaced(pollInterval), - }), - Micro.map((response) => interpretChallengeResponse(response, log)), - Micro.flatMap((result) => - isInternalError(result) ? Micro.fail(result) : Micro.succeed(result), - ), - ); + ); + + let response: PollDispatchResult = yield* doPoll(); + + for (let i = 0; i < maxRetries - 1 && isChallengeStillPending(response); i++) { + yield* delayMs(pollInterval); + response = yield* doPoll(); + } + + const status = interpretChallengeResponse(response, log); + + if (isInternalError(status)) { + return yield* Effect.fail(status); + } + + return status; + }); } /** - * Builds a Micro effect for the continue polling branch. + * Builds an Effect for the continue polling branch. * If retries remain, delays by pollInterval then returns 'continue'. * If retries are exhausted, returns 'timedOut' immediately. */ function continuePollingµ( mode: Extract, -): Micro.Micro { +): Effect.Effect { if (mode.retriesRemaining <= 0) { - return Micro.succeed('timedOut' as PollingStatus); + return Effect.succeed('timedOut'); } - return Micro.sleep(mode.pollInterval).pipe(Micro.map(() => 'continue')); + return delayMs(mode.pollInterval).pipe(Effect.map(() => 'continue')); } /** * Routes a validated PollingMode to the appropriate polling effect. - * This is the single entry point — the caller lifts getPollingMode into Micro, pipes through this. + * This is the single entry point — the caller lifts getPollingMode into Effect, pipes through this. */ export function pollingµ({ mode, @@ -295,9 +316,9 @@ export function pollingµ({ }: { mode: PollingMode; collector: PollingCollector; - store: ReturnType; + store: DavinciStore; log: ReturnType; -}): Micro.Micro { +}): Effect.Effect { if (mode._tag === 'challenge') { return challengePollingµ({ collector, challenge: mode.challenge, store, log }); } @@ -306,7 +327,7 @@ export function pollingµ({ return continuePollingµ(mode); } - return Micro.fail( + return Effect.fail( createInternalError('Invalid polling collector configuration', 'argument_error'), ); } diff --git a/packages/davinci-client/src/lib/client.store.ts b/packages/davinci-client/src/lib/client.store.ts index 1fae4b490c1..6a4f9ac06eb 100644 --- a/packages/davinci-client/src/lib/client.store.ts +++ b/packages/davinci-client/src/lib/client.store.ts @@ -6,9 +6,9 @@ */ import { logger as loggerFn } from '@forgerock/sdk-logger'; import { createWellknownError, isGenericError } from '@forgerock/sdk-utilities'; +import { wellknownApi } from '@forgerock/sdk-wellknown'; import { createStorage } from '@forgerock/storage'; -import { Either, Micro } from 'effect'; -import { exitIsFail, exitIsSuccess } from 'effect/Micro'; +import { Cause, Effect, Exit, Option, Result } from 'effect'; import { getPollingModeµ, pollingµ } from './client.store.effects.js'; /** @@ -20,17 +20,19 @@ import { handleUpdateValidateError, isValidCollectorCategory, resolveCollectorUpdateValue, + toSdkStore, } from './client.store.utils.js'; import { returnValidator } from './collector.utils.js'; import { configSlice } from './config.slice.js'; import { davinciApi } from './davinci.api.js'; import { nodeSlice } from './node.slice.js'; import { returnPasswordPolicyValidator } from './password-policy.rules.js'; -import { wellknownApi } from './wellknown.api.js'; import type { CustomLogger, LogLevel } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import type { SdkStore } from '@forgerock/sdk-types'; +import type { PollingMode } from './client.store.effects.js'; import type { RootState } from './client.store.utils.js'; import type { CollectorValueTypes, @@ -85,7 +87,8 @@ export async function davinci({ level: logger?.level ?? config.log ?? 'error', custom: logger?.custom, }); - const store = createClientStore({ requestMiddleware, logger: log }); + const injectable = createClientStore({ requestMiddleware, logger: log }); + const store = injectable.store; const serverInfo = createStorage({ type: 'localStorage', name: 'serverInfo', @@ -117,6 +120,8 @@ export async function davinci({ store.dispatch(configSlice.actions.set({ ...config, wellknownResponse: openIdResponse })); return { + // Opaque store handle — pass to oidc() to share this store + store: toSdkStore(injectable) as SdkStore, // Pass store methods to the client subscribe: store.subscribe, @@ -356,9 +361,9 @@ export async function davinci({ * shape, so the cast is safe. */ const result = resolveCollectorUpdateValue(collectorToUpdate as UpdatableCollectors, value); - if (Either.isLeft(result)) { - log.error(result.left.error.message); - return result.left; + if (Result.isFailure(result)) { + log.error(result.failure.error.message); + return result.failure; } // Update the collector in the store with the value @@ -454,18 +459,28 @@ export async function davinci({ */ pollStatus: (collector: PollingCollector): Poller => { return async () => { - const result = await getPollingModeµ(collector).pipe( - Micro.flatMap((mode) => pollingµ({ mode, collector, store, log })), - Micro.tapError((err) => Micro.sync(() => log.error(err.error.message))), - Micro.runPromiseExit, + const pollingEffect = getPollingModeµ(collector).pipe( + Effect.flatMap((mode: PollingMode) => pollingµ({ mode, collector, store, log })), + Effect.tapError((err: InternalErrorResponse) => + Effect.sync(() => log.error(err.error.message)), + ), ); - if (exitIsSuccess(result)) { + const result = await Effect.runPromiseExit(pollingEffect); + + if (Exit.isSuccess(result)) { return result.value; } - if (exitIsFail(result)) { - return result.cause.error; + if (Exit.isFailure(result)) { + const maybeError = Cause.findErrorOption(result.cause); + if (Option.isSome(maybeError)) { + return maybeError.value; + } + // Handle defects (unexpected thrown errors) + const defect = Cause.squash(result.cause); + const message = defect instanceof Error ? defect.message : String(defect); + return createInternalError(message, 'unknown_error'); } return createInternalError( diff --git a/packages/davinci-client/src/lib/client.store.utils.ts b/packages/davinci-client/src/lib/client.store.utils.ts index 31e4eda11dc..a9176679ea2 100644 --- a/packages/davinci-client/src/lib/client.store.utils.ts +++ b/packages/davinci-client/src/lib/client.store.utils.ts @@ -4,32 +4,50 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { configureStore } from '@reduxjs/toolkit'; -import { Either, Match } from 'effect'; +import { wellknownApi } from '@forgerock/sdk-wellknown'; +import { combineSlices, configureStore, createDynamicMiddleware } from '@reduxjs/toolkit'; import { configSlice } from './config.slice.js'; import { davinciApi } from './davinci.api.js'; import { nodeSlice } from './node.slice.js'; -import { wellknownApi } from './wellknown.api.js'; import type { logger as loggerFn } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; import type { GenericError } from '@forgerock/sdk-types'; -import type { - CollectorValueType, - CollectorValueTypes, - InternalErrorResponse, - UpdatableCollectors, -} from './client.types.js'; -import type { - CollectorCategory, - Collectors, - ContinueNode, - ErrorNode, - StartNode, - SuccessNode, -} from './node.types.js'; +import type { InternalErrorResponse } from './client.types.js'; +import type { ContinueNode, ErrorNode, StartNode, SuccessNode } from './node.types.js'; + +/** + * Root reducer built with combineSlices to support lazy injection. + * External slices (e.g. oidcApi) can be injected via rootReducer.inject(). + */ +export const rootReducer = combineSlices( + configSlice, + nodeSlice, + davinciApi, + wellknownApi, +).withLazyLoadedSlices(); + +export type RootState = ReturnType; + +export interface RootStateWithNode< + T extends ErrorNode | ContinueNode | StartNode | SuccessNode, +> extends RootState { + node: T; +} + +/** + * Internal store shape that carries the root reducer and dynamic middleware + * so that oidc-client can inject its reducers and middleware at init time. + * + * Consumers only ever see the opaque SdkStore type. + */ +export interface InjectableStore { + readonly store: ReturnType>; + readonly rootReducer: typeof rootReducer; + readonly dynamicMiddleware: ReturnType; +} export function createClientStore({ requestMiddleware, @@ -37,14 +55,11 @@ export function createClientStore({ }: { requestMiddleware?: RequestMiddleware[]; logger?: ReturnType; -}) { - return configureStore({ - reducer: { - config: configSlice.reducer, - node: nodeSlice.reducer, - [davinciApi.reducerPath]: davinciApi.reducer, - [wellknownApi.reducerPath]: wellknownApi.reducer, - }, +}): InjectableStore { + const dynamicMiddleware = createDynamicMiddleware(); + + const store = configureStore({ + reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ thunk: { @@ -59,21 +74,36 @@ export function createClientStore({ }, }) .concat(davinciApi.middleware) - .concat(wellknownApi.middleware), + .concat(wellknownApi.middleware) + .concat(dynamicMiddleware.middleware), }); + + return { store, rootReducer, dynamicMiddleware }; } export type ClientStore = typeof createClientStore; -export type RootState = ReturnType['getState']>; +/** The inner Redux store type — used by effects that need dispatch/getState. */ +export type DavinciStore = InjectableStore['store']; -export interface RootStateWithNode< - T extends ErrorNode | ContinueNode | StartNode | SuccessNode, -> extends RootState { - node: T; -} +export type AppDispatch = ReturnType; -export type AppDispatch = ReturnType['dispatch']>; +export function handleUpdateValidateError( + message: string, + type: 'argument_error' | 'state_error', + cb: (message: string) => void, +): () => InternalErrorResponse { + cb(message); + return function () { + return { + error: { + message: message, + type: type, + }, + type: 'internal_error' as const, + }; + }; +} /** * @function createInternalError @@ -101,160 +131,14 @@ export function isInternalError(value: unknown): value is InternalErrorResponse ); } -/** - * Logs a collector update or validation failure and returns a - * function producing the corresponding `InternalErrorResponse`. - * - * @param message - The error message to log and embed in the response - * @param type - Whether the failure stems from a bad argument or invalid state - * @param cb - Logging callback invoked with `message` (e.g. `log.error`) - * @returns A function that, when called, returns the `InternalErrorResponse` - */ -export function handleUpdateValidateError( - message: string, - type: 'argument_error' | 'state_error', - cb: (message: string) => void, -): () => InternalErrorResponse { - cb(message); - return function () { - return { - error: { - message: message, - type: type, - }, - type: 'internal_error' as const, - }; - }; -} +export { isValidCollectorCategory, resolveCollectorUpdateValue } from './collector.resolver.js'; -/** - * Type guard: checks whether a collector's `category` is one of the given - * `validCategories`, narrowing it to the matching union member on success. - * - * @param collector - The collector to check - * @param validCategories - The set of categories considered valid - * @returns `true` if `collector.category` is included in `validCategories` - */ -export function isValidCollectorCategory( - collector: Collectors, - validCategories: C[], -): collector is Extract { - return validCategories.some((validCategory) => collector.category === validCategory); +/** Cast InjectableStore to the opaque SdkStore for public API exposure. */ +export function toSdkStore(injectable: InjectableStore): object { + return injectable as unknown as object; } -/** - * Validates a value against the shape a given collector accepts, returning the - * value narrowed to `CollectorValueType` on success. - * - * This is the single source of truth for the collector→value-type correlation: - * both `update()` (pre-dispatch, to fail fast) and the `node/update` reducer - * (post-dispatch, to type the assignment) call this same function so the - * mapping can't drift between the two call sites. - * - * @param collector - The collector the value is being validated against - * @param value - The candidate value to validate - * @returns `Either.right` with the narrowed value, or `Either.left` with the validation error - */ -export function resolveCollectorUpdateValue( - collector: T, - value: CollectorValueTypes, -): Either.Either, InternalErrorResponse> { - const ok = (v: CollectorValueTypes) => Either.right(v as CollectorValueType); - const err = (message: string) => Either.left(createInternalError(message, 'argument_error')); - - if (value === undefined) { - return err('Value argument cannot be undefined'); - } - - return Match.value(collector).pipe( - Match.when({ type: 'BooleanCollector' }, () => - typeof value === 'boolean' ? ok(value) : err('Value argument must be a boolean'), - ), - Match.when({ type: 'ValidatedBooleanCollector' }, () => - typeof value === 'boolean' ? ok(value) : err('Value argument must be a boolean'), - ), - Match.when({ type: 'DeviceAuthenticationCollector' }, (c) => { - if (typeof value !== 'string') return err('Value argument must be a string'); - const option = c.output.options.find((option) => option.value === value); - return option ? ok(value) : err('No option found matching value to update'); - }), - Match.when({ type: 'DeviceRegistrationCollector' }, (c) => { - if (typeof value !== 'string') return err('Value argument must be a string'); - const option = c.output.options.find((option) => option.value === value); - return option ? ok(value) : err('No option found matching value to update'); - }), - Match.when({ type: 'PhoneNumberCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - if (!('phoneNumber' in value) || !('countryCode' in value)) { - return err('Value argument must contain a phoneNumber and countryCode property'); - } - return ok(value); - }), - Match.when({ type: 'PhoneNumberExtensionCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - if (!('phoneNumber' in value) || !('countryCode' in value) || !('extension' in value)) { - return err( - 'Value argument must contain a phoneNumber, countryCode, and extension property', - ); - } - return ok(value); - }), - Match.when({ type: 'FidoRegistrationCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - const isFidoError = 'type' in value && value.type === 'fido_error'; - if (!isFidoError && !('attestationValue' in value)) { - return err('Value argument must contain an attestationValue property'); - } - return ok(value); - }), - Match.when({ type: 'FidoAuthenticationCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - const isFidoError = 'type' in value && value.type === 'fido_error'; - if (!isFidoError && !('assertionValue' in value)) { - return err('Value argument must contain an assertionValue property'); - } - return ok(value); - }), - Match.when({ type: 'MetadataCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - return ok(value); - }), - Match.when({ category: 'SingleValueCollector' }, () => - typeof value === 'string' ? ok(value) : err('Value argument must be a string'), - ), - Match.when({ category: 'ValidatedSingleValueCollector' }, () => - typeof value === 'string' ? ok(value) : err('Value argument must be a string'), - ), - Match.when({ category: 'SingleValueAutoCollector' }, () => - typeof value === 'string' ? ok(value) : err('Value argument must be a string'), - ), - Match.when({ category: 'MultiValueCollector' }, () => - typeof value === 'string' || Array.isArray(value) - ? ok(value) - : err('MultiValueCollector does not accept an object'), - ), - Match.when({ category: 'ObjectValueCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - return ok(value); - }), - Match.when({ category: 'ObjectValueAutoCollector' }, () => { - if (typeof value !== 'object' || value === null || Array.isArray(value)) { - return err('Value argument must be an object'); - } - return ok(value); - }), - Match.exhaustive, - ); +/** Recover the InjectableStore from an opaque SdkStore handle. */ +export function fromSdkStore(sdkStore: object): InjectableStore { + return sdkStore as unknown as InjectableStore; } diff --git a/packages/davinci-client/src/lib/collector.resolver.ts b/packages/davinci-client/src/lib/collector.resolver.ts new file mode 100644 index 00000000000..5e85a279184 --- /dev/null +++ b/packages/davinci-client/src/lib/collector.resolver.ts @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +/** + * Pure resolver functions for collector value validation. + * + * Extracted from client.store.utils.ts into its own module to break the + * circular import chain: + * + * node.slice.ts → node.reducer.ts → client.store.utils.ts → nodeSlice (node.slice.ts) + * + * By living here, node.reducer.ts can import these functions without touching + * client.store.utils.ts (which imports nodeSlice). client.store.utils.ts + * re-exports from this file to preserve its public API. + */ +import { Match, Result } from 'effect'; + +import type { GenericError } from '@forgerock/sdk-types'; + +import type { + CollectorValueType, + CollectorValueTypes, + InternalErrorResponse, + UpdatableCollectors, +} from './client.types.js'; +import type { CollectorCategory, Collectors } from './node.types.js'; + +/** Locally-inlined copy of createInternalError to avoid importing from client.store.utils.ts, + * which imports nodeSlice (node.slice.ts) and would recreate the circular dependency. + */ +function createInternalError( + message: string, + type: GenericError['type'] = 'internal_error', +): InternalErrorResponse { + return { error: { message, type }, type: 'internal_error' }; +} + +/** + * Type guard: checks whether a collector's `category` is one of the given + * `validCategories`, narrowing it to the matching union member on success. + * + * @param collector - The collector to check + * @param validCategories - The set of categories considered valid + * @returns `true` if `collector.category` is included in `validCategories` + */ +export function isValidCollectorCategory( + collector: Collectors, + validCategories: C[], +): collector is Extract { + return validCategories.some((validCategory) => collector.category === validCategory); +} + +/** + * Validates a value against the shape a given collector accepts, returning the + * value narrowed to `CollectorValueType` on success. + * + * This is the single source of truth for the collector→value-type correlation: + * both `update()` (pre-dispatch, to fail fast) and the `node/update` reducer + * (post-dispatch, to type the assignment) call this same function so the + * mapping can't drift between the two call sites. + * + * @param collector - The collector the value is being validated against + * @param value - The candidate value to validate + * @returns `Result.succeed` with the narrowed value, or `Result.fail` with the validation error + */ +export function resolveCollectorUpdateValue( + collector: T, + value: CollectorValueTypes, +): Result.Result, InternalErrorResponse> { + const ok = (v: CollectorValueTypes) => Result.succeed(v as CollectorValueType); + const err = (message: string) => Result.fail(createInternalError(message, 'argument_error')); + + if (value === undefined) { + return err('Value argument cannot be undefined'); + } + + return Match.value(collector).pipe( + Match.when({ type: 'BooleanCollector' }, () => + typeof value === 'boolean' ? ok(value) : err('Value argument must be a boolean'), + ), + Match.when({ type: 'ValidatedBooleanCollector' }, () => + typeof value === 'boolean' ? ok(value) : err('Value argument must be a boolean'), + ), + Match.when({ type: 'DeviceAuthenticationCollector' }, (c) => { + if (typeof value !== 'string') return err('Value argument must be a string'); + const option = c.output.options.find((option) => option.value === value); + return option ? ok(value) : err('No option found matching value to update'); + }), + Match.when({ type: 'DeviceRegistrationCollector' }, (c) => { + if (typeof value !== 'string') return err('Value argument must be a string'); + const option = c.output.options.find((option) => option.value === value); + return option ? ok(value) : err('No option found matching value to update'); + }), + Match.when({ type: 'PhoneNumberCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + if (!('phoneNumber' in value) || !('countryCode' in value)) { + return err('Value argument must contain a phoneNumber and countryCode property'); + } + return ok(value); + }), + Match.when({ type: 'PhoneNumberExtensionCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + if (!('phoneNumber' in value) || !('countryCode' in value) || !('extension' in value)) { + return err( + 'Value argument must contain a phoneNumber, countryCode, and extension property', + ); + } + return ok(value); + }), + Match.when({ type: 'FidoRegistrationCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + const isFidoError = 'type' in value && value.type === 'fido_error'; + if (!isFidoError && !('attestationValue' in value)) { + return err('Value argument must contain an attestationValue property'); + } + return ok(value); + }), + Match.when({ type: 'FidoAuthenticationCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + const isFidoError = 'type' in value && value.type === 'fido_error'; + if (!isFidoError && !('assertionValue' in value)) { + return err('Value argument must contain an assertionValue property'); + } + return ok(value); + }), + Match.when({ type: 'MetadataCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + return ok(value); + }), + Match.when({ category: 'SingleValueCollector' }, () => + typeof value === 'string' ? ok(value) : err('Value argument must be a string'), + ), + Match.when({ category: 'ValidatedSingleValueCollector' }, () => + typeof value === 'string' ? ok(value) : err('Value argument must be a string'), + ), + Match.when({ category: 'SingleValueAutoCollector' }, () => + typeof value === 'string' ? ok(value) : err('Value argument must be a string'), + ), + Match.when({ category: 'MultiValueCollector' }, () => + typeof value === 'string' || Array.isArray(value) + ? ok(value) + : err('MultiValueCollector does not accept an object'), + ), + Match.when({ category: 'ObjectValueCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + return ok(value); + }), + Match.when({ category: 'ObjectValueAutoCollector' }, () => { + if (typeof value !== 'object' || value === null || Array.isArray(value)) { + return err('Value argument must be an object'); + } + return ok(value); + }), + Match.exhaustive, + ); +} diff --git a/packages/davinci-client/src/lib/config.slice.test.ts b/packages/davinci-client/src/lib/config.slice.test.ts index 5dda0d85882..9eb08dd9d45 100644 --- a/packages/davinci-client/src/lib/config.slice.test.ts +++ b/packages/davinci-client/src/lib/config.slice.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/config.slice.ts b/packages/davinci-client/src/lib/config.slice.ts index a7d9fba0475..17fdaa8476c 100644 --- a/packages/davinci-client/src/lib/config.slice.ts +++ b/packages/davinci-client/src/lib/config.slice.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/config.types.test-d.ts b/packages/davinci-client/src/lib/config.types.test-d.ts index 37e03af8ec5..cf6ca3b3635 100644 --- a/packages/davinci-client/src/lib/config.types.test-d.ts +++ b/packages/davinci-client/src/lib/config.types.test-d.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/fido/fido.ts b/packages/davinci-client/src/lib/fido/fido.ts index e49305d6c79..040353cd808 100644 --- a/packages/davinci-client/src/lib/fido/fido.ts +++ b/packages/davinci-client/src/lib/fido/fido.ts @@ -4,8 +4,7 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { Micro } from 'effect'; -import { exitIsFail, exitIsSuccess } from 'effect/Micro'; +import { Cause, Effect, Exit, Option } from 'effect'; import { createFidoError, @@ -47,14 +46,14 @@ export function fido(): FidoClient { ); } - const createCredentialµ = Micro.sync(() => transformRegistrationOptions(options)).pipe( - Micro.flatMap((publicKeyCredentialCreationOptions) => - Micro.tryPromise({ + const createCredentialµ = Effect.sync(() => transformRegistrationOptions(options)).pipe( + Effect.flatMap((publicKeyCredentialCreationOptions: PublicKeyCredentialCreationOptions) => + Effect.tryPromise({ try: () => navigator.credentials.create({ publicKey: publicKeyCredentialCreationOptions, }), - catch: (error) => { + catch: (error: unknown) => { const code = toFidoErrorCode(error); console.error('Failed to create keypair: ', code); return createFidoError( @@ -65,9 +64,9 @@ export function fido(): FidoClient { }, }), ), - Micro.flatMap((credential) => { + Effect.flatMap((credential: Credential | null) => { if (!credential) { - return Micro.fail( + return Effect.fail( createFidoError( 'UnknownError', 'registration_error', @@ -75,19 +74,25 @@ export function fido(): FidoClient { ), ); } - return Micro.succeed(transformPublicKeyCredential(credential as PublicKeyCredential)); + return Effect.succeed(transformPublicKeyCredential(credential as PublicKeyCredential)); }), ); - const result = await Micro.runPromiseExit(createCredentialµ); + const result = await Effect.runPromiseExit(createCredentialµ); - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; - } else if (exitIsFail(result)) { - return result.cause.error; - } else { - return createFidoError('UnknownError', 'registration_error', result.cause.message); } + + if (Exit.isFailure(result)) { + const maybeError = Cause.findErrorOption(result.cause); + if (Option.isSome(maybeError)) { + return maybeError.value; + } + return createFidoError('UnknownError', 'registration_error', Cause.pretty(result.cause)); + } + + return createFidoError('UnknownError', 'registration_error', 'Unexpected exit state'); }, /** @@ -104,14 +109,14 @@ export function fido(): FidoClient { ); } - const getAssertionµ = Micro.sync(() => transformAuthenticationOptions(options)).pipe( - Micro.flatMap((publicKeyCredentialRequestOptions) => - Micro.tryPromise({ + const getAssertionµ = Effect.sync(() => transformAuthenticationOptions(options)).pipe( + Effect.flatMap((publicKeyCredentialRequestOptions: PublicKeyCredentialRequestOptions) => + Effect.tryPromise({ try: () => navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions, }), - catch: (error) => { + catch: (error: unknown) => { const code = toFidoErrorCode(error); console.error('Failed to authenticate: ', code); return createFidoError( @@ -122,9 +127,9 @@ export function fido(): FidoClient { }, }), ), - Micro.flatMap((assertion) => { + Effect.flatMap((assertion: Credential | null) => { if (!assertion) { - return Micro.fail( + return Effect.fail( createFidoError( 'UnknownError', 'authentication_error', @@ -132,19 +137,25 @@ export function fido(): FidoClient { ), ); } - return Micro.succeed(transformAssertion(assertion as PublicKeyCredential)); + return Effect.succeed(transformAssertion(assertion as PublicKeyCredential)); }), ); - const result = await Micro.runPromiseExit(getAssertionµ); + const result = await Effect.runPromiseExit(getAssertionµ); - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; - } else if (exitIsFail(result)) { - return result.cause.error; - } else { - return createFidoError('UnknownError', 'authentication_error', result.cause.message); } + + if (Exit.isFailure(result)) { + const maybeError = Cause.findErrorOption(result.cause); + if (Option.isSome(maybeError)) { + return maybeError.value; + } + return createFidoError('UnknownError', 'authentication_error', Cause.pretty(result.cause)); + } + + return createFidoError('UnknownError', 'authentication_error', 'Unexpected exit state'); }, }; } diff --git a/packages/davinci-client/src/lib/fido/fido.utils.test.ts b/packages/davinci-client/src/lib/fido/fido.utils.test.ts index 6255816c4ab..67968dad572 100644 --- a/packages/davinci-client/src/lib/fido/fido.utils.test.ts +++ b/packages/davinci-client/src/lib/fido/fido.utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/node.reducer.ts b/packages/davinci-client/src/lib/node.reducer.ts index 65c7af5e93c..538a837f2ae 100644 --- a/packages/davinci-client/src/lib/node.reducer.ts +++ b/packages/davinci-client/src/lib/node.reducer.ts @@ -8,9 +8,9 @@ * Import the required utilities from Redux Toolkit */ import { createAction, createReducer } from '@reduxjs/toolkit'; -import { Either } from 'effect'; +import { Result } from 'effect'; -import { resolveCollectorUpdateValue } from './client.store.utils.js'; +import { resolveCollectorUpdateValue } from './collector.resolver.js'; /** * Import the collector utilities */ @@ -59,9 +59,8 @@ function updateCollector( cb: (resolvedValue: CollectorValueType) => void, ): void { const result = resolveCollectorUpdateValue(collector, value); - if (Either.isRight(result)) { - const resolvedValue = result.right; - cb(resolvedValue); + if (Result.isSuccess(result)) { + cb(result.success as CollectorValueType); } } diff --git a/packages/davinci-client/src/lib/node.slice.test.ts b/packages/davinci-client/src/lib/node.slice.test.ts index 948034d52fb..e92f82f8b5f 100644 --- a/packages/davinci-client/src/lib/node.slice.test.ts +++ b/packages/davinci-client/src/lib/node.slice.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/node.slice.ts b/packages/davinci-client/src/lib/node.slice.ts index f9d68afe6e6..bb7773dbec6 100644 --- a/packages/davinci-client/src/lib/node.slice.ts +++ b/packages/davinci-client/src/lib/node.slice.ts @@ -9,9 +9,6 @@ */ import { createSlice } from '@reduxjs/toolkit'; -/** - * Import the needed reducers - */ import { nodeCollectorReducer } from './node.reducer.js'; import { getCollectorErrors } from './node.utils.js'; @@ -27,6 +24,9 @@ import type { DaVinciNextResponse, DaVinciSuccessResponse, } from './davinci.types.js'; +/** + * Import the needed reducers + */ import type { updateCollectorValues } from './node.reducer.js'; import type { ContinueNode, ErrorNode, FailureNode, StartNode, SuccessNode } from './node.types.js'; diff --git a/packages/davinci-client/src/lib/node.utils.test.ts b/packages/davinci-client/src/lib/node.utils.test.ts index 44a569cdaec..4ad93782038 100644 --- a/packages/davinci-client/src/lib/node.utils.test.ts +++ b/packages/davinci-client/src/lib/node.utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/node.utils.ts b/packages/davinci-client/src/lib/node.utils.ts index a597e02e9b2..d4a599975cd 100644 --- a/packages/davinci-client/src/lib/node.utils.ts +++ b/packages/davinci-client/src/lib/node.utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/src/lib/password-policy.rules.ts b/packages/davinci-client/src/lib/password-policy.rules.ts index 07dfd6f3487..69487e7ee52 100644 --- a/packages/davinci-client/src/lib/password-policy.rules.ts +++ b/packages/davinci-client/src/lib/password-policy.rules.ts @@ -4,7 +4,7 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { Array as Arr, Option, pipe } from 'effect'; +import { Array as Arr, pipe, Result } from 'effect'; import type { Validator } from './client.types.js'; import type { ValidatedPasswordCollector } from './collector.types.js'; @@ -52,7 +52,7 @@ const maxRepeatedCharactersRule: PasswordPolicyRule = (policy, value) => { const maxCount = pipe( countChars(value), (counts) => Array.from(counts.values()), - Arr.reduce(0, (acc, n) => (n > acc ? n : acc)), + (values) => Math.max(0, ...values), ); return maxCount > max ? [`Password cannot repeat any character more than ${max} times`] : []; }; @@ -66,8 +66,8 @@ const minCharactersRule: PasswordPolicyRule = (policy, value) => { let hits = 0; for (const ch of value) if (members.has(ch)) hits += 1; return hits < min - ? Option.some(`Password must contain at least ${min} character(s) from "${charset}"`) - : Option.none(); + ? Result.succeed(`Password must contain at least ${min} character(s) from "${charset}"`) + : Result.fail(undefined); }), ); }; diff --git a/packages/davinci-client/src/lib/wellknown.api.ts b/packages/davinci-client/src/lib/wellknown.api.ts deleted file mode 100644 index 882a66bcc38..00000000000 --- a/packages/davinci-client/src/lib/wellknown.api.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -import { initWellknownQuery } from '@forgerock/sdk-oidc'; -import { createSelector } from '@reduxjs/toolkit'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'; - -import type { WellknownResponse } from '@forgerock/sdk-types'; -import type { - FetchBaseQueryError, - FetchBaseQueryMeta, - QueryReturnValue, -} from '@reduxjs/toolkit/query'; - -/** - * RTK Query API for well-known endpoint discovery. - * - * Uses the `initWellknownQuery` builder pattern from `@forgerock/sdk-oidc`. - * The builder constructs the request and validates the response; - * `fetchBaseQuery` handles the HTTP transport through RTK Query's pipeline. - */ -export const wellknownApi = createApi({ - reducerPath: 'wellknown', - baseQuery: fetchBaseQuery(), - endpoints: (builder) => ({ - configuration: builder.query({ - queryFn: async (url, _api, _extra, baseQuery) => { - const result = await initWellknownQuery(url).applyQuery(async (req) => { - const queryResult = await baseQuery(req); - return queryResult as QueryReturnValue; - }); - return result as QueryReturnValue< - WellknownResponse, - FetchBaseQueryError, - FetchBaseQueryMeta - >; - }, - }), - }), -}); - -/** - * Creates a memoized selector for cached well-known data. - * - * @param wellknownUrl - The well-known endpoint URL used as the cache key - * @returns A memoized selector that extracts the WellknownResponse from state, or undefined if not yet fetched - */ -export function createWellknownSelector(wellknownUrl: string) { - return createSelector( - wellknownApi.endpoints.configuration.select(wellknownUrl), - (result) => result?.data, - ); -} diff --git a/packages/davinci-client/src/types.test-d.ts b/packages/davinci-client/src/types.test-d.ts index bd408e56f19..cd14898dd73 100644 --- a/packages/davinci-client/src/types.test-d.ts +++ b/packages/davinci-client/src/types.test-d.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/davinci-client/tsconfig.json b/packages/davinci-client/tsconfig.json index 141b4ebf5f8..4b134f1186a 100644 --- a/packages/davinci-client/tsconfig.json +++ b/packages/davinci-client/tsconfig.json @@ -23,6 +23,9 @@ { "path": "../sdk-effects/sdk-request-middleware" }, + { + "path": "../sdk-effects/wellknown" + }, { "path": "../sdk-effects/oidc" }, diff --git a/packages/davinci-client/tsconfig.lib.json b/packages/davinci-client/tsconfig.lib.json index 6c7bbdefeff..c0645d65ac5 100644 --- a/packages/davinci-client/tsconfig.lib.json +++ b/packages/davinci-client/tsconfig.lib.json @@ -48,6 +48,9 @@ }, { "path": "../sdk-effects/logger/tsconfig.lib.json" + }, + { + "path": "../sdk-effects/wellknown/tsconfig.lib.json" } ] } diff --git a/packages/davinci-client/vite.config.ts b/packages/davinci-client/vite.config.ts index b921b564ce2..a08bb405979 100644 --- a/packages/davinci-client/vite.config.ts +++ b/packages/davinci-client/vite.config.ts @@ -4,11 +4,17 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ +import { resolve } from 'path'; import { defineConfig } from 'vitest/config'; export default defineConfig({ root: __dirname, cacheDir: '../../node_modules/.vite/packages/davinci-client', + resolve: { + alias: { + '@forgerock/sdk-wellknown': resolve(__dirname, '../sdk-effects/wellknown/src/index.ts'), + }, + }, test: { watch: false, typecheck: { diff --git a/packages/device-client/api-report/device-client.api.md b/packages/device-client/api-report/device-client.api.md index 77ef261064b..797330f24de 100644 --- a/packages/device-client/api-report/device-client.api.md +++ b/packages/device-client/api-report/device-client.api.md @@ -1,527 +1,499 @@ -## API Report File for "@forgerock/device-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import type { LegacyConfigOptions } from '@forgerock/sdk-types'; - -// @public (undocumented) -export type Bluetooth = { - supported: true; -}; - -// @public (undocumented) -export type BoundDeviceQuery = GetBoundDevicesQuery & { - device: Device; -}; - -// @public (undocumented) -export type Browser = { - userAgent: string; -}; - -// @public (undocumented) -export type ConfigOptions = LegacyConfigOptions; - -// @public (undocumented) -export type DeleteDeviceQuery = { - realm?: string; - userId: string; - device: PushDevice; -}; - -// @public (undocumented) -export type DeletedOathDevice = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - sharedSecret: string; - deviceName: string; - lastLogin: number; - counter: number; - checksumDigit: boolean; - truncationOffset: number; - clockDriftSeconds: number; -}; - -// @public (undocumented) -export interface DeletedPushDevice { - // (undocumented) - communicationId: string; - // (undocumented) - communicationType: string; - // (undocumented) - createdDate: number; - // (undocumented) - deviceId: string; - // (undocumented) - deviceMechanismUID: string; - // (undocumented) - deviceName: string; - // (undocumented) - deviceType: string; - // (undocumented) - _id: string; - // (undocumented) - issuer: string; - // (undocumented) - lastAccessDate: number; - // (undocumented) - recoveryCodes: string[]; - // (undocumented) - _rev: string; - // (undocumented) - sharedSecret: string; - // (undocumented) - uuid: string; -} - -// @public (undocumented) -export type DeleteOathQuery = { - realm?: string; - userId: string; - uuid: string; -}; - -// @public (undocumented) -export type Device = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - deviceId: string; - deviceName: string; - uuid: string; - recoveryCodes: string[]; - key: { - kty: string; - kid: string; - use: string; - alg: string; - n: string; - e: string; - }; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type DeviceClient = ReturnType; - -// @public -export const deviceClient: (config: LegacyConfigOptions) => { - oath: { - get: (query: RetrieveOathQuery) => Promise< - | OathDevice[] - | { - error: unknown; - } - >; - delete: ( - query: RetrieveOathQuery & { - device: OathDevice; - }, - ) => Promise; - }; - push: { - get: (query: PushDeviceQuery) => Promise< - | PushDevice[] - | { - error: unknown; - } - >; - delete: (query: DeleteDeviceQuery) => Promise; - }; - webAuthn: { - get: (query: WebAuthnQuery) => Promise< - | WebAuthnDevice[] - | { - error: unknown; - } - >; - update: ( - query: WebAuthnQuery & { - device: WebAuthnDevice; - }, - ) => Promise< - | UpdatedWebAuthnDevice - | { - error: unknown; - } - >; - delete: ( - query: WebAuthnQuery & { - device: WebAuthnDevice | UpdatedWebAuthnDevice; - }, - ) => Promise; - }; - bound: { - get: (query: GetBoundDevicesQuery) => Promise< - | Device[] - | { - error: unknown; - } - >; - delete: (query: BoundDeviceQuery) => Promise; - update: (query: BoundDeviceQuery) => Promise< - | Device - | { - error: unknown; - } - >; - }; - profile: { - get: (query: GetProfileDevices) => Promise< - | ProfileDevice[] - | { - error: unknown; - } - >; - update: (query: ProfileDevicesQuery) => Promise< - | ProfileDevice - | { - error: unknown; - } - >; - delete: (query: ProfileDevicesQuery) => Promise; - }; -}; - -// @public (undocumented) -export type DeviceInfo = { - _id: string; - _rev: string; - identifier: string; - metadata: { - platform: { - platform: string; - version: number; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: number; - }; - hardware: { - hardware: string; - manufacturer: string; - storage: number; - memory: number; - cpu: number; - display: { - width: number; - height: number; - orientation: number; - }; - camera: { - numberOfCameras: number; - }; - }; - browser: { - userAgent: string; - }; - bluetooth: { - supported: boolean; - }; - network: { - connected: boolean; - }; - telephony: { - networkCountryIso: string; - carrierName: string; - }; - }; - lastSelectedDate: number; - alias: string; - recoveryCodes: string[]; -}; - -// @public (undocumented) -export type DeviceInfoResponse = { - result: DeviceInfo[]; - resultCount: number; - pagedResultsCookie: null; - totalPagedResultsPolicy: string; - totalPagedResults: -1; - remainingPagedResults: -1; -}; - -// @public (undocumented) -export type DeviceMetadata = { - platform: string; - version: 34; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: 0; -}; - -// @public (undocumented) -export type DeviceProfile = { - _id: string; - _rev: string; - identifier: string; - metadata: Metadata; - lastSelectedDate: number; - alias: 'Test3'; - recoveryCodes: []; -}; - -// @public (undocumented) -export type DeviceResponse = { - result: Device[]; - resultCount: number; - pagedResultsCookie: null; - totalPagedResultsPolicy: string; - totalPagedResults: -1; - remainingPagedResults: -1; -}; - -// @public (undocumented) -export type GetBoundDevicesQuery = { - userId: string; - realm?: string; -}; - -// @public (undocumented) -export interface GetProfileDevices { - // (undocumented) - realm?: string; - // (undocumented) - userId: string; -} - -// @public (undocumented) -export type Hardware = { - hardware: string; - manufacturer: string; - storage: 5939; - memory: 2981; - cpu: 4; - display: { - width: 1440; - height: 2678; - orientation: 1; - }; - camera: { - numberOfCameras: 2; - }; -}; - -// @public (undocumented) -export type Metadata = { - platform: DeviceMetadata; - hardware: Hardware; - browser: Browser; - bluetooth: Bluetooth; - network: Network; - telephony: Telephony; -}; - -// @public (undocumented) -export type Network = { - connected: true; -}; - -// @public (undocumented) -export type OathDevice = { - _id: string; - deviceManagementStatus: boolean; - deviceName: string; - uuid: string; - createdDate: number; - lastAccessDate: number; - _rev: string; -}; - -// @public (undocumented) -export type OathResponse = { - pagedResultsCookie: string | null; - remainingPagedResults: number; - resultCount: number; - totalPagedResults: number; - totalPagedResultsPolicy: string; - result: OathDevice[]; -}; - -// @public (undocumented) -export type ProfileDevice = { - _id: string; - _rev: string; - identifier: string; - metadata: { - platform: { - platform: string; - version: number; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: number; - }; - hardware: { - hardware: string; - manufacturer: string; - storage: number; - memory: number; - cpu: number; - display: { - width: number; - height: number; - orientation: number; - }; - camera: { - numberOfCameras: number; - }; - }; - browser: { - userAgent: string; - }; - bluetooth: { - supported: boolean; - }; - network: { - connected: boolean; - }; - telephony: { - networkCountryIso: string; - carrierName: string; - }; - }; - lastSelectedDate: number; - alias: string; - recoveryCodes: string[]; -}; - -// @public (undocumented) -export interface ProfileDevicesQuery extends GetProfileDevices { - // (undocumented) - device: ProfileDevice; -} - -// @public (undocumented) -export type PushDevice = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - deviceName: string; - uuid: string; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type PushDeviceBody = { - id: string; - deviceName: string; - uuid: string; - createdDate: string; - lastAccessDate: string; -}; - -// @public (undocumented) -export type PushDeviceQuery = { - realm?: string; - userId: string; -}; - -// @public (undocumented) -export type RetrieveOathQuery = { - realm?: string; - userId: string; -}; - -// @public (undocumented) -export type Telephony = { - networkCountryIso: 'us'; - carrierName: 'T-Mobile'; -}; - -// @public (undocumented) -export type UpdatedWebAuthnDevice = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - credentialId: string; - algorithm: string; - deviceName: string; - signCount: number; - key: { - kty: string; - x: string; - y: string; - crv: string; - }; -}; - -// @public (undocumented) -export type WebAuthnBody = { - id: string; - deviceName: string; - uuid: string; - credentialId: string; - createdDate: number; - lastAccessDate: number; -}; - -// @public (undocumented) -export type WebAuthnCredential = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - credentialId: string; - algorithm: string; - deviceName: string; - key: { - kty: string; - x: string; - y: string; - crv: string; - }; -}; - -// @public (undocumented) -export type WebAuthnDevice = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - credentialId: string; - deviceName: string; - uuid: string; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type WebAuthnQuery = { - realm?: string; - userId: string; -}; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/device-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import type { LegacyConfigOptions } from '@forgerock/sdk-types'; + +// @public (undocumented) +export type Bluetooth = { + supported: true; +}; + +// @public (undocumented) +export type BoundDeviceQuery = GetBoundDevicesQuery & { + device: Device; +}; + +// @public (undocumented) +export type Browser = { + userAgent: string; +}; + +// @public (undocumented) +export type ConfigOptions = LegacyConfigOptions; + +// @public (undocumented) +export type DeleteDeviceQuery = { + realm?: string; + userId: string; + device: PushDevice; +}; + +// @public (undocumented) +export type DeletedOathDevice = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + sharedSecret: string; + deviceName: string; + lastLogin: number; + counter: number; + checksumDigit: boolean; + truncationOffset: number; + clockDriftSeconds: number; +}; + +// @public (undocumented) +export interface DeletedPushDevice { + // (undocumented) + communicationId: string; + // (undocumented) + communicationType: string; + // (undocumented) + createdDate: number; + // (undocumented) + deviceId: string; + // (undocumented) + deviceMechanismUID: string; + // (undocumented) + deviceName: string; + // (undocumented) + deviceType: string; + // (undocumented) + _id: string; + // (undocumented) + issuer: string; + // (undocumented) + lastAccessDate: number; + // (undocumented) + recoveryCodes: string[]; + // (undocumented) + _rev: string; + // (undocumented) + sharedSecret: string; + // (undocumented) + uuid: string; +} + +// @public (undocumented) +export type DeleteOathQuery = { + realm?: string; + userId: string; + uuid: string; +}; + +// @public (undocumented) +export type Device = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + deviceId: string; + deviceName: string; + uuid: string; + recoveryCodes: string[]; + key: { + kty: string; + kid: string; + use: string; + alg: string; + n: string; + e: string; + }; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type DeviceClient = ReturnType; + +// @public +export const deviceClient: (config: LegacyConfigOptions) => { + oath: { + get: (query: RetrieveOathQuery) => Promise; + delete: (query: RetrieveOathQuery & { + device: OathDevice; + }) => Promise; + }; + push: { + get: (query: PushDeviceQuery) => Promise; + delete: (query: DeleteDeviceQuery) => Promise; + }; + webAuthn: { + get: (query: WebAuthnQuery) => Promise; + update: (query: WebAuthnQuery & { + device: WebAuthnDevice; + }) => Promise; + delete: (query: WebAuthnQuery & { + device: WebAuthnDevice | UpdatedWebAuthnDevice; + }) => Promise; + }; + bound: { + get: (query: GetBoundDevicesQuery) => Promise; + delete: (query: BoundDeviceQuery) => Promise; + update: (query: BoundDeviceQuery) => Promise; + }; + profile: { + get: (query: GetProfileDevices) => Promise; + update: (query: ProfileDevicesQuery) => Promise; + delete: (query: ProfileDevicesQuery) => Promise; + }; +}; + +// @public (undocumented) +export type DeviceInfo = { + _id: string; + _rev: string; + identifier: string; + metadata: { + platform: { + platform: string; + version: number; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: number; + }; + hardware: { + hardware: string; + manufacturer: string; + storage: number; + memory: number; + cpu: number; + display: { + width: number; + height: number; + orientation: number; + }; + camera: { + numberOfCameras: number; + }; + }; + browser: { + userAgent: string; + }; + bluetooth: { + supported: boolean; + }; + network: { + connected: boolean; + }; + telephony: { + networkCountryIso: string; + carrierName: string; + }; + }; + lastSelectedDate: number; + alias: string; + recoveryCodes: string[]; +}; + +// @public (undocumented) +export type DeviceInfoResponse = { + result: DeviceInfo[]; + resultCount: number; + pagedResultsCookie: null; + totalPagedResultsPolicy: string; + totalPagedResults: -1; + remainingPagedResults: -1; +}; + +// @public (undocumented) +export type DeviceMetadata = { + platform: string; + version: 34; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: 0; +}; + +// @public (undocumented) +export type DeviceProfile = { + _id: string; + _rev: string; + identifier: string; + metadata: Metadata; + lastSelectedDate: number; + alias: 'Test3'; + recoveryCodes: []; +}; + +// @public (undocumented) +export type DeviceResponse = { + result: Device[]; + resultCount: number; + pagedResultsCookie: null; + totalPagedResultsPolicy: string; + totalPagedResults: -1; + remainingPagedResults: -1; +}; + +// @public (undocumented) +export type GetBoundDevicesQuery = { + userId: string; + realm?: string; +}; + +// @public (undocumented) +export interface GetProfileDevices { + // (undocumented) + realm?: string; + // (undocumented) + userId: string; +} + +// @public (undocumented) +export type Hardware = { + hardware: string; + manufacturer: string; + storage: 5939; + memory: 2981; + cpu: 4; + display: { + width: 1440; + height: 2678; + orientation: 1; + }; + camera: { + numberOfCameras: 2; + }; +}; + +// @public (undocumented) +export type Metadata = { + platform: DeviceMetadata; + hardware: Hardware; + browser: Browser; + bluetooth: Bluetooth; + network: Network; + telephony: Telephony; +}; + +// @public (undocumented) +export type Network = { + connected: true; +}; + +// @public (undocumented) +export type OathDevice = { + _id: string; + deviceManagementStatus: boolean; + deviceName: string; + uuid: string; + createdDate: number; + lastAccessDate: number; + _rev: string; +}; + +// @public (undocumented) +export type OathResponse = { + pagedResultsCookie: string | null; + remainingPagedResults: number; + resultCount: number; + totalPagedResults: number; + totalPagedResultsPolicy: string; + result: OathDevice[]; +}; + +// @public (undocumented) +export type ProfileDevice = { + _id: string; + _rev: string; + identifier: string; + metadata: { + platform: { + platform: string; + version: number; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: number; + }; + hardware: { + hardware: string; + manufacturer: string; + storage: number; + memory: number; + cpu: number; + display: { + width: number; + height: number; + orientation: number; + }; + camera: { + numberOfCameras: number; + }; + }; + browser: { + userAgent: string; + }; + bluetooth: { + supported: boolean; + }; + network: { + connected: boolean; + }; + telephony: { + networkCountryIso: string; + carrierName: string; + }; + }; + lastSelectedDate: number; + alias: string; + recoveryCodes: string[]; +}; + +// @public (undocumented) +export interface ProfileDevicesQuery extends GetProfileDevices { + // (undocumented) + device: ProfileDevice; +} + +// @public (undocumented) +export type PushDevice = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + deviceName: string; + uuid: string; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type PushDeviceBody = { + id: string; + deviceName: string; + uuid: string; + createdDate: string; + lastAccessDate: string; +}; + +// @public (undocumented) +export type PushDeviceQuery = { + realm?: string; + userId: string; +}; + +// @public (undocumented) +export type RetrieveOathQuery = { + realm?: string; + userId: string; +}; + +// @public (undocumented) +export type Telephony = { + networkCountryIso: 'us'; + carrierName: 'T-Mobile'; +}; + +// @public (undocumented) +export type UpdatedWebAuthnDevice = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + credentialId: string; + algorithm: string; + deviceName: string; + signCount: number; + key: { + kty: string; + x: string; + y: string; + crv: string; + }; +}; + +// @public (undocumented) +export type WebAuthnBody = { + id: string; + deviceName: string; + uuid: string; + credentialId: string; + createdDate: number; + lastAccessDate: number; +}; + +// @public (undocumented) +export type WebAuthnCredential = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + credentialId: string; + algorithm: string; + deviceName: string; + key: { + kty: string; + x: string; + y: string; + crv: string; + }; +}; + +// @public (undocumented) +export type WebAuthnDevice = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + credentialId: string; + deviceName: string; + uuid: string; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type WebAuthnQuery = { + realm?: string; + userId: string; +}; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/device-client/api-report/device-client.types.api.md b/packages/device-client/api-report/device-client.types.api.md index 77ef261064b..797330f24de 100644 --- a/packages/device-client/api-report/device-client.types.api.md +++ b/packages/device-client/api-report/device-client.types.api.md @@ -1,527 +1,499 @@ -## API Report File for "@forgerock/device-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import type { LegacyConfigOptions } from '@forgerock/sdk-types'; - -// @public (undocumented) -export type Bluetooth = { - supported: true; -}; - -// @public (undocumented) -export type BoundDeviceQuery = GetBoundDevicesQuery & { - device: Device; -}; - -// @public (undocumented) -export type Browser = { - userAgent: string; -}; - -// @public (undocumented) -export type ConfigOptions = LegacyConfigOptions; - -// @public (undocumented) -export type DeleteDeviceQuery = { - realm?: string; - userId: string; - device: PushDevice; -}; - -// @public (undocumented) -export type DeletedOathDevice = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - sharedSecret: string; - deviceName: string; - lastLogin: number; - counter: number; - checksumDigit: boolean; - truncationOffset: number; - clockDriftSeconds: number; -}; - -// @public (undocumented) -export interface DeletedPushDevice { - // (undocumented) - communicationId: string; - // (undocumented) - communicationType: string; - // (undocumented) - createdDate: number; - // (undocumented) - deviceId: string; - // (undocumented) - deviceMechanismUID: string; - // (undocumented) - deviceName: string; - // (undocumented) - deviceType: string; - // (undocumented) - _id: string; - // (undocumented) - issuer: string; - // (undocumented) - lastAccessDate: number; - // (undocumented) - recoveryCodes: string[]; - // (undocumented) - _rev: string; - // (undocumented) - sharedSecret: string; - // (undocumented) - uuid: string; -} - -// @public (undocumented) -export type DeleteOathQuery = { - realm?: string; - userId: string; - uuid: string; -}; - -// @public (undocumented) -export type Device = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - deviceId: string; - deviceName: string; - uuid: string; - recoveryCodes: string[]; - key: { - kty: string; - kid: string; - use: string; - alg: string; - n: string; - e: string; - }; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type DeviceClient = ReturnType; - -// @public -export const deviceClient: (config: LegacyConfigOptions) => { - oath: { - get: (query: RetrieveOathQuery) => Promise< - | OathDevice[] - | { - error: unknown; - } - >; - delete: ( - query: RetrieveOathQuery & { - device: OathDevice; - }, - ) => Promise; - }; - push: { - get: (query: PushDeviceQuery) => Promise< - | PushDevice[] - | { - error: unknown; - } - >; - delete: (query: DeleteDeviceQuery) => Promise; - }; - webAuthn: { - get: (query: WebAuthnQuery) => Promise< - | WebAuthnDevice[] - | { - error: unknown; - } - >; - update: ( - query: WebAuthnQuery & { - device: WebAuthnDevice; - }, - ) => Promise< - | UpdatedWebAuthnDevice - | { - error: unknown; - } - >; - delete: ( - query: WebAuthnQuery & { - device: WebAuthnDevice | UpdatedWebAuthnDevice; - }, - ) => Promise; - }; - bound: { - get: (query: GetBoundDevicesQuery) => Promise< - | Device[] - | { - error: unknown; - } - >; - delete: (query: BoundDeviceQuery) => Promise; - update: (query: BoundDeviceQuery) => Promise< - | Device - | { - error: unknown; - } - >; - }; - profile: { - get: (query: GetProfileDevices) => Promise< - | ProfileDevice[] - | { - error: unknown; - } - >; - update: (query: ProfileDevicesQuery) => Promise< - | ProfileDevice - | { - error: unknown; - } - >; - delete: (query: ProfileDevicesQuery) => Promise; - }; -}; - -// @public (undocumented) -export type DeviceInfo = { - _id: string; - _rev: string; - identifier: string; - metadata: { - platform: { - platform: string; - version: number; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: number; - }; - hardware: { - hardware: string; - manufacturer: string; - storage: number; - memory: number; - cpu: number; - display: { - width: number; - height: number; - orientation: number; - }; - camera: { - numberOfCameras: number; - }; - }; - browser: { - userAgent: string; - }; - bluetooth: { - supported: boolean; - }; - network: { - connected: boolean; - }; - telephony: { - networkCountryIso: string; - carrierName: string; - }; - }; - lastSelectedDate: number; - alias: string; - recoveryCodes: string[]; -}; - -// @public (undocumented) -export type DeviceInfoResponse = { - result: DeviceInfo[]; - resultCount: number; - pagedResultsCookie: null; - totalPagedResultsPolicy: string; - totalPagedResults: -1; - remainingPagedResults: -1; -}; - -// @public (undocumented) -export type DeviceMetadata = { - platform: string; - version: 34; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: 0; -}; - -// @public (undocumented) -export type DeviceProfile = { - _id: string; - _rev: string; - identifier: string; - metadata: Metadata; - lastSelectedDate: number; - alias: 'Test3'; - recoveryCodes: []; -}; - -// @public (undocumented) -export type DeviceResponse = { - result: Device[]; - resultCount: number; - pagedResultsCookie: null; - totalPagedResultsPolicy: string; - totalPagedResults: -1; - remainingPagedResults: -1; -}; - -// @public (undocumented) -export type GetBoundDevicesQuery = { - userId: string; - realm?: string; -}; - -// @public (undocumented) -export interface GetProfileDevices { - // (undocumented) - realm?: string; - // (undocumented) - userId: string; -} - -// @public (undocumented) -export type Hardware = { - hardware: string; - manufacturer: string; - storage: 5939; - memory: 2981; - cpu: 4; - display: { - width: 1440; - height: 2678; - orientation: 1; - }; - camera: { - numberOfCameras: 2; - }; -}; - -// @public (undocumented) -export type Metadata = { - platform: DeviceMetadata; - hardware: Hardware; - browser: Browser; - bluetooth: Bluetooth; - network: Network; - telephony: Telephony; -}; - -// @public (undocumented) -export type Network = { - connected: true; -}; - -// @public (undocumented) -export type OathDevice = { - _id: string; - deviceManagementStatus: boolean; - deviceName: string; - uuid: string; - createdDate: number; - lastAccessDate: number; - _rev: string; -}; - -// @public (undocumented) -export type OathResponse = { - pagedResultsCookie: string | null; - remainingPagedResults: number; - resultCount: number; - totalPagedResults: number; - totalPagedResultsPolicy: string; - result: OathDevice[]; -}; - -// @public (undocumented) -export type ProfileDevice = { - _id: string; - _rev: string; - identifier: string; - metadata: { - platform: { - platform: string; - version: number; - device: string; - deviceName: string; - model: string; - brand: string; - locale: string; - timeZone: string; - jailBreakScore: number; - }; - hardware: { - hardware: string; - manufacturer: string; - storage: number; - memory: number; - cpu: number; - display: { - width: number; - height: number; - orientation: number; - }; - camera: { - numberOfCameras: number; - }; - }; - browser: { - userAgent: string; - }; - bluetooth: { - supported: boolean; - }; - network: { - connected: boolean; - }; - telephony: { - networkCountryIso: string; - carrierName: string; - }; - }; - lastSelectedDate: number; - alias: string; - recoveryCodes: string[]; -}; - -// @public (undocumented) -export interface ProfileDevicesQuery extends GetProfileDevices { - // (undocumented) - device: ProfileDevice; -} - -// @public (undocumented) -export type PushDevice = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - deviceName: string; - uuid: string; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type PushDeviceBody = { - id: string; - deviceName: string; - uuid: string; - createdDate: string; - lastAccessDate: string; -}; - -// @public (undocumented) -export type PushDeviceQuery = { - realm?: string; - userId: string; -}; - -// @public (undocumented) -export type RetrieveOathQuery = { - realm?: string; - userId: string; -}; - -// @public (undocumented) -export type Telephony = { - networkCountryIso: 'us'; - carrierName: 'T-Mobile'; -}; - -// @public (undocumented) -export type UpdatedWebAuthnDevice = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - credentialId: string; - algorithm: string; - deviceName: string; - signCount: number; - key: { - kty: string; - x: string; - y: string; - crv: string; - }; -}; - -// @public (undocumented) -export type WebAuthnBody = { - id: string; - deviceName: string; - uuid: string; - credentialId: string; - createdDate: number; - lastAccessDate: number; -}; - -// @public (undocumented) -export type WebAuthnCredential = { - _id: string; - _rev: string; - uuid: string; - recoveryCodes: string[]; - createdDate: number; - lastAccessDate: number; - credentialId: string; - algorithm: string; - deviceName: string; - key: { - kty: string; - x: string; - y: string; - crv: string; - }; -}; - -// @public (undocumented) -export type WebAuthnDevice = { - _id: string; - _rev: string; - createdDate: number; - lastAccessDate: number; - credentialId: string; - deviceName: string; - uuid: string; - deviceManagementStatus: boolean; -}; - -// @public (undocumented) -export type WebAuthnQuery = { - realm?: string; - userId: string; -}; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/device-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import type { LegacyConfigOptions } from '@forgerock/sdk-types'; + +// @public (undocumented) +export type Bluetooth = { + supported: true; +}; + +// @public (undocumented) +export type BoundDeviceQuery = GetBoundDevicesQuery & { + device: Device; +}; + +// @public (undocumented) +export type Browser = { + userAgent: string; +}; + +// @public (undocumented) +export type ConfigOptions = LegacyConfigOptions; + +// @public (undocumented) +export type DeleteDeviceQuery = { + realm?: string; + userId: string; + device: PushDevice; +}; + +// @public (undocumented) +export type DeletedOathDevice = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + sharedSecret: string; + deviceName: string; + lastLogin: number; + counter: number; + checksumDigit: boolean; + truncationOffset: number; + clockDriftSeconds: number; +}; + +// @public (undocumented) +export interface DeletedPushDevice { + // (undocumented) + communicationId: string; + // (undocumented) + communicationType: string; + // (undocumented) + createdDate: number; + // (undocumented) + deviceId: string; + // (undocumented) + deviceMechanismUID: string; + // (undocumented) + deviceName: string; + // (undocumented) + deviceType: string; + // (undocumented) + _id: string; + // (undocumented) + issuer: string; + // (undocumented) + lastAccessDate: number; + // (undocumented) + recoveryCodes: string[]; + // (undocumented) + _rev: string; + // (undocumented) + sharedSecret: string; + // (undocumented) + uuid: string; +} + +// @public (undocumented) +export type DeleteOathQuery = { + realm?: string; + userId: string; + uuid: string; +}; + +// @public (undocumented) +export type Device = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + deviceId: string; + deviceName: string; + uuid: string; + recoveryCodes: string[]; + key: { + kty: string; + kid: string; + use: string; + alg: string; + n: string; + e: string; + }; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type DeviceClient = ReturnType; + +// @public +export const deviceClient: (config: LegacyConfigOptions) => { + oath: { + get: (query: RetrieveOathQuery) => Promise; + delete: (query: RetrieveOathQuery & { + device: OathDevice; + }) => Promise; + }; + push: { + get: (query: PushDeviceQuery) => Promise; + delete: (query: DeleteDeviceQuery) => Promise; + }; + webAuthn: { + get: (query: WebAuthnQuery) => Promise; + update: (query: WebAuthnQuery & { + device: WebAuthnDevice; + }) => Promise; + delete: (query: WebAuthnQuery & { + device: WebAuthnDevice | UpdatedWebAuthnDevice; + }) => Promise; + }; + bound: { + get: (query: GetBoundDevicesQuery) => Promise; + delete: (query: BoundDeviceQuery) => Promise; + update: (query: BoundDeviceQuery) => Promise; + }; + profile: { + get: (query: GetProfileDevices) => Promise; + update: (query: ProfileDevicesQuery) => Promise; + delete: (query: ProfileDevicesQuery) => Promise; + }; +}; + +// @public (undocumented) +export type DeviceInfo = { + _id: string; + _rev: string; + identifier: string; + metadata: { + platform: { + platform: string; + version: number; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: number; + }; + hardware: { + hardware: string; + manufacturer: string; + storage: number; + memory: number; + cpu: number; + display: { + width: number; + height: number; + orientation: number; + }; + camera: { + numberOfCameras: number; + }; + }; + browser: { + userAgent: string; + }; + bluetooth: { + supported: boolean; + }; + network: { + connected: boolean; + }; + telephony: { + networkCountryIso: string; + carrierName: string; + }; + }; + lastSelectedDate: number; + alias: string; + recoveryCodes: string[]; +}; + +// @public (undocumented) +export type DeviceInfoResponse = { + result: DeviceInfo[]; + resultCount: number; + pagedResultsCookie: null; + totalPagedResultsPolicy: string; + totalPagedResults: -1; + remainingPagedResults: -1; +}; + +// @public (undocumented) +export type DeviceMetadata = { + platform: string; + version: 34; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: 0; +}; + +// @public (undocumented) +export type DeviceProfile = { + _id: string; + _rev: string; + identifier: string; + metadata: Metadata; + lastSelectedDate: number; + alias: 'Test3'; + recoveryCodes: []; +}; + +// @public (undocumented) +export type DeviceResponse = { + result: Device[]; + resultCount: number; + pagedResultsCookie: null; + totalPagedResultsPolicy: string; + totalPagedResults: -1; + remainingPagedResults: -1; +}; + +// @public (undocumented) +export type GetBoundDevicesQuery = { + userId: string; + realm?: string; +}; + +// @public (undocumented) +export interface GetProfileDevices { + // (undocumented) + realm?: string; + // (undocumented) + userId: string; +} + +// @public (undocumented) +export type Hardware = { + hardware: string; + manufacturer: string; + storage: 5939; + memory: 2981; + cpu: 4; + display: { + width: 1440; + height: 2678; + orientation: 1; + }; + camera: { + numberOfCameras: 2; + }; +}; + +// @public (undocumented) +export type Metadata = { + platform: DeviceMetadata; + hardware: Hardware; + browser: Browser; + bluetooth: Bluetooth; + network: Network; + telephony: Telephony; +}; + +// @public (undocumented) +export type Network = { + connected: true; +}; + +// @public (undocumented) +export type OathDevice = { + _id: string; + deviceManagementStatus: boolean; + deviceName: string; + uuid: string; + createdDate: number; + lastAccessDate: number; + _rev: string; +}; + +// @public (undocumented) +export type OathResponse = { + pagedResultsCookie: string | null; + remainingPagedResults: number; + resultCount: number; + totalPagedResults: number; + totalPagedResultsPolicy: string; + result: OathDevice[]; +}; + +// @public (undocumented) +export type ProfileDevice = { + _id: string; + _rev: string; + identifier: string; + metadata: { + platform: { + platform: string; + version: number; + device: string; + deviceName: string; + model: string; + brand: string; + locale: string; + timeZone: string; + jailBreakScore: number; + }; + hardware: { + hardware: string; + manufacturer: string; + storage: number; + memory: number; + cpu: number; + display: { + width: number; + height: number; + orientation: number; + }; + camera: { + numberOfCameras: number; + }; + }; + browser: { + userAgent: string; + }; + bluetooth: { + supported: boolean; + }; + network: { + connected: boolean; + }; + telephony: { + networkCountryIso: string; + carrierName: string; + }; + }; + lastSelectedDate: number; + alias: string; + recoveryCodes: string[]; +}; + +// @public (undocumented) +export interface ProfileDevicesQuery extends GetProfileDevices { + // (undocumented) + device: ProfileDevice; +} + +// @public (undocumented) +export type PushDevice = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + deviceName: string; + uuid: string; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type PushDeviceBody = { + id: string; + deviceName: string; + uuid: string; + createdDate: string; + lastAccessDate: string; +}; + +// @public (undocumented) +export type PushDeviceQuery = { + realm?: string; + userId: string; +}; + +// @public (undocumented) +export type RetrieveOathQuery = { + realm?: string; + userId: string; +}; + +// @public (undocumented) +export type Telephony = { + networkCountryIso: 'us'; + carrierName: 'T-Mobile'; +}; + +// @public (undocumented) +export type UpdatedWebAuthnDevice = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + credentialId: string; + algorithm: string; + deviceName: string; + signCount: number; + key: { + kty: string; + x: string; + y: string; + crv: string; + }; +}; + +// @public (undocumented) +export type WebAuthnBody = { + id: string; + deviceName: string; + uuid: string; + credentialId: string; + createdDate: number; + lastAccessDate: number; +}; + +// @public (undocumented) +export type WebAuthnCredential = { + _id: string; + _rev: string; + uuid: string; + recoveryCodes: string[]; + createdDate: number; + lastAccessDate: number; + credentialId: string; + algorithm: string; + deviceName: string; + key: { + kty: string; + x: string; + y: string; + crv: string; + }; +}; + +// @public (undocumented) +export type WebAuthnDevice = { + _id: string; + _rev: string; + createdDate: number; + lastAccessDate: number; + credentialId: string; + deviceName: string; + uuid: string; + deviceManagementStatus: boolean; +}; + +// @public (undocumented) +export type WebAuthnQuery = { + realm?: string; + userId: string; +}; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/journey-client/api-report/journey-client._utils.api.md b/packages/journey-client/api-report/journey-client._utils.api.md index d5030be69c6..d10450dfee5 100644 --- a/packages/journey-client/api-report/journey-client._utils.api.md +++ b/packages/journey-client/api-report/journey-client._utils.api.md @@ -6,7 +6,7 @@ import type { AuthResponse } from '@forgerock/sdk-types'; import type { Callback } from '@forgerock/sdk-types'; import type { CallbackType } from '@forgerock/sdk-types'; -import type { Step } from '@forgerock/sdk-types'; +import { Step } from '@forgerock/sdk-types'; import type { StepType } from '@forgerock/sdk-types'; // @public diff --git a/packages/journey-client/api-report/journey-client.api.md b/packages/journey-client/api-report/journey-client.api.md index 67d98aac9c1..24db4a6b916 100644 --- a/packages/journey-client/api-report/journey-client.api.md +++ b/packages/journey-client/api-report/journey-client.api.md @@ -1,507 +1,539 @@ -## API Report File for "@forgerock/journey-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { AuthResponse } from '@forgerock/sdk-types'; -import { Callback } from '@forgerock/sdk-types'; -import { CallbackType } from '@forgerock/sdk-types'; -import { callbackType } from '@forgerock/sdk-types'; -import { createWellknownError } from '@forgerock/sdk-utilities'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import { FailedPolicyRequirement } from '@forgerock/sdk-types'; -import { FailureDetail } from '@forgerock/sdk-types'; -import { GenericError } from '@forgerock/sdk-types'; -import { isValidWellknownUrl } from '@forgerock/sdk-utilities'; -import { JourneyClientConfig } from '@forgerock/sdk-types'; -import { JourneyServerConfig } from '@forgerock/sdk-types'; -import { LegacyServerConfig } from '@forgerock/sdk-types'; -import { LogLevel } from '@forgerock/sdk-logger'; -import { makeJourneyConfig } from '@forgerock/sdk-utilities'; -import { NameValue } from '@forgerock/sdk-types'; -import { PolicyKey } from '@forgerock/sdk-types'; -import { PolicyParams } from '@forgerock/sdk-types'; -import { PolicyRequirement } from '@forgerock/sdk-types'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { Step } from '@forgerock/sdk-types'; -import { StepDetail } from '@forgerock/sdk-types'; -import { StepType } from '@forgerock/sdk-types'; -import { WellknownResponse } from '@forgerock/sdk-types'; - -export { ActionTypes }; - -// @public -export class AttributeInputCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getName(): string; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setValidateOnly(value: boolean): void; - setValue(value: T): void; -} - -export { AuthResponse }; - -// @public -export class BaseCallback { - constructor(payload: Callback); - getInputValue(selector?: number | string): unknown; - getOutputByName(name: string, defaultValue: T): T; - getOutputValue(selector?: number | string): unknown; - getType(): CallbackType; - // (undocumented) - payload: Callback; - setInputValue(value: unknown, selector?: number | string | RegExp): void; -} - -export { Callback }; - -// @public (undocumented) -export type CallbackFactory = (callback: Callback) => BaseCallback; - -export { CallbackType }; - -export { callbackType }; - -// @public -export class ChoiceCallback extends BaseCallback { - constructor(payload: Callback); - getChoices(): string[]; - getDefaultChoice(): number; - getPrompt(): string; - // (undocumented) - payload: Callback; - setChoiceIndex(index: number): void; - setChoiceValue(value: string): void; -} - -// @public -export class ConfirmationCallback extends BaseCallback { - constructor(payload: Callback); - getDefaultOption(): number; - getMessageType(): number; - getOptions(): string[]; - getOptionType(): number; - getPrompt(): string; - // (undocumented) - payload: Callback; - setOptionIndex(index: number): void; - setOptionValue(value: string): void; -} - -// @public (undocumented) -export function createCallback(callback: Callback): BaseCallback; - -export { createWellknownError }; - -export { CustomLogger }; - -// @public -export class DeviceProfileCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - isLocationRequired(): boolean; - isMetadataRequired(): boolean; - // (undocumented) - payload: Callback; - setProfile(profile: DeviceProfileData): void; -} - -// @public (undocumented) -export interface DeviceProfileData { - // (undocumented) - identifier: string; - // (undocumented) - location?: Geolocation_2 | Record; - // (undocumented) - metadata?: { - hardware: { - display: { - [key: string]: string | number | null; - }; - [key: string]: any; - }; - browser: { - [key: string]: string | number | null; - }; - platform: { - [key: string]: string | number | null; - }; - }; -} - -export { FailedPolicyRequirement }; - -export { FailureDetail }; - -export { GenericError }; - -// @public (undocumented) -interface Geolocation_2 { - // (undocumented) - latitude: number; - // (undocumented) - longitude: number; -} -export { Geolocation_2 as Geolocation }; - -// @public -export class HiddenValueCallback extends BaseCallback { - constructor(payload: Callback); - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export interface IdPValue { - // (undocumented) - provider: string; - // (undocumented) - uiConfig: { - [key: string]: string; - }; -} - -// @internal -export interface InternalJourneyClientConfig { - // (undocumented) - error?: GenericError; - // (undocumented) - serverConfig: ResolvedServerConfig; -} - -export { isValidWellknownUrl }; - -// @public -export function journey(input: { - config: JourneyClientConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; -}): Promise; - -// @public -export interface JourneyClient { - // (undocumented) - next: (step: JourneyStep, options?: NextOptions) => Promise; - // (undocumented) - redirect: (step: JourneyStep) => Promise; - // (undocumented) - resume: (url: string, options?: ResumeOptions) => Promise; - // (undocumented) - start: (options?: StartParam) => Promise; - // (undocumented) - subscribe: (listener: () => void) => () => void; - // (undocumented) - terminate: (options?: { query?: Record }) => Promise; -} - -export { JourneyClientConfig }; - -// @public (undocumented) -export type JourneyLoginFailure = AuthResponse & { - type: StepType.LoginFailure; - payload: Step; - getCode: () => number; - getDetail: () => FailureDetail | undefined; - getMessage: () => string | undefined; - getProcessedMessage: (messageCreator?: MessageCreator) => ProcessedPropertyError[]; - getReason: () => string | undefined; -}; - -// @public (undocumented) -export type JourneyLoginSuccess = AuthResponse & { - type: StepType.LoginSuccess; - payload: Step; - getRealm: () => string | undefined; - getSessionToken: () => string | undefined; - getSuccessUrl: () => string | undefined; -}; - -// @public (undocumented) -export type JourneyResult = JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | GenericError; - -export { JourneyServerConfig }; - -// @public (undocumented) -export type JourneyStep = AuthResponse & { - type: StepType.Step; - payload: Step; - callbacks: BaseCallback[]; - getCallbackOfType: (type: CallbackType) => T; - getCallbacksOfType: (type: CallbackType) => T[]; - setCallbackValue: (type: CallbackType, value: unknown) => void; - getDescription: () => string | undefined; - getHeader: () => string | undefined; - getStage: () => string | undefined; -}; - -// @public -export class KbaCreateCallback extends BaseCallback { - constructor(payload: Callback); - getPredefinedQuestions(): string[]; - getPrompt(): string; - isAllowedUserDefinedQuestions(): boolean; - // (undocumented) - payload: Callback; - setAnswer(answer: string): void; - setQuestion(question: string): void; -} - -export { LegacyServerConfig }; - -export { LogLevel }; - -export { makeJourneyConfig }; - -// @public (undocumented) -export interface MessageCreator { - // (undocumented) - [key: string]: ( - propertyName: string, - params?: { - [key: string]: unknown; - }, - ) => string; -} - -// @public -export class MetadataCallback extends BaseCallback { - constructor(payload: Callback); - getData(): T; - // (undocumented) - payload: Callback; -} - -// @public -export class NameCallback extends BaseCallback { - constructor(payload: Callback); - getPrompt(): string; - // (undocumented) - payload: Callback; - setName(name: string): void; -} - -export { NameValue }; - -// @public (undocumented) -export interface NextOptions { - // (undocumented) - query?: Record; -} - -// @public -export class PasswordCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): string[]; - getPrompt(): string; - // (undocumented) - payload: Callback; - setPassword(password: string): void; -} - -// @public -export class PingOneProtectEvaluationCallback extends BaseCallback { - constructor(payload: Callback); - getPauseBehavioralData(): boolean; - // (undocumented) - payload: Callback; - setClientError(errorMessage: string): void; - setData(data: string): void; -} - -// @public -export class PingOneProtectInitializeCallback extends BaseCallback { - constructor(payload: Callback); - getConfig(): - | Record - | { - envId: string; - consoleLogEnabled: boolean; - deviceAttributesToIgnore: string[]; - customHost: string; - lazyMetadata: boolean; - behavioralDataCollection: boolean; - deviceKeyRsyncIntervals: number; - enableTrust: boolean; - disableTags: boolean; - disableHub: boolean; - }; - // (undocumented) - payload: Callback; - // (undocumented) - setClientError(errorMessage: string): void; -} - -export { PolicyKey }; - -export { PolicyParams }; - -export { PolicyRequirement }; - -// @public -export class PollingWaitCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - getWaitTime(): number; - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export interface ProcessedPropertyError { - // (undocumented) - detail: FailedPolicyRequirement; - // (undocumented) - messages: string[]; -} - -// @public -export class ReCaptchaCallback extends BaseCallback { - constructor(payload: Callback); - getSiteKey(): string; - // (undocumented) - payload: Callback; - setResult(result: string): void; -} - -// @public -export class ReCaptchaEnterpriseCallback extends BaseCallback { - constructor(payload: Callback); - getApiUrl(): string; - getElementClass(): string; - getSiteKey(): string; - // (undocumented) - payload: Callback; - setAction(action: string): void; - setClientError(error: string): void; - setPayload(payload: unknown): void; - setResult(result: string): void; -} - -// @public -export class RedirectCallback extends BaseCallback { - constructor(payload: Callback); - getRedirectUrl(): string; - // (undocumented) - payload: Callback; -} - -export { RequestMiddleware }; - -// @public -export interface ResolvedServerConfig { - // (undocumented) - baseUrl: string; - // (undocumented) - paths: { - authenticate: string; - sessions: string; - }; -} - -// @public (undocumented) -export interface ResumeOptions { - // (undocumented) - journey?: string; - // (undocumented) - query?: Record; -} - -// @public -export class SelectIdPCallback extends BaseCallback { - constructor(payload: Callback); - getProviders(): IdPValue[]; - // (undocumented) - payload: Callback; - setProvider(value: string): void; -} - -// @public (undocumented) -export interface StartParam { - // (undocumented) - journey: string; - // (undocumented) - query?: Record; -} - -export { Step }; - -export { StepDetail }; - -export { StepType }; - -// @public -export class SuspendedTextOutputCallback extends TextOutputCallback { - constructor(payload: Callback); - // (undocumented) - payload: Callback; -} - -// @public -export class TermsAndConditionsCallback extends BaseCallback { - constructor(payload: Callback); - getCreateDate(): Date | null; - getTerms(): string; - getVersion(): string; - // (undocumented) - payload: Callback; - setAccepted(accepted?: boolean): void; -} - -// @public -export class TextInputCallback extends BaseCallback { - constructor(payload: Callback); - getPrompt(): string; - // (undocumented) - payload: Callback; - setInput(input: string): void; -} - -// @public -export class TextOutputCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - getMessageType(): string; - // (undocumented) - payload: Callback; -} - -// @public -export class ValidatedCreatePasswordCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setPassword(password: string): void; - setValidateOnly(value: boolean): void; -} - -// @public -export class ValidatedCreateUsernameCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setName(name: string): void; - setValidateOnly(value: boolean): void; -} - -export { WellknownResponse }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/journey-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { AuthResponse } from '@forgerock/sdk-types'; +import { Callback } from '@forgerock/sdk-types'; +import { CallbackType } from '@forgerock/sdk-types'; +import { callbackType } from '@forgerock/sdk-types'; +import { createWellknownError } from '@forgerock/sdk-utilities'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import { FailedPolicyRequirement } from '@forgerock/sdk-types'; +import { FailureDetail } from '@forgerock/sdk-types'; +import { GenericError } from '@forgerock/sdk-types'; +import { isValidWellknownUrl } from '@forgerock/sdk-utilities'; +import { JourneyClientConfig } from '@forgerock/sdk-types'; +import { JourneyServerConfig } from '@forgerock/sdk-types'; +import { LegacyServerConfig } from '@forgerock/sdk-types'; +import { LogLevel } from '@forgerock/sdk-logger'; +import { makeJourneyConfig } from '@forgerock/sdk-utilities'; +import { NameValue } from '@forgerock/sdk-types'; +import { PolicyKey } from '@forgerock/sdk-types'; +import { PolicyParams } from '@forgerock/sdk-types'; +import { PolicyRequirement } from '@forgerock/sdk-types'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { Step } from '@forgerock/sdk-types'; +import { StepDetail } from '@forgerock/sdk-types'; +import { StepType } from '@forgerock/sdk-types'; +import { WellknownResponse } from '@forgerock/sdk-types'; + +export { ActionTypes } + +// @public +export class AttributeInputCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getName(): string; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setValidateOnly(value: boolean): void; + setValue(value: T): void; +} + +export { AuthResponse } + +// @public +export class BaseCallback { + constructor(payload: Callback); + getInputValue(selector?: number | string): unknown; + getOutputByName(name: string, defaultValue: T): T; + getOutputValue(selector?: number | string): unknown; + getType(): CallbackType; + // (undocumented) + payload: Callback; + setInputValue(value: unknown, selector?: number | string | RegExp): void; +} + +export { Callback } + +// @public (undocumented) +export type CallbackFactory = (callback: Callback) => BaseCallback; + +export { CallbackType } + +export { callbackType } + +// @public +export class ChoiceCallback extends BaseCallback { + constructor(payload: Callback); + getChoices(): string[]; + getDefaultChoice(): number; + getPrompt(): string; + // (undocumented) + payload: Callback; + setChoiceIndex(index: number): void; + setChoiceValue(value: string): void; +} + +// @public +export class ConfirmationCallback extends BaseCallback { + constructor(payload: Callback); + getDefaultOption(): number; + getMessageType(): number; + getOptions(): string[]; + getOptionType(): number; + getPrompt(): string; + // (undocumented) + payload: Callback; + setOptionIndex(index: number): void; + setOptionValue(value: string): void; +} + +// @public (undocumented) +export function createCallback(callback: Callback): BaseCallback; + +export { createWellknownError } + +export { CustomLogger } + +// @public +export class DeviceProfileCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + isLocationRequired(): boolean; + isMetadataRequired(): boolean; + // (undocumented) + payload: Callback; + setProfile(profile: DeviceProfileData): void; +} + +// @public (undocumented) +export interface DeviceProfileData { + // (undocumented) + identifier: string; + // (undocumented) + location?: Geolocation_2 | Record; + // (undocumented) + metadata?: { + hardware: { + display: { + [key: string]: string | number | null; + }; + [key: string]: any; + }; + browser: { + [key: string]: string | number | null; + }; + platform: { + [key: string]: string | number | null; + }; + }; +} + +export { FailedPolicyRequirement } + +export { FailureDetail } + +export { GenericError } + +// @public (undocumented) +interface Geolocation_2 { + // (undocumented) + latitude: number; + // (undocumented) + longitude: number; +} +export { Geolocation_2 as Geolocation } + +// @public +export class HiddenValueCallback extends BaseCallback { + constructor(payload: Callback); + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export interface IdPValue { + // (undocumented) + provider: string; + // (undocumented) + uiConfig: { + [key: string]: string; + }; +} + +// @internal +export interface InternalJourneyClientConfig { + // (undocumented) + error?: GenericError; + // (undocumented) + serverConfig: ResolvedServerConfig; +} + +export { isValidWellknownUrl } + +// @public +export function journey(input: { + config: JourneyClientConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; +}): Promise; + +// @public +export interface JourneyClient { + // (undocumented) + next: (step: JourneyStep, options?: NextOptions) => Promise; + // (undocumented) + redirect: (step: JourneyStep) => Promise; + // (undocumented) + resume: (url: string, options?: ResumeOptions) => Promise; + // (undocumented) + start: (options?: StartParam) => Promise; + // (undocumented) + store: SdkStore; + // (undocumented) + subscribe: (listener: () => void) => () => void; + // (undocumented) + terminate: (options?: { + query?: Record; + }) => Promise; +} + +export { JourneyClientConfig } + +// @public (undocumented) +export type JourneyLoginFailure = AuthResponse & { + type: StepType.LoginFailure; + payload: Step; + getCode: () => number; + getDetail: () => FailureDetail | undefined; + getMessage: () => string | undefined; + getProcessedMessage: (messageCreator?: MessageCreator) => ProcessedPropertyError[]; + getReason: () => string | undefined; +}; + +// @public (undocumented) +export type JourneyLoginSuccess = AuthResponse & { + type: StepType.LoginSuccess; + payload: Step; + getRealm: () => string | undefined; + getSessionToken: () => string | undefined; + getSuccessUrl: () => string | undefined; +}; + +// @public (undocumented) +export type JourneyResult = JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | GenericError; + +export { JourneyServerConfig } + +// @public (undocumented) +export type JourneyStep = AuthResponse & { + type: StepType.Step; + payload: Step; + callbacks: BaseCallback[]; + getCallbackOfType: (type: CallbackType) => T; + getCallbacksOfType: (type: CallbackType) => T[]; + setCallbackValue: (type: CallbackType, value: unknown) => void; + getDescription: () => string | undefined; + getHeader: () => string | undefined; + getStage: () => string | undefined; +}; + +// @public +export class KbaCreateCallback extends BaseCallback { + constructor(payload: Callback); + getPredefinedQuestions(): string[]; + getPrompt(): string; + isAllowedUserDefinedQuestions(): boolean; + // (undocumented) + payload: Callback; + setAnswer(answer: string): void; + setQuestion(question: string): void; +} + +export { LegacyServerConfig } + +export { LogLevel } + +export { makeJourneyConfig } + +// @public (undocumented) +export interface MessageCreator { + // (undocumented) + [key: string]: (propertyName: string, params?: { + [key: string]: unknown; + }) => string; +} + +// @public +export class MetadataCallback extends BaseCallback { + constructor(payload: Callback); + getData(): T; + // (undocumented) + payload: Callback; +} + +// @public +export class NameCallback extends BaseCallback { + constructor(payload: Callback); + getPrompt(): string; + // (undocumented) + payload: Callback; + setName(name: string): void; +} + +export { NameValue } + +// @public (undocumented) +export interface NextOptions { + // (undocumented) + query?: Record; +} + +// @public +export class PasswordCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): string[]; + getPrompt(): string; + // (undocumented) + payload: Callback; + setPassword(password: string): void; +} + +// @public +export class PingOneProtectEvaluationCallback extends BaseCallback { + constructor(payload: Callback); + getPauseBehavioralData(): boolean; + // (undocumented) + payload: Callback; + setClientError(errorMessage: string): void; + setData(data: string): void; +} + +// @public +export class PingOneProtectInitializeCallback extends BaseCallback { + constructor(payload: Callback); + getConfig(): Record | { + envId: string; + consoleLogEnabled: boolean; + deviceAttributesToIgnore: string[]; + customHost: string; + lazyMetadata: boolean; + behavioralDataCollection: boolean; + deviceKeyRsyncIntervals: number; + enableTrust: boolean; + disableTags: boolean; + disableHub: boolean; + }; + // (undocumented) + payload: Callback; + // (undocumented) + setClientError(errorMessage: string): void; +} + +// @public +export class PingOneRecognizeCallback extends BaseCallback { + constructor(payload: Callback); + // (undocumented) + getCustomerName(): string; + // (undocumented) + getOperationType(): PingOneRecognizeOperationType; + // (undocumented) + getOptions(): Record; + // (undocumented) + getServiceURL(): string; + // (undocumented) + getTransactionData(): string; + // (undocumented) + getUsername(): string; + // (undocumented) + payload: Callback; + // (undocumented) + setClientError(errorMessage: string): void; + // (undocumented) + setClientErrorCode(errorCode: string): void; + // (undocumented) + setRecognizeId(recognizeId: string): void; + // (undocumented) + setSignedJwt(jwt: string): void; +} + +// @public (undocumented) +export type PingOneRecognizeOperationType = 'ENROLL' | 'AUTHENTICATE'; + +export { PolicyKey } + +export { PolicyParams } + +export { PolicyRequirement } + +// @public +export class PollingWaitCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + getWaitTime(): number; + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export interface ProcessedPropertyError { + // (undocumented) + detail: FailedPolicyRequirement; + // (undocumented) + messages: string[]; +} + +// @public +export class ReCaptchaCallback extends BaseCallback { + constructor(payload: Callback); + getSiteKey(): string; + // (undocumented) + payload: Callback; + setResult(result: string): void; +} + +// @public +export class ReCaptchaEnterpriseCallback extends BaseCallback { + constructor(payload: Callback); + getApiUrl(): string; + getElementClass(): string; + getSiteKey(): string; + // (undocumented) + payload: Callback; + setAction(action: string): void; + setClientError(error: string): void; + setPayload(payload: unknown): void; + setResult(result: string): void; +} + +// @public +export class RedirectCallback extends BaseCallback { + constructor(payload: Callback); + getRedirectUrl(): string; + // (undocumented) + payload: Callback; +} + +export { RequestMiddleware } + +// @public +export interface ResolvedServerConfig { + // (undocumented) + baseUrl: string; + // (undocumented) + paths: { + authenticate: string; + sessions: string; + }; +} + +// @public (undocumented) +export interface ResumeOptions { + // (undocumented) + journey?: string; + // (undocumented) + query?: Record; +} + +// @public +export class SelectIdPCallback extends BaseCallback { + constructor(payload: Callback); + getProviders(): IdPValue[]; + // (undocumented) + payload: Callback; + setProvider(value: string): void; +} + +// @public (undocumented) +export interface StartParam { + // (undocumented) + journey: string; + // (undocumented) + query?: Record; +} + +export { Step } + +export { StepDetail } + +export { StepType } + +// @public +export class SuspendedTextOutputCallback extends TextOutputCallback { + constructor(payload: Callback); + // (undocumented) + payload: Callback; +} + +// @public +export class TermsAndConditionsCallback extends BaseCallback { + constructor(payload: Callback); + getCreateDate(): Date | null; + getTerms(): string; + getVersion(): string; + // (undocumented) + payload: Callback; + setAccepted(accepted?: boolean): void; +} + +// @public +export class TextInputCallback extends BaseCallback { + constructor(payload: Callback); + getPrompt(): string; + // (undocumented) + payload: Callback; + setInput(input: string): void; +} + +// @public +export class TextOutputCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + getMessageType(): string; + // (undocumented) + payload: Callback; +} + +// @public +export class ValidatedCreatePasswordCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setPassword(password: string): void; + setValidateOnly(value: boolean): void; +} + +// @public +export class ValidatedCreateUsernameCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setName(name: string): void; + setValidateOnly(value: boolean): void; +} + +export { WellknownResponse } + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/journey-client/api-report/journey-client.types.api.md b/packages/journey-client/api-report/journey-client.types.api.md index f6b1565f2cb..b834afaa531 100644 --- a/packages/journey-client/api-report/journey-client.types.api.md +++ b/packages/journey-client/api-report/journey-client.types.api.md @@ -1,491 +1,523 @@ -## API Report File for "@forgerock/journey-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { AuthResponse } from '@forgerock/sdk-types'; -import { Callback } from '@forgerock/sdk-types'; -import { CallbackType } from '@forgerock/sdk-types'; -import { createWellknownError } from '@forgerock/sdk-utilities'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import { FailedPolicyRequirement } from '@forgerock/sdk-types'; -import { FailureDetail } from '@forgerock/sdk-types'; -import { GenericError } from '@forgerock/sdk-types'; -import { isValidWellknownUrl } from '@forgerock/sdk-utilities'; -import { JourneyClientConfig } from '@forgerock/sdk-types'; -import { JourneyServerConfig } from '@forgerock/sdk-types'; -import { LegacyServerConfig } from '@forgerock/sdk-types'; -import { LogLevel } from '@forgerock/sdk-logger'; -import { NameValue } from '@forgerock/sdk-types'; -import { PolicyKey } from '@forgerock/sdk-types'; -import { PolicyParams } from '@forgerock/sdk-types'; -import { PolicyRequirement } from '@forgerock/sdk-types'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { Step } from '@forgerock/sdk-types'; -import { StepDetail } from '@forgerock/sdk-types'; -import { StepType } from '@forgerock/sdk-types'; -import { WellknownResponse } from '@forgerock/sdk-types'; - -export { ActionTypes }; - -// @public -export class AttributeInputCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getName(): string; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setValidateOnly(value: boolean): void; - setValue(value: T): void; -} - -export { AuthResponse }; - -// @public -export class BaseCallback { - constructor(payload: Callback); - getInputValue(selector?: number | string): unknown; - getOutputByName(name: string, defaultValue: T): T; - getOutputValue(selector?: number | string): unknown; - getType(): CallbackType; - // (undocumented) - payload: Callback; - setInputValue(value: unknown, selector?: number | string | RegExp): void; -} - -export { Callback }; - -// @public (undocumented) -export type CallbackFactory = (callback: Callback) => BaseCallback; - -export { CallbackType }; - -// @public -export class ChoiceCallback extends BaseCallback { - constructor(payload: Callback); - getChoices(): string[]; - getDefaultChoice(): number; - getPrompt(): string; - // (undocumented) - payload: Callback; - setChoiceIndex(index: number): void; - setChoiceValue(value: string): void; -} - -// @public -export class ConfirmationCallback extends BaseCallback { - constructor(payload: Callback); - getDefaultOption(): number; - getMessageType(): number; - getOptions(): string[]; - getOptionType(): number; - getPrompt(): string; - // (undocumented) - payload: Callback; - setOptionIndex(index: number): void; - setOptionValue(value: string): void; -} - -// @public (undocumented) -export function createCallback(callback: Callback): BaseCallback; - -export { createWellknownError }; - -export { CustomLogger }; - -// @public -export class DeviceProfileCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - isLocationRequired(): boolean; - isMetadataRequired(): boolean; - // (undocumented) - payload: Callback; - setProfile(profile: DeviceProfileData): void; -} - -// @public (undocumented) -export interface DeviceProfileData { - // (undocumented) - identifier: string; - // (undocumented) - location?: Geolocation_2 | Record; - // (undocumented) - metadata?: { - hardware: { - display: { - [key: string]: string | number | null; - }; - [key: string]: any; - }; - browser: { - [key: string]: string | number | null; - }; - platform: { - [key: string]: string | number | null; - }; - }; -} - -export { FailedPolicyRequirement }; - -export { FailureDetail }; - -export { GenericError }; - -// @public (undocumented) -interface Geolocation_2 { - // (undocumented) - latitude: number; - // (undocumented) - longitude: number; -} -export { Geolocation_2 as Geolocation }; - -// @public -export class HiddenValueCallback extends BaseCallback { - constructor(payload: Callback); - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export interface IdPValue { - // (undocumented) - provider: string; - // (undocumented) - uiConfig: { - [key: string]: string; - }; -} - -// @internal -export interface InternalJourneyClientConfig { - // (undocumented) - error?: GenericError; - // (undocumented) - serverConfig: ResolvedServerConfig; -} - -export { isValidWellknownUrl }; - -// @public -export interface JourneyClient { - // (undocumented) - next: (step: JourneyStep, options?: NextOptions) => Promise; - // (undocumented) - redirect: (step: JourneyStep) => Promise; - // (undocumented) - resume: (url: string, options?: ResumeOptions) => Promise; - // (undocumented) - start: (options?: StartParam) => Promise; - // (undocumented) - subscribe: (listener: () => void) => () => void; - // (undocumented) - terminate: (options?: { query?: Record }) => Promise; -} - -export { JourneyClientConfig }; - -// @public (undocumented) -export type JourneyLoginFailure = AuthResponse & { - type: StepType.LoginFailure; - payload: Step; - getCode: () => number; - getDetail: () => FailureDetail | undefined; - getMessage: () => string | undefined; - getProcessedMessage: (messageCreator?: MessageCreator) => ProcessedPropertyError[]; - getReason: () => string | undefined; -}; - -// @public (undocumented) -export type JourneyLoginSuccess = AuthResponse & { - type: StepType.LoginSuccess; - payload: Step; - getRealm: () => string | undefined; - getSessionToken: () => string | undefined; - getSuccessUrl: () => string | undefined; -}; - -// @public (undocumented) -export type JourneyResult = JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | GenericError; - -export { JourneyServerConfig }; - -// @public (undocumented) -export type JourneyStep = AuthResponse & { - type: StepType.Step; - payload: Step; - callbacks: BaseCallback[]; - getCallbackOfType: (type: CallbackType) => T; - getCallbacksOfType: (type: CallbackType) => T[]; - setCallbackValue: (type: CallbackType, value: unknown) => void; - getDescription: () => string | undefined; - getHeader: () => string | undefined; - getStage: () => string | undefined; -}; - -// @public -export class KbaCreateCallback extends BaseCallback { - constructor(payload: Callback); - getPredefinedQuestions(): string[]; - getPrompt(): string; - isAllowedUserDefinedQuestions(): boolean; - // (undocumented) - payload: Callback; - setAnswer(answer: string): void; - setQuestion(question: string): void; -} - -export { LegacyServerConfig }; - -export { LogLevel }; - -// @public (undocumented) -export interface MessageCreator { - // (undocumented) - [key: string]: ( - propertyName: string, - params?: { - [key: string]: unknown; - }, - ) => string; -} - -// @public -export class MetadataCallback extends BaseCallback { - constructor(payload: Callback); - getData(): T; - // (undocumented) - payload: Callback; -} - -// @public -export class NameCallback extends BaseCallback { - constructor(payload: Callback); - getPrompt(): string; - // (undocumented) - payload: Callback; - setName(name: string): void; -} - -export { NameValue }; - -// @public (undocumented) -export interface NextOptions { - // (undocumented) - query?: Record; -} - -// @public -export class PasswordCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): string[]; - getPrompt(): string; - // (undocumented) - payload: Callback; - setPassword(password: string): void; -} - -// @public -export class PingOneProtectEvaluationCallback extends BaseCallback { - constructor(payload: Callback); - getPauseBehavioralData(): boolean; - // (undocumented) - payload: Callback; - setClientError(errorMessage: string): void; - setData(data: string): void; -} - -// @public -export class PingOneProtectInitializeCallback extends BaseCallback { - constructor(payload: Callback); - getConfig(): - | Record - | { - envId: string; - consoleLogEnabled: boolean; - deviceAttributesToIgnore: string[]; - customHost: string; - lazyMetadata: boolean; - behavioralDataCollection: boolean; - deviceKeyRsyncIntervals: number; - enableTrust: boolean; - disableTags: boolean; - disableHub: boolean; - }; - // (undocumented) - payload: Callback; - // (undocumented) - setClientError(errorMessage: string): void; -} - -export { PolicyKey }; - -export { PolicyParams }; - -export { PolicyRequirement }; - -// @public -export class PollingWaitCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - getWaitTime(): number; - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export interface ProcessedPropertyError { - // (undocumented) - detail: FailedPolicyRequirement; - // (undocumented) - messages: string[]; -} - -// @public -export class ReCaptchaCallback extends BaseCallback { - constructor(payload: Callback); - getSiteKey(): string; - // (undocumented) - payload: Callback; - setResult(result: string): void; -} - -// @public -export class ReCaptchaEnterpriseCallback extends BaseCallback { - constructor(payload: Callback); - getApiUrl(): string; - getElementClass(): string; - getSiteKey(): string; - // (undocumented) - payload: Callback; - setAction(action: string): void; - setClientError(error: string): void; - setPayload(payload: unknown): void; - setResult(result: string): void; -} - -// @public -export class RedirectCallback extends BaseCallback { - constructor(payload: Callback); - getRedirectUrl(): string; - // (undocumented) - payload: Callback; -} - -export { RequestMiddleware }; - -// @public -export interface ResolvedServerConfig { - // (undocumented) - baseUrl: string; - // (undocumented) - paths: { - authenticate: string; - sessions: string; - }; -} - -// @public (undocumented) -export interface ResumeOptions { - // (undocumented) - journey?: string; - // (undocumented) - query?: Record; -} - -// @public -export class SelectIdPCallback extends BaseCallback { - constructor(payload: Callback); - getProviders(): IdPValue[]; - // (undocumented) - payload: Callback; - setProvider(value: string): void; -} - -// @public (undocumented) -export interface StartParam { - // (undocumented) - journey: string; - // (undocumented) - query?: Record; -} - -export { Step }; - -export { StepDetail }; - -export { StepType }; - -// @public -export class SuspendedTextOutputCallback extends TextOutputCallback { - constructor(payload: Callback); - // (undocumented) - payload: Callback; -} - -// @public -export class TermsAndConditionsCallback extends BaseCallback { - constructor(payload: Callback); - getCreateDate(): Date | null; - getTerms(): string; - getVersion(): string; - // (undocumented) - payload: Callback; - setAccepted(accepted?: boolean): void; -} - -// @public -export class TextInputCallback extends BaseCallback { - constructor(payload: Callback); - getPrompt(): string; - // (undocumented) - payload: Callback; - setInput(input: string): void; -} - -// @public -export class TextOutputCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - getMessageType(): string; - // (undocumented) - payload: Callback; -} - -// @public -export class ValidatedCreatePasswordCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setPassword(password: string): void; - setValidateOnly(value: boolean): void; -} - -// @public -export class ValidatedCreateUsernameCallback extends BaseCallback { - constructor(payload: Callback); - getFailedPolicies(): PolicyRequirement[]; - getPolicies(): Record; - getPrompt(): string; - isRequired(): boolean; - // (undocumented) - payload: Callback; - setName(name: string): void; - setValidateOnly(value: boolean): void; -} - -export { WellknownResponse }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/journey-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { AuthResponse } from '@forgerock/sdk-types'; +import { Callback } from '@forgerock/sdk-types'; +import { CallbackType } from '@forgerock/sdk-types'; +import { createWellknownError } from '@forgerock/sdk-utilities'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import { FailedPolicyRequirement } from '@forgerock/sdk-types'; +import { FailureDetail } from '@forgerock/sdk-types'; +import { GenericError } from '@forgerock/sdk-types'; +import { isValidWellknownUrl } from '@forgerock/sdk-utilities'; +import { JourneyClientConfig } from '@forgerock/sdk-types'; +import { JourneyServerConfig } from '@forgerock/sdk-types'; +import { LegacyServerConfig } from '@forgerock/sdk-types'; +import { LogLevel } from '@forgerock/sdk-logger'; +import { NameValue } from '@forgerock/sdk-types'; +import { PolicyKey } from '@forgerock/sdk-types'; +import { PolicyParams } from '@forgerock/sdk-types'; +import { PolicyRequirement } from '@forgerock/sdk-types'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { Step } from '@forgerock/sdk-types'; +import { StepDetail } from '@forgerock/sdk-types'; +import { StepType } from '@forgerock/sdk-types'; +import { WellknownResponse } from '@forgerock/sdk-types'; + +export { ActionTypes } + +// @public +export class AttributeInputCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getName(): string; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setValidateOnly(value: boolean): void; + setValue(value: T): void; +} + +export { AuthResponse } + +// @public +export class BaseCallback { + constructor(payload: Callback); + getInputValue(selector?: number | string): unknown; + getOutputByName(name: string, defaultValue: T): T; + getOutputValue(selector?: number | string): unknown; + getType(): CallbackType; + // (undocumented) + payload: Callback; + setInputValue(value: unknown, selector?: number | string | RegExp): void; +} + +export { Callback } + +// @public (undocumented) +export type CallbackFactory = (callback: Callback) => BaseCallback; + +export { CallbackType } + +// @public +export class ChoiceCallback extends BaseCallback { + constructor(payload: Callback); + getChoices(): string[]; + getDefaultChoice(): number; + getPrompt(): string; + // (undocumented) + payload: Callback; + setChoiceIndex(index: number): void; + setChoiceValue(value: string): void; +} + +// @public +export class ConfirmationCallback extends BaseCallback { + constructor(payload: Callback); + getDefaultOption(): number; + getMessageType(): number; + getOptions(): string[]; + getOptionType(): number; + getPrompt(): string; + // (undocumented) + payload: Callback; + setOptionIndex(index: number): void; + setOptionValue(value: string): void; +} + +// @public (undocumented) +export function createCallback(callback: Callback): BaseCallback; + +export { createWellknownError } + +export { CustomLogger } + +// @public +export class DeviceProfileCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + isLocationRequired(): boolean; + isMetadataRequired(): boolean; + // (undocumented) + payload: Callback; + setProfile(profile: DeviceProfileData): void; +} + +// @public (undocumented) +export interface DeviceProfileData { + // (undocumented) + identifier: string; + // (undocumented) + location?: Geolocation_2 | Record; + // (undocumented) + metadata?: { + hardware: { + display: { + [key: string]: string | number | null; + }; + [key: string]: any; + }; + browser: { + [key: string]: string | number | null; + }; + platform: { + [key: string]: string | number | null; + }; + }; +} + +export { FailedPolicyRequirement } + +export { FailureDetail } + +export { GenericError } + +// @public (undocumented) +interface Geolocation_2 { + // (undocumented) + latitude: number; + // (undocumented) + longitude: number; +} +export { Geolocation_2 as Geolocation } + +// @public +export class HiddenValueCallback extends BaseCallback { + constructor(payload: Callback); + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export interface IdPValue { + // (undocumented) + provider: string; + // (undocumented) + uiConfig: { + [key: string]: string; + }; +} + +// @internal +export interface InternalJourneyClientConfig { + // (undocumented) + error?: GenericError; + // (undocumented) + serverConfig: ResolvedServerConfig; +} + +export { isValidWellknownUrl } + +// @public +export interface JourneyClient { + // (undocumented) + next: (step: JourneyStep, options?: NextOptions) => Promise; + // (undocumented) + redirect: (step: JourneyStep) => Promise; + // (undocumented) + resume: (url: string, options?: ResumeOptions) => Promise; + // (undocumented) + start: (options?: StartParam) => Promise; + // (undocumented) + store: SdkStore; + // (undocumented) + subscribe: (listener: () => void) => () => void; + // (undocumented) + terminate: (options?: { + query?: Record; + }) => Promise; +} + +export { JourneyClientConfig } + +// @public (undocumented) +export type JourneyLoginFailure = AuthResponse & { + type: StepType.LoginFailure; + payload: Step; + getCode: () => number; + getDetail: () => FailureDetail | undefined; + getMessage: () => string | undefined; + getProcessedMessage: (messageCreator?: MessageCreator) => ProcessedPropertyError[]; + getReason: () => string | undefined; +}; + +// @public (undocumented) +export type JourneyLoginSuccess = AuthResponse & { + type: StepType.LoginSuccess; + payload: Step; + getRealm: () => string | undefined; + getSessionToken: () => string | undefined; + getSuccessUrl: () => string | undefined; +}; + +// @public (undocumented) +export type JourneyResult = JourneyStep | JourneyLoginSuccess | JourneyLoginFailure | GenericError; + +export { JourneyServerConfig } + +// @public (undocumented) +export type JourneyStep = AuthResponse & { + type: StepType.Step; + payload: Step; + callbacks: BaseCallback[]; + getCallbackOfType: (type: CallbackType) => T; + getCallbacksOfType: (type: CallbackType) => T[]; + setCallbackValue: (type: CallbackType, value: unknown) => void; + getDescription: () => string | undefined; + getHeader: () => string | undefined; + getStage: () => string | undefined; +}; + +// @public +export class KbaCreateCallback extends BaseCallback { + constructor(payload: Callback); + getPredefinedQuestions(): string[]; + getPrompt(): string; + isAllowedUserDefinedQuestions(): boolean; + // (undocumented) + payload: Callback; + setAnswer(answer: string): void; + setQuestion(question: string): void; +} + +export { LegacyServerConfig } + +export { LogLevel } + +// @public (undocumented) +export interface MessageCreator { + // (undocumented) + [key: string]: (propertyName: string, params?: { + [key: string]: unknown; + }) => string; +} + +// @public +export class MetadataCallback extends BaseCallback { + constructor(payload: Callback); + getData(): T; + // (undocumented) + payload: Callback; +} + +// @public +export class NameCallback extends BaseCallback { + constructor(payload: Callback); + getPrompt(): string; + // (undocumented) + payload: Callback; + setName(name: string): void; +} + +export { NameValue } + +// @public (undocumented) +export interface NextOptions { + // (undocumented) + query?: Record; +} + +// @public +export class PasswordCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): string[]; + getPrompt(): string; + // (undocumented) + payload: Callback; + setPassword(password: string): void; +} + +// @public +export class PingOneProtectEvaluationCallback extends BaseCallback { + constructor(payload: Callback); + getPauseBehavioralData(): boolean; + // (undocumented) + payload: Callback; + setClientError(errorMessage: string): void; + setData(data: string): void; +} + +// @public +export class PingOneProtectInitializeCallback extends BaseCallback { + constructor(payload: Callback); + getConfig(): Record | { + envId: string; + consoleLogEnabled: boolean; + deviceAttributesToIgnore: string[]; + customHost: string; + lazyMetadata: boolean; + behavioralDataCollection: boolean; + deviceKeyRsyncIntervals: number; + enableTrust: boolean; + disableTags: boolean; + disableHub: boolean; + }; + // (undocumented) + payload: Callback; + // (undocumented) + setClientError(errorMessage: string): void; +} + +// @public +export class PingOneRecognizeCallback extends BaseCallback { + constructor(payload: Callback); + // (undocumented) + getCustomerName(): string; + // (undocumented) + getOperationType(): PingOneRecognizeOperationType; + // (undocumented) + getOptions(): Record; + // (undocumented) + getServiceURL(): string; + // (undocumented) + getTransactionData(): string; + // (undocumented) + getUsername(): string; + // (undocumented) + payload: Callback; + // (undocumented) + setClientError(errorMessage: string): void; + // (undocumented) + setClientErrorCode(errorCode: string): void; + // (undocumented) + setRecognizeId(recognizeId: string): void; + // (undocumented) + setSignedJwt(jwt: string): void; +} + +// @public (undocumented) +export type PingOneRecognizeOperationType = 'ENROLL' | 'AUTHENTICATE'; + +export { PolicyKey } + +export { PolicyParams } + +export { PolicyRequirement } + +// @public +export class PollingWaitCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + getWaitTime(): number; + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export interface ProcessedPropertyError { + // (undocumented) + detail: FailedPolicyRequirement; + // (undocumented) + messages: string[]; +} + +// @public +export class ReCaptchaCallback extends BaseCallback { + constructor(payload: Callback); + getSiteKey(): string; + // (undocumented) + payload: Callback; + setResult(result: string): void; +} + +// @public +export class ReCaptchaEnterpriseCallback extends BaseCallback { + constructor(payload: Callback); + getApiUrl(): string; + getElementClass(): string; + getSiteKey(): string; + // (undocumented) + payload: Callback; + setAction(action: string): void; + setClientError(error: string): void; + setPayload(payload: unknown): void; + setResult(result: string): void; +} + +// @public +export class RedirectCallback extends BaseCallback { + constructor(payload: Callback); + getRedirectUrl(): string; + // (undocumented) + payload: Callback; +} + +export { RequestMiddleware } + +// @public +export interface ResolvedServerConfig { + // (undocumented) + baseUrl: string; + // (undocumented) + paths: { + authenticate: string; + sessions: string; + }; +} + +// @public (undocumented) +export interface ResumeOptions { + // (undocumented) + journey?: string; + // (undocumented) + query?: Record; +} + +// @public +export class SelectIdPCallback extends BaseCallback { + constructor(payload: Callback); + getProviders(): IdPValue[]; + // (undocumented) + payload: Callback; + setProvider(value: string): void; +} + +// @public (undocumented) +export interface StartParam { + // (undocumented) + journey: string; + // (undocumented) + query?: Record; +} + +export { Step } + +export { StepDetail } + +export { StepType } + +// @public +export class SuspendedTextOutputCallback extends TextOutputCallback { + constructor(payload: Callback); + // (undocumented) + payload: Callback; +} + +// @public +export class TermsAndConditionsCallback extends BaseCallback { + constructor(payload: Callback); + getCreateDate(): Date | null; + getTerms(): string; + getVersion(): string; + // (undocumented) + payload: Callback; + setAccepted(accepted?: boolean): void; +} + +// @public +export class TextInputCallback extends BaseCallback { + constructor(payload: Callback); + getPrompt(): string; + // (undocumented) + payload: Callback; + setInput(input: string): void; +} + +// @public +export class TextOutputCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + getMessageType(): string; + // (undocumented) + payload: Callback; +} + +// @public +export class ValidatedCreatePasswordCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setPassword(password: string): void; + setValidateOnly(value: boolean): void; +} + +// @public +export class ValidatedCreateUsernameCallback extends BaseCallback { + constructor(payload: Callback); + getFailedPolicies(): PolicyRequirement[]; + getPolicies(): Record; + getPrompt(): string; + isRequired(): boolean; + // (undocumented) + payload: Callback; + setName(name: string): void; + setValidateOnly(value: boolean): void; +} + +export { WellknownResponse } + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/journey-client/api-report/journey-client.webauthn.api.md b/packages/journey-client/api-report/journey-client.webauthn.api.md index 32e8ec42a86..311a1028280 100644 --- a/packages/journey-client/api-report/journey-client.webauthn.api.md +++ b/packages/journey-client/api-report/journey-client.webauthn.api.md @@ -1,210 +1,189 @@ -## API Report File for "@forgerock/journey-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import type { AuthResponse } from '@forgerock/sdk-types'; -import type { Callback } from '@forgerock/sdk-types'; -import type { CallbackType } from '@forgerock/sdk-types'; -import type { Step } from '@forgerock/sdk-types'; -import type { StepType } from '@forgerock/sdk-types'; - -// @public (undocumented) -export enum AttestationType { - // (undocumented) - Direct = 'direct', - // (undocumented) - Indirect = 'indirect', - // (undocumented) - None = 'none', -} - -// @public -export class BaseCallback { - constructor(payload: Callback); - getInputValue(selector?: number | string): unknown; - getOutputByName(name: string, defaultValue: T): T; - getOutputValue(selector?: number | string): unknown; - getType(): CallbackType; - // (undocumented) - payload: Callback; - setInputValue(value: unknown, selector?: number | string | RegExp): void; -} - -// @public -export class HiddenValueCallback extends BaseCallback { - constructor(payload: Callback); - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export type JourneyStep = AuthResponse & { - type: StepType.Step; - payload: Step; - callbacks: BaseCallback[]; - getCallbackOfType: (type: CallbackType) => T; - getCallbacksOfType: (type: CallbackType) => T[]; - setCallbackValue: (type: CallbackType, value: unknown) => void; - getDescription: () => string | undefined; - getHeader: () => string | undefined; - getStage: () => string | undefined; -}; - -// @public -export class MetadataCallback extends BaseCallback { - constructor(payload: Callback); - getData(): T; - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export type OutcomeWithName< - ClientId extends string, - Attestation extends AttestationType, - PubKeyCred extends PublicKeyCredential, - Name = '', -> = Name extends infer P extends string - ? `${ClientId}::${Attestation}::${PubKeyCred['id']}${P extends '' ? '' : `::${P}`}` - : never; - -// @public (undocumented) -export interface RelyingParty { - // (undocumented) - id?: string; - // (undocumented) - name: string; -} - -// @public -export class TextOutputCallback extends BaseCallback { - constructor(payload: Callback); - getMessage(): string; - getMessageType(): string; - // (undocumented) - payload: Callback; -} - -// @public (undocumented) -export enum UserVerificationType { - // (undocumented) - Discouraged = 'discouraged', - // (undocumented) - Preferred = 'preferred', - // (undocumented) - Required = 'required', -} - -// @public -export abstract class WebAuthn { - static authenticate(step: JourneyStep, signal?: AbortSignal): Promise; - static createAuthenticationPublicKey( - metadata: WebAuthnAuthenticationMetadata, - ): PublicKeyCredentialRequestOptions; - static createRegistrationPublicKey( - metadata: WebAuthnRegistrationMetadata, - ): PublicKeyCredentialCreationOptions; - static getAuthenticationCredential( - options: PublicKeyCredentialRequestOptions, - mediation?: CredentialMediationRequirement, - signal?: AbortSignal, - ): Promise; - static getAuthenticationOutcome( - credential: PublicKeyCredential | null, - ): - | OutcomeWithName - | OutcomeWithName; - static getCallbacks(step: JourneyStep): WebAuthnCallbacks; - static getMetadataCallback(step: JourneyStep): MetadataCallback | undefined; - static getOutcomeCallback(step: JourneyStep): HiddenValueCallback | undefined; - static getRegistrationCredential( - options: PublicKeyCredentialCreationOptions, - ): Promise; - static getRegistrationOutcome( - credential: PublicKeyCredential | null, - ): OutcomeWithName; - static getTextOutputCallback(step: JourneyStep): TextOutputCallback | undefined; - static getWebAuthnStepType(step: JourneyStep): WebAuthnStepType; - static isConditionalMediationSupported(step?: JourneyStep): Promise; - static register(step: JourneyStep, deviceName?: T): Promise; -} - -// @public (undocumented) -export interface WebAuthnAuthenticationMetadata { - // (undocumented) - acceptableCredentials?: string; - // (undocumented) - allowCredentials?: string; - // (undocumented) - challenge: string; - // (undocumented) - mediation?: CredentialMediationRequirement; - // (undocumented) - relyingPartyId: string; - // (undocumented) - supportsJsonResponse?: boolean; - // (undocumented) - timeout: number; - // (undocumented) - userVerification: UserVerificationType; -} - -// @public (undocumented) -export interface WebAuthnCallbacks { - // (undocumented) - hiddenCallback?: HiddenValueCallback; - // (undocumented) - metadataCallback?: MetadataCallback; - // (undocumented) - textOutputCallback?: TextOutputCallback; -} - -// @public (undocumented) -export enum WebAuthnOutcome { - // (undocumented) - Error = 'ERROR', - // (undocumented) - Unsupported = 'unsupported', -} - -// @public (undocumented) -export interface WebAuthnRegistrationMetadata { - // (undocumented) - attestationPreference: 'none' | 'indirect' | 'direct'; - // (undocumented) - authenticatorSelection: string; - // (undocumented) - challenge: string; - // (undocumented) - displayName?: string; - // (undocumented) - excludeCredentials: string; - // (undocumented) - pubKeyCredParams: string; - // (undocumented) - relyingPartyId: string; - // (undocumented) - relyingPartyName: string; - // (undocumented) - supportsJsonResponse?: boolean; - // (undocumented) - timeout: number; - // (undocumented) - userId: string; - // (undocumented) - userName: string; -} - -// @public (undocumented) -export enum WebAuthnStepType { - // (undocumented) - Authentication = 1, - // (undocumented) - None = 0, - // (undocumented) - Registration = 2, -} - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/journey-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import type { AuthResponse } from '@forgerock/sdk-types'; +import type { Callback } from '@forgerock/sdk-types'; +import type { CallbackType } from '@forgerock/sdk-types'; +import type { Step } from '@forgerock/sdk-types'; +import type { StepType } from '@forgerock/sdk-types'; + +// @public (undocumented) +export enum AttestationType { + // (undocumented) + Direct = "direct", + // (undocumented) + Indirect = "indirect", + // (undocumented) + None = "none" +} + +// @public +export class BaseCallback { + constructor(payload: Callback); + getInputValue(selector?: number | string): unknown; + getOutputByName(name: string, defaultValue: T): T; + getOutputValue(selector?: number | string): unknown; + getType(): CallbackType; + // (undocumented) + payload: Callback; + setInputValue(value: unknown, selector?: number | string | RegExp): void; +} + +// @public +export class HiddenValueCallback extends BaseCallback { + constructor(payload: Callback); + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export type JourneyStep = AuthResponse & { + type: StepType.Step; + payload: Step; + callbacks: BaseCallback[]; + getCallbackOfType: (type: CallbackType) => T; + getCallbacksOfType: (type: CallbackType) => T[]; + setCallbackValue: (type: CallbackType, value: unknown) => void; + getDescription: () => string | undefined; + getHeader: () => string | undefined; + getStage: () => string | undefined; +}; + +// @public +export class MetadataCallback extends BaseCallback { + constructor(payload: Callback); + getData(): T; + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export type OutcomeWithName = Name extends infer P extends string ? `${ClientId}::${Attestation}::${PubKeyCred['id']}${P extends '' ? '' : `::${P}`}` : never; + +// @public (undocumented) +export interface RelyingParty { + // (undocumented) + id?: string; + // (undocumented) + name: string; +} + +// @public +export class TextOutputCallback extends BaseCallback { + constructor(payload: Callback); + getMessage(): string; + getMessageType(): string; + // (undocumented) + payload: Callback; +} + +// @public (undocumented) +export enum UserVerificationType { + // (undocumented) + Discouraged = "discouraged", + // (undocumented) + Preferred = "preferred", + // (undocumented) + Required = "required" +} + +// @public +export abstract class WebAuthn { + static authenticate(step: JourneyStep, signal?: AbortSignal): Promise; + static createAuthenticationPublicKey(metadata: WebAuthnAuthenticationMetadata): PublicKeyCredentialRequestOptions; + static createRegistrationPublicKey(metadata: WebAuthnRegistrationMetadata): PublicKeyCredentialCreationOptions; + static getAuthenticationCredential(options: PublicKeyCredentialRequestOptions, mediation?: CredentialMediationRequirement, signal?: AbortSignal): Promise; + static getAuthenticationOutcome(credential: PublicKeyCredential | null): OutcomeWithName | OutcomeWithName; + static getCallbacks(step: JourneyStep): WebAuthnCallbacks; + static getMetadataCallback(step: JourneyStep): MetadataCallback | undefined; + static getOutcomeCallback(step: JourneyStep): HiddenValueCallback | undefined; + static getRegistrationCredential(options: PublicKeyCredentialCreationOptions): Promise; + static getRegistrationOutcome(credential: PublicKeyCredential | null): OutcomeWithName; + static getTextOutputCallback(step: JourneyStep): TextOutputCallback | undefined; + static getWebAuthnStepType(step: JourneyStep): WebAuthnStepType; + static isConditionalMediationSupported(): Promise; + static register(step: JourneyStep, deviceName?: T): Promise; +} + +// @public (undocumented) +export interface WebAuthnAuthenticationMetadata { + // (undocumented) + acceptableCredentials?: string; + // (undocumented) + allowCredentials?: string; + // (undocumented) + challenge: string; + // (undocumented) + mediation?: CredentialMediationRequirement; + // (undocumented) + relyingPartyId: string; + // (undocumented) + supportsJsonResponse?: boolean; + // (undocumented) + timeout: number; + // (undocumented) + userVerification: UserVerificationType; +} + +// @public (undocumented) +export interface WebAuthnCallbacks { + // (undocumented) + hiddenCallback?: HiddenValueCallback; + // (undocumented) + metadataCallback?: MetadataCallback; + // (undocumented) + textOutputCallback?: TextOutputCallback; +} + +// @public (undocumented) +export enum WebAuthnOutcome { + // (undocumented) + Error = "ERROR", + // (undocumented) + Unsupported = "unsupported" +} + +// @public (undocumented) +export interface WebAuthnRegistrationMetadata { + // (undocumented) + attestationPreference: 'none' | 'indirect' | 'direct'; + // (undocumented) + authenticatorSelection: string; + // (undocumented) + challenge: string; + // (undocumented) + displayName?: string; + // (undocumented) + excludeCredentials: string; + // (undocumented) + pubKeyCredParams: string; + // (undocumented) + relyingPartyId: string; + // (undocumented) + relyingPartyName: string; + // (undocumented) + supportsJsonResponse?: boolean; + // (undocumented) + timeout: number; + // (undocumented) + userId: string; + // (undocumented) + userName: string; +} + +// @public (undocumented) +export enum WebAuthnStepType { + // (undocumented) + Authentication = 1, + // (undocumented) + None = 0, + // (undocumented) + Registration = 2 +} + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/journey-client/package.json b/packages/journey-client/package.json index ff2e9148304..00b1c94f9a8 100644 --- a/packages/journey-client/package.json +++ b/packages/journey-client/package.json @@ -38,6 +38,7 @@ "@forgerock/sdk-request-middleware": "workspace:*", "@forgerock/sdk-types": "workspace:*", "@forgerock/sdk-utilities": "workspace:*", + "@forgerock/sdk-wellknown": "workspace:*", "@forgerock/storage": "workspace:*", "@reduxjs/toolkit": "catalog:", "effect": "catalog:effect", diff --git a/packages/journey-client/src/__tests__/types-reexport.typecheck.ts b/packages/journey-client/src/__tests__/types-reexport.typecheck.ts index bff6543a2d6..502b92d71f3 100644 --- a/packages/journey-client/src/__tests__/types-reexport.typecheck.ts +++ b/packages/journey-client/src/__tests__/types-reexport.typecheck.ts @@ -1,10 +1,3 @@ -/* - * Copyright (c) 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - /** * Verifies consumer-facing types are re-exported from @forgerock/journey-client/types. * Checked by tsc --noEmit, not executed at runtime. @@ -22,9 +15,11 @@ import type { FailureDetail, GenericError, LogLevel, + // These should be re-exported but are not yet NameValue, PolicyRequirement, RequestMiddleware, + // Already re-exported (regression guard) Step, StepDetail, StepType, diff --git a/packages/journey-client/src/lib/callbacks/attribute-input-callback.test.ts b/packages/journey-client/src/lib/callbacks/attribute-input-callback.test.ts index d9d2794be7c..ee3395af9ce 100644 --- a/packages/journey-client/src/lib/callbacks/attribute-input-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/attribute-input-callback.test.ts @@ -3,7 +3,7 @@ * * attribute-input-callback.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/attribute-input-callback.ts b/packages/journey-client/src/lib/callbacks/attribute-input-callback.ts index 0692e874eb1..48cc1a90369 100644 --- a/packages/journey-client/src/lib/callbacks/attribute-input-callback.ts +++ b/packages/journey-client/src/lib/callbacks/attribute-input-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/base-callback.test.ts b/packages/journey-client/src/lib/callbacks/base-callback.test.ts index 95dbd691c58..07ea7004edd 100644 --- a/packages/journey-client/src/lib/callbacks/base-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/base-callback.test.ts @@ -3,7 +3,7 @@ * * fr-auth-callback.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/base-callback.ts b/packages/journey-client/src/lib/callbacks/base-callback.ts index f0f4fdf3e00..6ab2166c62a 100644 --- a/packages/journey-client/src/lib/callbacks/base-callback.ts +++ b/packages/journey-client/src/lib/callbacks/base-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/choice-callback.test.ts b/packages/journey-client/src/lib/callbacks/choice-callback.test.ts index b39500086d7..ef025e884b0 100644 --- a/packages/journey-client/src/lib/callbacks/choice-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/choice-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/choice-callback.ts b/packages/journey-client/src/lib/callbacks/choice-callback.ts index 80c4796ce70..ad9a0ed7d3b 100644 --- a/packages/journey-client/src/lib/callbacks/choice-callback.ts +++ b/packages/journey-client/src/lib/callbacks/choice-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/confirmation-callback.test.ts b/packages/journey-client/src/lib/callbacks/confirmation-callback.test.ts index 81676a8a590..b83f36e248d 100644 --- a/packages/journey-client/src/lib/callbacks/confirmation-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/confirmation-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/confirmation-callback.ts b/packages/journey-client/src/lib/callbacks/confirmation-callback.ts index e10d0bc8f17..407869574d6 100644 --- a/packages/journey-client/src/lib/callbacks/confirmation-callback.ts +++ b/packages/journey-client/src/lib/callbacks/confirmation-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/device-profile-callback.test.ts b/packages/journey-client/src/lib/callbacks/device-profile-callback.test.ts index 0acebe70526..45f440b4d12 100644 --- a/packages/journey-client/src/lib/callbacks/device-profile-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/device-profile-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/device-profile-callback.ts b/packages/journey-client/src/lib/callbacks/device-profile-callback.ts index ffc7ecd11c2..a1a6ec0a19c 100644 --- a/packages/journey-client/src/lib/callbacks/device-profile-callback.ts +++ b/packages/journey-client/src/lib/callbacks/device-profile-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/factory.test.ts b/packages/journey-client/src/lib/callbacks/factory.test.ts index 0b5c72c37b1..6b41e3cee31 100644 --- a/packages/journey-client/src/lib/callbacks/factory.test.ts +++ b/packages/journey-client/src/lib/callbacks/factory.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/hidden-value-callback.test.ts b/packages/journey-client/src/lib/callbacks/hidden-value-callback.test.ts index 6c6e1159e49..f69ea8426f5 100644 --- a/packages/journey-client/src/lib/callbacks/hidden-value-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/hidden-value-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/hidden-value-callback.ts b/packages/journey-client/src/lib/callbacks/hidden-value-callback.ts index 9650a71f359..7fa27819b2f 100644 --- a/packages/journey-client/src/lib/callbacks/hidden-value-callback.ts +++ b/packages/journey-client/src/lib/callbacks/hidden-value-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/kba-create-callback.test.ts b/packages/journey-client/src/lib/callbacks/kba-create-callback.test.ts index 88a44d3ee2d..5d8c3135509 100644 --- a/packages/journey-client/src/lib/callbacks/kba-create-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/kba-create-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/kba-create-callback.ts b/packages/journey-client/src/lib/callbacks/kba-create-callback.ts index 980bbcb6d88..544771295ea 100644 --- a/packages/journey-client/src/lib/callbacks/kba-create-callback.ts +++ b/packages/journey-client/src/lib/callbacks/kba-create-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/metadata-callback.test.ts b/packages/journey-client/src/lib/callbacks/metadata-callback.test.ts index 533de8c0123..047b7b1818e 100644 --- a/packages/journey-client/src/lib/callbacks/metadata-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/metadata-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/metadata-callback.ts b/packages/journey-client/src/lib/callbacks/metadata-callback.ts index d7c65765b50..2df225edac7 100644 --- a/packages/journey-client/src/lib/callbacks/metadata-callback.ts +++ b/packages/journey-client/src/lib/callbacks/metadata-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/name-callback.test.ts b/packages/journey-client/src/lib/callbacks/name-callback.test.ts index 15f10631f30..97259ecad17 100644 --- a/packages/journey-client/src/lib/callbacks/name-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/name-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/name-callback.ts b/packages/journey-client/src/lib/callbacks/name-callback.ts index 4eecf0d1a55..d36e6ef20ef 100644 --- a/packages/journey-client/src/lib/callbacks/name-callback.ts +++ b/packages/journey-client/src/lib/callbacks/name-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/password-callback.test.ts b/packages/journey-client/src/lib/callbacks/password-callback.test.ts index 7a97776bb00..718441e17c0 100644 --- a/packages/journey-client/src/lib/callbacks/password-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/password-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/password-callback.ts b/packages/journey-client/src/lib/callbacks/password-callback.ts index 028cee73459..e016a8d0db9 100644 --- a/packages/journey-client/src/lib/callbacks/password-callback.ts +++ b/packages/journey-client/src/lib/callbacks/password-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.test.ts b/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.test.ts index 8d675173134..5f1ee4f2b9a 100644 --- a/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.test.ts @@ -3,7 +3,7 @@ * * ping-protect-evaluation-callback.test.ts * - * Copyright (c) 2024 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2024 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.ts b/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.ts index 1e13eaf58b4..68911dcd766 100644 --- a/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.ts +++ b/packages/journey-client/src/lib/callbacks/ping-protect-evaluation-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2024 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/polling-wait-callback.test.ts b/packages/journey-client/src/lib/callbacks/polling-wait-callback.test.ts index c919a7ce879..8acfe27da8a 100644 --- a/packages/journey-client/src/lib/callbacks/polling-wait-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/polling-wait-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/polling-wait-callback.ts b/packages/journey-client/src/lib/callbacks/polling-wait-callback.ts index f607e202eea..4e48d8a9d2a 100644 --- a/packages/journey-client/src/lib/callbacks/polling-wait-callback.ts +++ b/packages/journey-client/src/lib/callbacks/polling-wait-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/recaptcha-callback.test.ts b/packages/journey-client/src/lib/callbacks/recaptcha-callback.test.ts index db46cc3b532..64faf604b09 100644 --- a/packages/journey-client/src/lib/callbacks/recaptcha-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/recaptcha-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/recaptcha-callback.ts b/packages/journey-client/src/lib/callbacks/recaptcha-callback.ts index f5846abfc69..5877ad99864 100644 --- a/packages/journey-client/src/lib/callbacks/recaptcha-callback.ts +++ b/packages/journey-client/src/lib/callbacks/recaptcha-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.test.ts b/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.test.ts index 5ae3672b492..8690aa83da0 100644 --- a/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.test.ts @@ -3,7 +3,7 @@ * * recaptcha-enterprise-callback.test.ts * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.ts b/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.ts index 287da26e7c7..c3125bc581f 100644 --- a/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.ts +++ b/packages/journey-client/src/lib/callbacks/recaptcha-enterprise-callback.ts @@ -3,7 +3,7 @@ * * recaptcha-callback.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/redirect-callback.test.ts b/packages/journey-client/src/lib/callbacks/redirect-callback.test.ts index 89f61a01a6b..f2a7425140d 100644 --- a/packages/journey-client/src/lib/callbacks/redirect-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/redirect-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/redirect-callback.ts b/packages/journey-client/src/lib/callbacks/redirect-callback.ts index 71e836faff9..0f88b060020 100644 --- a/packages/journey-client/src/lib/callbacks/redirect-callback.ts +++ b/packages/journey-client/src/lib/callbacks/redirect-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/select-idp-callback.test.ts b/packages/journey-client/src/lib/callbacks/select-idp-callback.test.ts index ad9b868b9b6..95a88022b4a 100644 --- a/packages/journey-client/src/lib/callbacks/select-idp-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/select-idp-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/select-idp-callback.ts b/packages/journey-client/src/lib/callbacks/select-idp-callback.ts index 02b92a644f1..6821b0aac13 100644 --- a/packages/journey-client/src/lib/callbacks/select-idp-callback.ts +++ b/packages/journey-client/src/lib/callbacks/select-idp-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.test.ts b/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.test.ts index 8f31a45db64..bdf15855cd1 100644 --- a/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.ts b/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.ts index 4e918b9723e..34b5321a11c 100644 --- a/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.ts +++ b/packages/journey-client/src/lib/callbacks/suspended-text-output-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.test.ts b/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.test.ts index c04942f7869..1d18014c9ad 100644 --- a/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.ts b/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.ts index dc6cf4dfbd7..90e9a2594b8 100644 --- a/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.ts +++ b/packages/journey-client/src/lib/callbacks/terms-and-conditions-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/text-input-callback.test.ts b/packages/journey-client/src/lib/callbacks/text-input-callback.test.ts index 85a960993ab..e051da165ff 100644 --- a/packages/journey-client/src/lib/callbacks/text-input-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/text-input-callback.test.ts @@ -3,7 +3,7 @@ * * attribute-input-callback.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/text-input-callback.ts b/packages/journey-client/src/lib/callbacks/text-input-callback.ts index 3d64c21afba..fed13138632 100644 --- a/packages/journey-client/src/lib/callbacks/text-input-callback.ts +++ b/packages/journey-client/src/lib/callbacks/text-input-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2022 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/text-output-callback.test.ts b/packages/journey-client/src/lib/callbacks/text-output-callback.test.ts index 7d4c8a82632..96cb9595001 100644 --- a/packages/journey-client/src/lib/callbacks/text-output-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/text-output-callback.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/callbacks/text-output-callback.ts b/packages/journey-client/src/lib/callbacks/text-output-callback.ts index 98e67debb77..a6714e63be4 100644 --- a/packages/journey-client/src/lib/callbacks/text-output-callback.ts +++ b/packages/journey-client/src/lib/callbacks/text-output-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/validated-create-password-callback.test.ts b/packages/journey-client/src/lib/callbacks/validated-create-password-callback.test.ts index 62a1e4537dd..8ec317d1545 100644 --- a/packages/journey-client/src/lib/callbacks/validated-create-password-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/validated-create-password-callback.test.ts @@ -3,7 +3,7 @@ * * validated-create-password-callback.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/validated-create-password-callback.ts b/packages/journey-client/src/lib/callbacks/validated-create-password-callback.ts index 37cff4c9769..ef863ecb46e 100644 --- a/packages/journey-client/src/lib/callbacks/validated-create-password-callback.ts +++ b/packages/journey-client/src/lib/callbacks/validated-create-password-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/validated-create-username-callback.test.ts b/packages/journey-client/src/lib/callbacks/validated-create-username-callback.test.ts index 654156584ff..9da99b166ba 100644 --- a/packages/journey-client/src/lib/callbacks/validated-create-username-callback.test.ts +++ b/packages/journey-client/src/lib/callbacks/validated-create-username-callback.test.ts @@ -3,7 +3,7 @@ * * validated-create-username-callback.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/callbacks/validated-create-username-callback.ts b/packages/journey-client/src/lib/callbacks/validated-create-username-callback.ts index e3c9636a8ce..e824ffd62ec 100644 --- a/packages/journey-client/src/lib/callbacks/validated-create-username-callback.ts +++ b/packages/journey-client/src/lib/callbacks/validated-create-username-callback.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/client.store.ts b/packages/journey-client/src/lib/client.store.ts index 0f26e34d294..c3d63db8edc 100644 --- a/packages/journey-client/src/lib/client.store.ts +++ b/packages/journey-client/src/lib/client.store.ts @@ -13,18 +13,18 @@ import { isGenericError, isValidWellknownUrl, } from '@forgerock/sdk-utilities'; +import { wellknownApi } from '@forgerock/sdk-wellknown'; import { createStorage } from '@forgerock/storage'; -import * as Either from 'effect/Either'; +import * as Result from 'effect/Result'; -import { createJourneyStore } from './client.store.utils.js'; +import { createJourneyStore, toSdkStore } from './client.store.utils.js'; import { configSlice } from './config.slice.js'; import { journeyApi } from './journey.api.js'; import { createJourneyObject, parseJourneyResponse } from './journey.utils.js'; -import { wellknownApi } from './wellknown.api.js'; import type { CustomLogger, LogLevel } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import type { GenericError } from '@forgerock/sdk-types'; +import type { GenericError, SdkStore } from '@forgerock/sdk-types'; import type { Step } from '@forgerock/sdk-types'; import type { RedirectCallback } from './callbacks/redirect-callback.js'; @@ -35,6 +35,7 @@ import type { JourneyStep } from './step.utils.js'; /** The journey client instance returned by the `journey()` function. */ export interface JourneyClient { + store: SdkStore; subscribe: (listener: () => void) => () => void; start: (options?: StartParam) => Promise; next: (step: JourneyStep, options?: NextOptions) => Promise; @@ -115,7 +116,8 @@ export async function journey({ ); } - const store = createJourneyStore({ requestMiddleware, logger: log }); + const injectable = createJourneyStore({ requestMiddleware, logger: log }); + const store = injectable.store; if ('baseUrl' in config.serverConfig) { const { baseUrl } = config.serverConfig; @@ -182,13 +184,14 @@ export async function journey({ }); const self: JourneyClient = { + store: toSdkStore(injectable) as SdkStore, subscribe: store.subscribe, start: async (options?: StartParam) => { const response = await store.dispatch(journeyApi.endpoints.start.initiate(options)); - return Either.match(parseJourneyResponse(response), { - onLeft: (err): JourneyResult => err, - onRight: (step): JourneyResult => createJourneyObject(step), + return Result.match(parseJourneyResponse(response), { + onFailure: (err): JourneyResult => err, + onSuccess: (step): JourneyResult => createJourneyObject(step), }); }, @@ -197,9 +200,9 @@ export async function journey({ */ next: async (step: JourneyStep, options?: NextOptions) => { const response = await store.dispatch(journeyApi.endpoints.next.initiate({ step, options })); - return Either.match(parseJourneyResponse(response), { - onLeft: (err): JourneyResult => err, - onRight: (step): JourneyResult => createJourneyObject(step), + return Result.match(parseJourneyResponse(response), { + onFailure: (err): JourneyResult => err, + onSuccess: (step): JourneyResult => createJourneyObject(step), }); }, diff --git a/packages/journey-client/src/lib/client.store.utils.ts b/packages/journey-client/src/lib/client.store.utils.ts index 6439d9a4a5a..2b21a094186 100644 --- a/packages/journey-client/src/lib/client.store.utils.ts +++ b/packages/journey-client/src/lib/client.store.utils.ts @@ -5,20 +5,39 @@ * of the MIT license. See the LICENSE file for details. */ -import { combineReducers, configureStore } from '@reduxjs/toolkit'; +import { wellknownApi } from '@forgerock/sdk-wellknown'; +import { combineSlices, configureStore, createDynamicMiddleware } from '@reduxjs/toolkit'; import { configSlice } from './config.slice.js'; import { journeyApi } from './journey.api.js'; -import { wellknownApi } from './wellknown.api.js'; import type { logger as loggerFn } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; -const rootReducer = combineReducers({ - [journeyApi.reducerPath]: journeyApi.reducer, - [configSlice.name]: configSlice.reducer, - [wellknownApi.reducerPath]: wellknownApi.reducer, -}); +/** + * Root reducer built with combineSlices to support lazy injection. + * External slices (e.g. oidcApi) can be injected via rootReducer.inject(). + */ +export const rootReducer = combineSlices( + journeyApi, + configSlice, + wellknownApi, +).withLazyLoadedSlices(); + +export type RootState = ReturnType; + +/** + * Internal store shape carrying root reducer and dynamic middleware + * so that oidc-client can inject its reducers and middleware at init time. + */ +export interface InjectableStore { + readonly store: ReturnType>; + readonly rootReducer: typeof rootReducer; + readonly dynamicMiddleware: ReturnType; +} + +/** The inner Redux store type — used by effects that need dispatch/getState. */ +export type JourneyStore = InjectableStore['store']; export const createJourneyStore = ({ requestMiddleware, @@ -26,8 +45,10 @@ export const createJourneyStore = ({ }: { requestMiddleware?: RequestMiddleware[]; logger?: ReturnType; -}) => { - return configureStore({ +}): InjectableStore => { + const dynamicMiddleware = createDynamicMiddleware(); + + const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ @@ -40,8 +61,19 @@ export const createJourneyStore = ({ }, }) .concat(journeyApi.middleware) - .concat(wellknownApi.middleware), + .concat(wellknownApi.middleware) + .concat(dynamicMiddleware.middleware), }); + + return { store, rootReducer, dynamicMiddleware }; }; -export type RootState = ReturnType; +/** Cast InjectableStore to the opaque SdkStore for public API exposure. */ +export function toSdkStore(injectable: InjectableStore): object { + return injectable as unknown as object; +} + +/** Recover the InjectableStore from an opaque SdkStore handle. */ +export function fromSdkStore(sdkStore: object): InjectableStore { + return sdkStore as unknown as InjectableStore; +} diff --git a/packages/journey-client/src/lib/client.types.test-d.ts b/packages/journey-client/src/lib/client.types.test-d.ts index 5d3adc730e5..15c7e810502 100644 --- a/packages/journey-client/src/lib/client.types.test-d.ts +++ b/packages/journey-client/src/lib/client.types.test-d.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/device/device-profile.test.ts b/packages/journey-client/src/lib/device/device-profile.test.ts index 88367684ce9..4bd7df296b1 100644 --- a/packages/journey-client/src/lib/device/device-profile.test.ts +++ b/packages/journey-client/src/lib/device/device-profile.test.ts @@ -3,7 +3,7 @@ * * device-profile.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/device/device-profile.ts b/packages/journey-client/src/lib/device/device-profile.ts index 29d365ba2df..b502ca61faf 100644 --- a/packages/journey-client/src/lib/device/device-profile.ts +++ b/packages/journey-client/src/lib/device/device-profile.ts @@ -3,7 +3,7 @@ * * index.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/interfaces.ts b/packages/journey-client/src/lib/interfaces.ts index 6fa405f1d18..deb04b5ab49 100644 --- a/packages/journey-client/src/lib/interfaces.ts +++ b/packages/journey-client/src/lib/interfaces.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/journey.api.ts b/packages/journey-client/src/lib/journey.api.ts index 5ce1ce09c0b..ee221b4c63d 100644 --- a/packages/journey-client/src/lib/journey.api.ts +++ b/packages/journey-client/src/lib/journey.api.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/journey.utils.test.ts b/packages/journey-client/src/lib/journey.utils.test.ts index 88d5a4c5d8a..c2f64f718d1 100644 --- a/packages/journey-client/src/lib/journey.utils.test.ts +++ b/packages/journey-client/src/lib/journey.utils.test.ts @@ -70,8 +70,8 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Right'); - expect((result as { right: unknown }).right).toBe(body); + expect(result._tag).toBe('Success'); + expect((result as { success: unknown }).success).toBe(body); }); it('returns left(GenericError) when FetchBaseQueryError has numeric status but non-object body', () => { @@ -79,8 +79,8 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: unknown }).left).toMatchObject({ + expect(result._tag).toBe('Failure'); + expect((result as { failure: unknown }).failure).toMatchObject({ error: 'request_failed', type: 'unknown_error', }); @@ -91,8 +91,8 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: { message: string } }).left.message).toContain('Network error'); + expect(result._tag).toBe('Failure'); + expect((result as { failure: { message: string } }).failure.message).toContain('Network error'); }); it('returns left(GenericError) for PARSING_ERROR', () => { @@ -105,8 +105,10 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: { message: string } }).left.message).toContain('JSON parse error'); + expect(result._tag).toBe('Failure'); + expect((result as { failure: { message: string } }).failure.message).toContain( + 'JSON parse error', + ); }); it('returns left(GenericError) for TIMEOUT_ERROR', () => { @@ -114,8 +116,10 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: { message: string } }).left.message).toContain('Request timed out'); + expect(result._tag).toBe('Failure'); + expect((result as { failure: { message: string } }).failure.message).toContain( + 'Request timed out', + ); }); it('returns left(GenericError) for CUSTOM_ERROR', () => { @@ -123,8 +127,8 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: { message: string } }).left.message).toContain( + expect(result._tag).toBe('Failure'); + expect((result as { failure: { message: string } }).failure.message).toContain( 'Custom error occurred', ); }); @@ -134,8 +138,8 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data: undefined, error }); - expect(result._tag).toBe('Left'); - expect((result as { left: { message: string } }).left.message).toContain( + expect(result._tag).toBe('Failure'); + expect((result as { failure: { message: string } }).failure.message).toContain( 'Something went wrong', ); }); @@ -143,8 +147,8 @@ describe('parseJourneyResponse', () => { it('returns left(GenericError) when no data and no error', () => { const result = parseJourneyResponse({ data: undefined, error: undefined }); - expect(result._tag).toBe('Left'); - expect((result as { left: unknown }).left).toMatchObject({ + expect(result._tag).toBe('Failure'); + expect((result as { failure: unknown }).failure).toMatchObject({ error: 'no_response_data', type: 'unknown_error', }); @@ -155,7 +159,7 @@ describe('parseJourneyResponse', () => { const result = parseJourneyResponse({ data, error: undefined }); - expect(result._tag).toBe('Right'); - expect((result as { right: unknown }).right).toBe(data); + expect(result._tag).toBe('Success'); + expect((result as { success: unknown }).success).toBe(data); }); }); diff --git a/packages/journey-client/src/lib/journey.utils.ts b/packages/journey-client/src/lib/journey.utils.ts index 1ea88f88976..c04cc964bf2 100644 --- a/packages/journey-client/src/lib/journey.utils.ts +++ b/packages/journey-client/src/lib/journey.utils.ts @@ -1,12 +1,12 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ import { StepType } from '@forgerock/sdk-types'; -import * as Either from 'effect/Either'; +import * as Result from 'effect/Result'; import { createJourneyLoginFailure } from './login-failure.utils.js'; import { createJourneyLoginSuccess } from './login-success.utils.js'; @@ -70,7 +70,7 @@ export function createJourneyObject( export function parseJourneyResponse(res: { data?: Step; error?: FetchBaseQueryError | SerializedError; -}): Either.Either { +}): Result.Result { // https://redux-toolkit.js.org/rtk-query/api/fetchBaseQuery#signature // AM sends LoginFailure as a structured step body over HTTP 4xx — normalise both sources so the // left guards below only see genuine transport failures, never AM application responses. @@ -87,7 +87,7 @@ export function parseJourneyResponse(res: { // https://redux-toolkit.js.org/rtk-query/usage-with-typescript#type-safe-error-handling // Non-HTTP fetch failure (network down, CORS, etc.) — definitely left, never carries an AM body if (res.error && 'error' in res.error) { - return Either.left({ + return Result.fail({ error: 'request_failed', message: `Request failed: ${res.error.error}`, type: 'unknown_error', @@ -96,7 +96,7 @@ export function parseJourneyResponse(res: { // Redux serialization error — definitely left, never carries an AM body if (res.error && 'message' in res.error) { - return Either.left({ + return Result.fail({ error: 'request_failed', message: `Request failed: ${res.error.message ?? 'Unknown error'}`, type: 'unknown_error', @@ -105,7 +105,7 @@ export function parseJourneyResponse(res: { // HTTP error whose body was not a parseable AM step — left if (res.error && !stepData) { - return Either.left({ + return Result.fail({ error: 'request_failed', message: 'Request failed: Unknown error', type: 'unknown_error', @@ -114,7 +114,7 @@ export function parseJourneyResponse(res: { // No data from either source — left if (!stepData) { - return Either.left({ + return Result.fail({ error: 'no_response_data', message: 'No data received from server', type: 'unknown_error', @@ -122,5 +122,5 @@ export function parseJourneyResponse(res: { } // Every transport failure has been ruled out — this is a valid AM step - return Either.right(stepData); + return Result.succeed(stepData); } diff --git a/packages/journey-client/src/lib/login-failure.utils.ts b/packages/journey-client/src/lib/login-failure.utils.ts index ac0874ace2e..d5444adc6e8 100644 --- a/packages/journey-client/src/lib/login-failure.utils.ts +++ b/packages/journey-client/src/lib/login-failure.utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/login-success.utils.ts b/packages/journey-client/src/lib/login-success.utils.ts index e3e283d19c8..43684fbc094 100644 --- a/packages/journey-client/src/lib/login-success.utils.ts +++ b/packages/journey-client/src/lib/login-success.utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/policy/policy.test.ts b/packages/journey-client/src/lib/policy/policy.test.ts index b884d57fc98..cd9e3c78b5a 100644 --- a/packages/journey-client/src/lib/policy/policy.test.ts +++ b/packages/journey-client/src/lib/policy/policy.test.ts @@ -3,7 +3,7 @@ * * fr-policy.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/policy/policy.ts b/packages/journey-client/src/lib/policy/policy.ts index d78f769f349..f363a73eef5 100644 --- a/packages/journey-client/src/lib/policy/policy.ts +++ b/packages/journey-client/src/lib/policy/policy.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/qr-code/qr-code.test.ts b/packages/journey-client/src/lib/qr-code/qr-code.test.ts index cb028ca3081..961203710b0 100644 --- a/packages/journey-client/src/lib/qr-code/qr-code.test.ts +++ b/packages/journey-client/src/lib/qr-code/qr-code.test.ts @@ -3,7 +3,7 @@ * * index.test.ts * - * Copyright (c) 2024 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2024 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/qr-code/qr-code.ts b/packages/journey-client/src/lib/qr-code/qr-code.ts index 42f241b86a7..e82a2fc58ff 100644 --- a/packages/journey-client/src/lib/qr-code/qr-code.ts +++ b/packages/journey-client/src/lib/qr-code/qr-code.ts @@ -3,7 +3,7 @@ * * index.ts * - * Copyright (c) 2024 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2024 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/recovery-codes/recovery-codes.test.ts b/packages/journey-client/src/lib/recovery-codes/recovery-codes.test.ts index 8d659e4aff1..bba870283bb 100644 --- a/packages/journey-client/src/lib/recovery-codes/recovery-codes.test.ts +++ b/packages/journey-client/src/lib/recovery-codes/recovery-codes.test.ts @@ -3,7 +3,7 @@ * * recovery-codes.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/step.test.ts b/packages/journey-client/src/lib/step.test.ts index 7d3a52241c6..edd6c6c0b9c 100644 --- a/packages/journey-client/src/lib/step.test.ts +++ b/packages/journey-client/src/lib/step.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/step.utils.ts b/packages/journey-client/src/lib/step.utils.ts index 69f06564a98..95c1f7d3cfb 100644 --- a/packages/journey-client/src/lib/step.utils.ts +++ b/packages/journey-client/src/lib/step.utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/src/lib/webauthn/helpers.test.ts b/packages/journey-client/src/lib/webauthn/helpers.test.ts index afc691eca75..213c0ca3f7d 100644 --- a/packages/journey-client/src/lib/webauthn/helpers.test.ts +++ b/packages/journey-client/src/lib/webauthn/helpers.test.ts @@ -3,7 +3,7 @@ * * helpers.test.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/webauthn/helpers.ts b/packages/journey-client/src/lib/webauthn/helpers.ts index 23f3a56afdf..36181a82a70 100644 --- a/packages/journey-client/src/lib/webauthn/helpers.ts +++ b/packages/journey-client/src/lib/webauthn/helpers.ts @@ -3,7 +3,7 @@ * * helpers.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ diff --git a/packages/journey-client/src/lib/webauthn/webauthn.mock.data.ts b/packages/journey-client/src/lib/webauthn/webauthn.mock.data.ts index 898176ac442..dcb4809860d 100644 --- a/packages/journey-client/src/lib/webauthn/webauthn.mock.data.ts +++ b/packages/journey-client/src/lib/webauthn/webauthn.mock.data.ts @@ -3,7 +3,7 @@ * * fr-webauthn.mock.data.ts * - * Copyright (c) 2020 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2020 - 2025 Ping Identity Corporation. All rights reserved. * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ @@ -325,37 +325,6 @@ export const webAuthnAuthMetaCallback70StoredUsername = { ], }; -export const webAuthnAuthMetaCallback70Conditional = { - authId: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 ... ', - callbacks: [ - { - type: callbackType.MetadataCallback, - output: [ - { - name: 'data', - value: { - userVerification: 'preferred', - _type: 'WebAuthn', - challenge: 'OHmmFKfBhrUZKkuZJ84lf9N8TaRmQSjRdZyueeSIXAo=', - relyingPartyId: '', - allowCredentials: '', - timeout: '60000', - mediation: 'conditional', - }, - }, - ], - }, - { - type: callbackType.HiddenValueCallback, - output: [ - { name: 'value', value: 'false' }, - { name: 'id', value: 'webAuthnOutcome' }, - ], - input: [{ name: 'IDToken2', value: 'webAuthnOutcome' }], - }, - ], -}; - export const webAuthnAuthMetaCallbackJsonResponse = { authId: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoSW5kZXhWYWx1ZSI6IndlYmF1dGhuIiwib3RrIjoicXN1dTA0anNxZ2hmcGpubjFiM2IxdDh0NTQiLCJhdXRoSW5kZXhUeXBlIjoic2VydmljZSIsInJlYWxtIjoiLyIsInNlc3Npb25JZCI6IipBQUpUU1FBQ01ERUFCSFI1Y0dVQUNFcFhWRjlCVlZSSUFBSlRNUUFBKmV5SjBlWEFpT2lKS1YxUWlMQ0pqZEhraU9pSktWMVFpTENKaGJHY2lPaUpJVXpJMU5pSjkuWlhsS01HVllRV2xQYVVwTFZqRlJhVXhEU214aWJVMXBUMmxLUWsxVVNUUlJNRXBFVEZWb1ZFMXFWVEpKYVhkcFdWZDRia2xxYjJsYVIyeDVTVzR3TGk0M01qbDZSRXhsU0hwM1pXbFVPRll6VDB4cFgycEJMbGxpV1Y5WVl6WTJPVWxJU0MxT01VTk5Va05MZVROdFZFaHliVlJSVDJoV2VVSTBUVUUzYUVoRmFISjFTRU5SVWpWeWVsQnRZVzFpYlRNeFFqQlhSMlZxVEU5allUWllWMEUwTVROSlozRnVXV2gwV0hadlRHaE9VMkpDYUdkUlJFaGFSV1pLVmxaeWNsOTBTRUpJU1Y5elIyMVhNMEZYWm5wTk9WZElXblJMTm10ZmFITm9hemRNUTBkSVkwbzVhVGQ2Wnpob2FUbFROVm8wTVVkbk1rZFpXSFJJTnpoWlRGOVVaVTl5VWtOc1ozTlBkbDlWTWpGRFJ6STBReTFMWVRJNVMxRm9ibFYwTTNCVlozWldiamRCVUhWdWRFdEdaR2h6VERselJ6QlBTVnAwYzNoV1NqTXRPVmc1TmpSM2VrVldSV2w2Vnprek9XNTRlVm94VjNWVVgzWmpTRzFFV2t4eE0yWTJXamswVlVWTU5VNDJjMjVMTWs5U01XeDBOR3BrVld3eWVVMVRaVXR6YzJkb2VIRmlNMnhoZW1WQlVtMDBWM3BUVld4c1JFUTRVVVJuWDNoSFozSktlVmhQZWxCa1RWUnZYeTB0U1c0MFkxVjBTeloxTVdWSVkxOWhZbkZLTlhsRVpWcEpaM04yYkU5eE5qVTJkVU5KV0dzNU9GbElWMHBEWkhSR1MzcGtWV1k1ZG0xNlJIWk9iMmxXTlZnd2RXd3hiRzlTV0dOaFZtTkhVMDlaTlVGNFdITkJkSGd5UVhkVlVXUnViR0pmYTJodWN5MUhXblowZUVOM1lYRldlR2h1T1RsdVVWY3ljWFphUjNCTk1raFVPRzFMYUU5SVIyOVJOQzFWVkZrNVVWbDBNbGcwZGpaZlQzSk5kemxUZEdwSVl6RnRjMTkxVTI1VWVtVmpUR2RYUkVZdFVFNXNVM0J1Ymkxc1EyRlljRXREVmxsS1FVeDVUbWhoWDBJeGQwNTRSRzV0WW5vNVdYVjFXakZMYzFWTkxVZHJjVlJZYkY5c2JqUlBMVEpXVUhoTVFYSjFVblZOZW0xaVgxQndRMjlqY1d4T1Z6Sm1jWHBPV25seVlteE9RVEZXUkdaM04yYzJNMnhmTkhvd05UWkhlRXhOVjBOck5rOTZVQzFMY1RJMVlXTmxSa0ZQWWpGd1JtMXBkVGgzWW5kUGVITmtZa0ZLVW0xSWMxVlJWVzlQWm5aQlpURldORmcyUW5veGNFeG9SV3d0UzNGblkwMDBjMjluYTFab1YyRkhZWFpyVFUxSVFTNVlWRVpOV1d4R2F6bHFSV1V5VG5CamFIZDVZVzVuLmYyS2t1RlhnM05MUU1NbGNnMU1HU2Y2YTZQVmdJalhtUC1wcmJhQTNtTnciLCJleHAiOjE2MTM0OTc0OTksImlhdCI6MTYxMzQ5NzE5OX0.EuDmsY3C6I6vc_x7KlkW4rSQJY1FWevbGGmxkSu4HVU', diff --git a/packages/journey-client/src/lib/webauthn/webauthn.test.ts b/packages/journey-client/src/lib/webauthn/webauthn.test.ts index 603231ab646..6db4031d9cd 100644 --- a/packages/journey-client/src/lib/webauthn/webauthn.test.ts +++ b/packages/journey-client/src/lib/webauthn/webauthn.test.ts @@ -16,7 +16,6 @@ import { webAuthnAuthJSCallback70StoredUsername, webAuthnAuthJSCallback653, webAuthnAuthMetaCallback70, - webAuthnAuthMetaCallback70Conditional, webAuthnAuthMetaCallback70StoredUsername, webAuthnRegJSCallback70, webAuthnRegJSCallback70StoredUsername, @@ -25,60 +24,6 @@ import { webAuthnRegMetaCallback70StoredUsername, } from './webauthn.mock.data.js'; -describe('Test FRWebAuthn conditional mediation support', () => { - const originalPublicKeyCredential = globalThis.PublicKeyCredential; - - const withConditionalMediationAvailable = (available: boolean) => { - // jsdom has no PublicKeyCredential; install a minimal stub for these tests. - Object.defineProperty(globalThis, 'PublicKeyCredential', { - value: { - isConditionalMediationAvailable: vi.fn().mockResolvedValue(available), - }, - configurable: true, - writable: true, - }); - }; - - afterEach(() => { - Object.defineProperty(globalThis, 'PublicKeyCredential', { - value: originalPublicKeyCredential, - configurable: true, - writable: true, - }); - }); - - it('should return true when the browser supports conditional mediation and no step is given', async () => { - withConditionalMediationAvailable(true); - await expect(WebAuthn.isConditionalMediationSupported()).resolves.toBe(true); - }); - - it('should return false when the browser does not support conditional mediation and no step is given', async () => { - withConditionalMediationAvailable(false); - await expect(WebAuthn.isConditionalMediationSupported()).resolves.toBe(false); - }); - - it('should return false when the browser supports it but AM did not request conditional mediation', async () => { - // eslint-disable-next-line - const step = createJourneyStep(webAuthnAuthMetaCallback70 as any); - withConditionalMediationAvailable(true); - await expect(WebAuthn.isConditionalMediationSupported(step)).resolves.toBe(false); - }); - - it('should return true when the browser supports it and AM requested conditional mediation', async () => { - // eslint-disable-next-line - const step = createJourneyStep(webAuthnAuthMetaCallback70Conditional as any); - withConditionalMediationAvailable(true); - await expect(WebAuthn.isConditionalMediationSupported(step)).resolves.toBe(true); - }); - - it('should return false when AM requested conditional mediation but the browser does not support it', async () => { - // eslint-disable-next-line - const step = createJourneyStep(webAuthnAuthMetaCallback70Conditional as any); - withConditionalMediationAvailable(false); - await expect(WebAuthn.isConditionalMediationSupported(step)).resolves.toBe(false); - }); -}); - describe('Test FRWebAuthn class with 6.5.3 "Passwordless"', () => { it('should return Registration type with register text-output callbacks', () => { // eslint-disable-next-line diff --git a/packages/journey-client/src/lib/webauthn/webauthn.ts b/packages/journey-client/src/lib/webauthn/webauthn.ts index 89de0006ce4..8b2c8e111fd 100644 --- a/packages/journey-client/src/lib/webauthn/webauthn.ts +++ b/packages/journey-client/src/lib/webauthn/webauthn.ts @@ -66,9 +66,8 @@ type WebAuthnMetadata = WebAuthnAuthenticationMetadata | WebAuthnRegistrationMet * Conditional mediation is **server-driven** in this SDK via WebAuthn metadata (`meta.mediation`). * * ```js - * // Optional: feature-detect conditional UI before attempting. - * // Pass the step to also confirm AM requested conditional mediation. - * const supportsConditionalUI = await WebAuthn.isConditionalMediationSupported(step); + * // Optional: feature-detect conditional UI before attempting + * const supportsConditionalUI = await WebAuthn.isConditionalMediationSupported(); * * if (supportsConditionalUI) { * const controller = new AbortController(); @@ -127,29 +126,14 @@ export abstract class WebAuthn { /** * Determines if the browser supports conditional mediation. * - * When a step is provided, this also checks that the AM server requested - * conditional mediation via the WebAuthn metadata (`meta.mediation === 'conditional'`). - * - * @param step Optional step containing the WebAuthn metadata callback - * @return Whether conditional mediation is supported by the browser, - * and requested by AM when a step is provided + * @return Whether the browser supports conditional mediation */ - public static async isConditionalMediationSupported(step?: JourneyStep): Promise { - const isBrowserSupported = + public static async isConditionalMediationSupported(): Promise { + return ( typeof PublicKeyCredential !== 'undefined' && typeof PublicKeyCredential.isConditionalMediationAvailable === 'function' && - (await PublicKeyCredential.isConditionalMediationAvailable()); - - if (!step) { - return isBrowserSupported; - } - - const metadataCallback = this.getMetadataCallback(step); - const meta = metadataCallback?.getOutputValue('data') as - | WebAuthnAuthenticationMetadata - | undefined; - - return isBrowserSupported && meta?.mediation === 'conditional'; + (await PublicKeyCredential.isConditionalMediationAvailable()) + ); } /** diff --git a/packages/journey-client/src/lib/wellknown.api.ts b/packages/journey-client/src/lib/wellknown.api.ts deleted file mode 100644 index ad89ff6cd68..00000000000 --- a/packages/journey-client/src/lib/wellknown.api.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. - * - * This software may be modified and distributed under the terms - * of the MIT license. See the LICENSE file for details. - */ - -import { initWellknownQuery } from '@forgerock/sdk-oidc'; -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'; - -import type { WellknownResponse } from '@forgerock/sdk-types'; -import type { - FetchBaseQueryError, - FetchBaseQueryMeta, - QueryReturnValue, -} from '@reduxjs/toolkit/query'; - -/** - * RTK Query API for well-known endpoint discovery. - * - * Uses the `initWellknownQuery` builder pattern from `@forgerock/sdk-oidc`. - * The builder constructs the request and validates the response; - * `fetchBaseQuery` handles the HTTP transport through RTK Query's pipeline. - */ -export const wellknownApi = createApi({ - reducerPath: 'wellknown', - baseQuery: fetchBaseQuery(), - endpoints: (builder) => ({ - configuration: builder.query({ - queryFn: async (url, _api, _extra, baseQuery) => { - const result = await initWellknownQuery(url).applyQuery(async (req) => { - const queryResult = await baseQuery(req); - return queryResult as QueryReturnValue; - }); - return result as QueryReturnValue< - WellknownResponse, - FetchBaseQueryError, - FetchBaseQueryMeta - >; - }, - }), - }), -}); diff --git a/packages/journey-client/src/lib/wellknown.utils.test.ts b/packages/journey-client/src/lib/wellknown.utils.test.ts index 85007e8d5a3..48c6c99a96b 100644 --- a/packages/journey-client/src/lib/wellknown.utils.test.ts +++ b/packages/journey-client/src/lib/wellknown.utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/journey-client/tsconfig.lib.json b/packages/journey-client/tsconfig.lib.json index ca3f899b8dc..ae23b14b069 100644 --- a/packages/journey-client/tsconfig.lib.json +++ b/packages/journey-client/tsconfig.lib.json @@ -35,6 +35,9 @@ }, { "path": "../sdk-effects/logger/tsconfig.lib.json" + }, + { + "path": "../sdk-effects/wellknown/tsconfig.lib.json" } ] } diff --git a/packages/oidc-client/api-report/oidc-client.api.md b/packages/oidc-client/api-report/oidc-client.api.md index ec98f007181..fbac9c99dc2 100644 --- a/packages/oidc-client/api-report/oidc-client.api.md +++ b/packages/oidc-client/api-report/oidc-client.api.md @@ -1,668 +1,420 @@ -## API Report File for "@forgerock/oidc-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { BaseQueryFn } from '@reduxjs/toolkit/query'; -import { BrowserStorageConfig } from '@forgerock/storage'; -import { CombinedState } from '@reduxjs/toolkit/query'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import { CustomStorageConfig } from '@forgerock/storage'; -import { CustomStorageObject } from '@forgerock/sdk-types'; -import { EnhancedStore } from '@reduxjs/toolkit'; -import { FetchArgs } from '@reduxjs/toolkit/query'; -import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'; -import { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; -import { GenericError } from '@forgerock/sdk-types'; -import { GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; -import type { JWTPayload } from 'jose'; -import type { logger } from '@forgerock/sdk-logger'; -import { LogLevel } from '@forgerock/sdk-logger'; -import { LogMessage } from '@forgerock/sdk-logger'; -import { makeOidcConfig } from '@forgerock/sdk-utilities'; -import { MutationDefinition } from '@reduxjs/toolkit/query'; -import { OidcConfig } from '@forgerock/sdk-types'; -import { QueryDefinition } from '@reduxjs/toolkit/query'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { ResponseType as ResponseType_2 } from '@forgerock/sdk-types'; -import { StorageConfig } from '@forgerock/storage'; -import { StoreEnhancer } from '@reduxjs/toolkit'; -import { ThunkDispatch } from '@reduxjs/toolkit'; -import { Tuple } from '@reduxjs/toolkit'; -import { UnknownAction } from '@reduxjs/toolkit'; -import { Unsubscribe } from '@reduxjs/toolkit'; -import { WellknownResponse } from '@forgerock/sdk-types'; - -export { ActionTypes }; - -// @public (undocumented) -export type AppDispatch = ReturnType; - -// @public (undocumented) -export interface AuthorizationError { - // (undocumented) - error: string; - // (undocumented) - error_description: string; - // (undocumented) - redirectUrl?: string; - // (undocumented) - type: 'auth_error' | 'argument_error' | 'network_error' | 'unknown_error' | 'wellknown_error'; -} - -// @public (undocumented) -export interface AuthorizationSuccess { - // (undocumented) - code: string; - // (undocumented) - state: string; -} - -// @public (undocumented) -export interface AuthorizeErrorResponse { - // (undocumented) - code?: string; - // (undocumented) - details?: [ - { - code: string; - message: string; - }, - ]; - // (undocumented) - id?: string; - // (undocumented) - message?: string; -} - -// @public (undocumented) -export interface AuthorizeSuccessResponse { - // (undocumented) - authorizeResponse?: { - code: string; - state: string; - }; - // (undocumented) - createdAt?: string; - // (undocumented) - _embedded?: { - [key: string]: unknown; - }; - // (undocumented) - environment?: { - id: string; - }; - // (undocumented) - expiresAt?: string; - // (undocumented) - id?: string; - // (undocumented) - _links?: { - [key: string]: { - href: string; - }; - }; - // (undocumented) - resumeUrl?: string; - // (undocumented) - session?: { - id: string; - }; - // (undocumented) - status?: string; -} - -export { BrowserStorageConfig }; - -// @public (undocumented) -export type BuildAuthorizationData = [string, GetAuthorizationUrlOptions]; - -// @public (undocumented) -export type ClientStore = ReturnType; - -// @public -export function createClientStore(input: { - requestMiddleware?: RequestMiddleware[]; - logger?: ReturnType; -}): EnhancedStore< - { - oidc: CombinedState< - { - authorizeFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - AuthorizeSuccessResponse, - 'oidc', - unknown - >; - par: MutationDefinition< - { - endpoint: string; - body: URLSearchParams; - }, - BaseQueryFn, - never, - PushAuthorizationResponse, - 'oidc', - unknown - >; - sessionCheckIframe: MutationDefinition< - { - url: string; - responseType: SessionCheckResponseType; - }, - BaseQueryFn, - never, - { - params: Record; - }, - 'oidc', - unknown - >; - sessionCheckFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - { - status: 204; - }, - 'oidc', - unknown - >; - authorizeIframe: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - AuthorizationSuccess, - 'oidc', - unknown - >; - endSession: MutationDefinition< - { - idToken: string; - endpoint: string; - signOutRedirectUri?: string; - }, - BaseQueryFn, - never, - null, - 'oidc', - unknown - >; - exchange: MutationDefinition< - { - code: string; - config: OidcConfig; - endpoint: string; - verifier?: string; - }, - BaseQueryFn, - never, - TokenExchangeResponse, - 'oidc', - unknown - >; - revoke: MutationDefinition< - { - accessToken: string; - clientId?: string; - endpoint: string; - }, - BaseQueryFn, - never, - object, - 'oidc', - unknown - >; - userInfo: MutationDefinition< - { - accessToken: string; - endpoint: string; - }, - BaseQueryFn, - never, - UserInfoResponse, - 'oidc', - unknown - >; - }, - never, - 'oidc' - >; - wellknown: CombinedState< - { - configuration: QueryDefinition< - string, - BaseQueryFn, - never, - WellknownResponse, - 'wellknown', - unknown - >; - }, - never, - 'wellknown' - >; - }, - UnknownAction, - Tuple< - [ - StoreEnhancer<{ - dispatch: ThunkDispatch< - { - oidc: CombinedState< - { - authorizeFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - AuthorizeSuccessResponse, - 'oidc', - unknown - >; - par: MutationDefinition< - { - endpoint: string; - body: URLSearchParams; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - PushAuthorizationResponse, - 'oidc', - unknown - >; - sessionCheckIframe: MutationDefinition< - { - url: string; - responseType: SessionCheckResponseType; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - { - params: Record; - }, - 'oidc', - unknown - >; - sessionCheckFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - { - status: 204; - }, - 'oidc', - unknown - >; - authorizeIframe: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - AuthorizationSuccess, - 'oidc', - unknown - >; - endSession: MutationDefinition< - { - idToken: string; - endpoint: string; - signOutRedirectUri?: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - null, - 'oidc', - unknown - >; - exchange: MutationDefinition< - { - code: string; - config: OidcConfig; - endpoint: string; - verifier?: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - TokenExchangeResponse, - 'oidc', - unknown - >; - revoke: MutationDefinition< - { - accessToken: string; - clientId?: string; - endpoint: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - object, - 'oidc', - unknown - >; - userInfo: MutationDefinition< - { - accessToken: string; - endpoint: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - UserInfoResponse, - 'oidc', - unknown - >; - }, - never, - 'oidc' - >; - wellknown: CombinedState< - { - configuration: QueryDefinition< - string, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - WellknownResponse, - 'wellknown', - unknown - >; - }, - never, - 'wellknown' - >; - }, - { - requestMiddleware: RequestMiddleware[] | undefined; - logger: - | { - changeLevel: (level: LogLevel) => void; - error: (...args: LogMessage[]) => void; - warn: (...args: LogMessage[]) => void; - info: (...args: LogMessage[]) => void; - debug: (...args: LogMessage[]) => void; - } - | undefined; - }, - UnknownAction - >; - }>, - StoreEnhancer, - ] - > ->; - -export { CustomLogger }; - -export { CustomStorageConfig }; - -export { CustomStorageObject }; - -export { GenericError }; - -export { GetAuthorizationUrlOptions }; - -// @public (undocumented) -export interface GetTokensOptions { - // (undocumented) - authorizeOptions?: GetAuthorizationUrlOptions; - // (undocumented) - backgroundRenew?: boolean; - // (undocumented) - forceRenew?: boolean; - // (undocumented) - storageOptions?: Partial; -} - -export { LogLevel }; - -// @public (undocumented) -export type LogoutErrorResult = { - error: string; - sessionResponse: GenericError | null; - revokeResponse: GenericError | null; - deleteResponse: GenericError | null; -}; - -// @public (undocumented) -export type LogoutSuccessResult = RevokeSuccessResult & { - sessionResponse: null; -}; - -export { makeOidcConfig }; - -// @public (undocumented) -export interface OauthTokens { - // (undocumented) - accessToken: string; - // (undocumented) - expiresAt?: number; - // (undocumented) - expiryTimestamp?: number; - // (undocumented) - idToken: string; - // (undocumented) - refreshToken?: string; -} - -// @public -export function oidc(input: { - config: OidcConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; - storage?: Partial; -}): Promise< - | { - error: string; - type: string; - subscribe?: undefined; - authorize?: undefined; - token?: undefined; - user?: undefined; - } - | { - subscribe: (listener: () => void) => Unsubscribe; - authorize: { - url: (options?: GetAuthorizationUrlOptions) => Promise; - background: ( - options?: GetAuthorizationUrlOptions, - ) => Promise; - }; - token: { - exchange: ( - code: string, - state: string, - options?: Partial, - ) => Promise; - get: ( - options?: GetTokensOptions, - ) => Promise; - revoke: () => Promise; - }; - user: { - info: () => Promise; - logout: () => Promise; - session: (options?: SessionCheckOptions) => Promise; - }; - error?: undefined; - type?: undefined; - } ->; - -// @public (undocumented) -export type OidcClient = Awaited>; - -export { OidcConfig }; - -// @public (undocumented) -export type OptionalAuthorizeOptions = Partial; - -// @public (undocumented) -export interface PushAuthorizationResponse { - // (undocumented) - expires_in: number; - // (undocumented) - request_uri: string; -} - -export { RequestMiddleware }; - -export { ResponseType_2 as ResponseType }; - -// @public (undocumented) -export type RevokeErrorResult = { - error: string; - revokeResponse: GenericError | null; - deleteResponse: GenericError | null; -}; - -// @public (undocumented) -export type RevokeSuccessResult = { - revokeResponse: null; - deleteResponse: null; -}; - -// @public (undocumented) -export type RootState = ReturnType; - -// @public -export interface SessionCheckOptions { - redirectUri?: string; - responseType?: SessionCheckResponseType; - scope?: string; - subject?: string; -} - -// @public (undocumented) -export type SessionCheckResponseType = 'id_token' | 'none'; - -// @public (undocumented) -export type SessionCheckSuccess = { - responseType: SessionCheckResponseType; - claims?: JWTPayload; -}; - -export { StorageConfig }; - -// @public (undocumented) -export interface TokenExchangeErrorResponse { - // (undocumented) - error: string; - // (undocumented) - message: string; - // (undocumented) - type: 'exchange_error' | 'network_error' | 'state_error' | 'unknown_error'; -} - -// @public (undocumented) -export interface TokenExchangeResponse { - // (undocumented) - access_token: string; - // (undocumented) - expires_in?: number; - // (undocumented) - id_token: string; - // (undocumented) - refresh_token?: string; - // (undocumented) - scope?: string; - // (undocumented) - token_type?: string; -} - -// @public (undocumented) -export interface TokenRequestOptions { - // (undocumented) - code: string; - // (undocumented) - config: OidcConfig; - // (undocumented) - endpoint: string; - // (undocumented) - verifier?: string; -} - -// @public (undocumented) -export type UserInfoResponse = { - sub: string; - [key: string]: unknown; -}; - -export { WellknownResponse }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/oidc-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { BaseQueryFn } from '@reduxjs/toolkit/query'; +import { CombinedState } from '@reduxjs/toolkit/query'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import { EnhancedStore } from '@reduxjs/toolkit'; +import { FetchArgs } from '@reduxjs/toolkit/query'; +import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'; +import { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; +import { GenericError } from '@forgerock/sdk-types'; +import { GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; +import type { JWTPayload } from 'jose'; +import { logger } from '@forgerock/sdk-logger'; +import { LogLevel } from '@forgerock/sdk-logger'; +import { LogMessage } from '@forgerock/sdk-logger'; +import { makeOidcConfig } from '@forgerock/sdk-utilities'; +import { MutationDefinition } from '@reduxjs/toolkit/query'; +import { OidcConfig } from '@forgerock/sdk-types'; +import { QueryDefinition } from '@reduxjs/toolkit/query'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import { ResponseType as ResponseType_2 } from '@forgerock/sdk-types'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { StorageConfig } from '@forgerock/storage'; +import { StoreEnhancer } from '@reduxjs/toolkit'; +import { ThunkDispatch } from '@reduxjs/toolkit'; +import { Tuple } from '@reduxjs/toolkit'; +import { UnknownAction } from '@reduxjs/toolkit'; +import { Unsubscribe } from '@reduxjs/toolkit'; +import { WellknownResponse } from '@forgerock/sdk-types'; + +export { ActionTypes } + +// @public (undocumented) +export type AppDispatch = ReturnType; + +// @public (undocumented) +export interface AuthorizationError { + // (undocumented) + error: string; + // (undocumented) + error_description: string; + // (undocumented) + redirectUrl?: string; + // (undocumented) + type: 'auth_error' | 'argument_error' | 'network_error' | 'unknown_error' | 'wellknown_error'; +} + +// @public (undocumented) +export interface AuthorizationSuccess { + // (undocumented) + code: string; + // (undocumented) + state: string; +} + +// @public (undocumented) +export interface AuthorizeErrorResponse { + // (undocumented) + code?: string; + // (undocumented) + details?: [ + { + code: string; + message: string; + } + ]; + // (undocumented) + id?: string; + // (undocumented) + message?: string; +} + +// @public (undocumented) +export interface AuthorizeSuccessResponse { + // (undocumented) + authorizeResponse?: { + code: string; + state: string; + }; + // (undocumented) + createdAt?: string; + // (undocumented) + _embedded?: { + [key: string]: unknown; + }; + // (undocumented) + environment?: { + id: string; + }; + // (undocumented) + expiresAt?: string; + // (undocumented) + id?: string; + // (undocumented) + _links?: { + [key: string]: { + href: string; + }; + }; + // (undocumented) + resumeUrl?: string; + // (undocumented) + session?: { + id: string; + }; + // (undocumented) + status?: string; +} + +// @public (undocumented) +export type BuildAuthorizationData = [string, GetAuthorizationUrlOptions]; + +// @public (undocumented) +export type ClientStore = ReturnType; + +// @public +export function createClientStore(input: { + requestMiddleware?: RequestMiddleware[]; + logger?: ReturnType; +}): EnhancedStore< { +oidc: CombinedState< { +authorizeFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizeSuccessResponse, "oidc", unknown>; +par: MutationDefinition< { +endpoint: string; +body: URLSearchParams; +}, BaseQueryFn, never, PushAuthorizationResponse, "oidc", unknown>; +sessionCheckIframe: MutationDefinition< { +url: string; +responseType: SessionCheckResponseType; +}, BaseQueryFn, never, { +params: Record; +}, "oidc", unknown>; +sessionCheckFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, { +status: 204; +}, "oidc", unknown>; +authorizeIframe: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizationSuccess, "oidc", unknown>; +endSession: MutationDefinition< { +idToken: string; +endpoint: string; +signOutRedirectUri?: string; +}, BaseQueryFn, never, null, "oidc", unknown>; +exchange: MutationDefinition< { +code: string; +config: OidcConfig; +endpoint: string; +verifier?: string; +}, BaseQueryFn, never, TokenExchangeResponse, "oidc", unknown>; +revoke: MutationDefinition< { +accessToken: string; +clientId?: string; +endpoint: string; +}, BaseQueryFn, never, object, "oidc", unknown>; +userInfo: MutationDefinition< { +accessToken: string; +endpoint: string; +}, BaseQueryFn, never, UserInfoResponse, "oidc", unknown>; +}, never, "oidc">; +wellknown: CombinedState< { +configuration: QueryDefinition, never, WellknownResponse, "wellknown", unknown>; +}, never, "wellknown">; +}, UnknownAction, Tuple<[StoreEnhancer< { +dispatch: ThunkDispatch< { +oidc: CombinedState< { +authorizeFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizeSuccessResponse, "oidc", unknown>; +par: MutationDefinition< { +endpoint: string; +body: URLSearchParams; +}, BaseQueryFn, never, PushAuthorizationResponse, "oidc", unknown>; +sessionCheckIframe: MutationDefinition< { +url: string; +responseType: SessionCheckResponseType; +}, BaseQueryFn, never, { +params: Record; +}, "oidc", unknown>; +sessionCheckFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, { +status: 204; +}, "oidc", unknown>; +authorizeIframe: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizationSuccess, "oidc", unknown>; +endSession: MutationDefinition< { +idToken: string; +endpoint: string; +signOutRedirectUri?: string; +}, BaseQueryFn, never, null, "oidc", unknown>; +exchange: MutationDefinition< { +code: string; +config: OidcConfig; +endpoint: string; +verifier?: string; +}, BaseQueryFn, never, TokenExchangeResponse, "oidc", unknown>; +revoke: MutationDefinition< { +accessToken: string; +clientId?: string; +endpoint: string; +}, BaseQueryFn, never, object, "oidc", unknown>; +userInfo: MutationDefinition< { +accessToken: string; +endpoint: string; +}, BaseQueryFn, never, UserInfoResponse, "oidc", unknown>; +}, never, "oidc">; +wellknown: CombinedState< { +configuration: QueryDefinition, never, WellknownResponse, "wellknown", unknown>; +}, never, "wellknown">; +}, { +requestMiddleware: RequestMiddleware[] | undefined; +logger: { +changeLevel: (level: LogLevel) => void; +error: (...args: LogMessage[]) => void; +warn: (...args: LogMessage[]) => void; +info: (...args: LogMessage[]) => void; +debug: (...args: LogMessage[]) => void; +} | undefined; +}, UnknownAction>; +}>, StoreEnhancer]>>; + +export { CustomLogger } + +export { GenericError } + +export { GetAuthorizationUrlOptions } + +// @public (undocumented) +export interface GetTokensOptions { + // (undocumented) + authorizeOptions?: GetAuthorizationUrlOptions; + // (undocumented) + backgroundRenew?: boolean; + // (undocumented) + forceRenew?: boolean; + // (undocumented) + storageOptions?: Partial; +} + +export { LogLevel } + +// @public (undocumented) +export type LogoutErrorResult = { + error: string; + sessionResponse: GenericError | null; + revokeResponse: GenericError | null; + deleteResponse: GenericError | null; +}; + +// @public (undocumented) +export type LogoutSuccessResult = RevokeSuccessResult & { + sessionResponse: null; +}; + +export { makeOidcConfig } + +// @public (undocumented) +export interface OauthTokens { + // (undocumented) + accessToken: string; + // (undocumented) + expiresAt?: number; + // (undocumented) + expiryTimestamp?: number; + // (undocumented) + idToken: string; + // (undocumented) + refreshToken?: string; +} + +// @public +export function oidc(input: { + config: OidcConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; + storage?: Partial; +}, sharedStore?: SdkStore): Promise<{ + error: string; + type: string; + subscribe?: undefined; + authorize?: undefined; + token?: undefined; + user?: undefined; +} | { + subscribe: (listener: () => void) => Unsubscribe; + authorize: { + url: (options?: GetAuthorizationUrlOptions) => Promise; + background: (options?: GetAuthorizationUrlOptions) => Promise; + }; + token: { + exchange: (code: string, state: string, options?: Partial) => Promise; + get: (options?: GetTokensOptions) => Promise; + revoke: () => Promise; + }; + user: { + info: () => Promise; + logout: () => Promise; + session: (options?: SessionCheckOptions) => Promise; + }; + error?: undefined; + type?: undefined; +}>; + +// @public (undocumented) +export type OidcClient = Awaited>; + +export { OidcConfig } + +// @public (undocumented) +export type OptionalAuthorizeOptions = Partial; + +// @public (undocumented) +export interface PushAuthorizationResponse { + // (undocumented) + expires_in: number; + // (undocumented) + request_uri: string; +} + +export { RequestMiddleware } + +export { ResponseType_2 as ResponseType } + +// @public (undocumented) +export type RevokeErrorResult = { + error: string; + revokeResponse: GenericError | null; + deleteResponse: GenericError | null; +}; + +// @public (undocumented) +export type RevokeSuccessResult = { + revokeResponse: null; + deleteResponse: null; +}; + +// @public (undocumented) +export type RootState = ReturnType; + +// @public +export interface SessionCheckOptions { + redirectUri?: string; + responseType?: SessionCheckResponseType; + scope?: string; + subject?: string; +} + +// @public (undocumented) +export type SessionCheckResponseType = 'id_token' | 'none'; + +// @public (undocumented) +export type SessionCheckSuccess = { + responseType: SessionCheckResponseType; + claims?: JWTPayload; +}; + +export { StorageConfig } + +// @public (undocumented) +export interface TokenExchangeErrorResponse { + // (undocumented) + error: string; + // (undocumented) + message: string; + // (undocumented) + type: 'exchange_error' | 'network_error' | 'state_error' | 'unknown_error'; +} + +// @public (undocumented) +export interface TokenExchangeResponse { + // (undocumented) + access_token: string; + // (undocumented) + expires_in?: number; + // (undocumented) + id_token: string; + // (undocumented) + refresh_token?: string; + // (undocumented) + scope?: string; + // (undocumented) + token_type?: string; +} + +// @public (undocumented) +export interface TokenRequestOptions { + // (undocumented) + code: string; + // (undocumented) + config: OidcConfig; + // (undocumented) + endpoint: string; + // (undocumented) + verifier?: string; +} + +// @public (undocumented) +export type UserInfoResponse = { + sub: string; + [key: string]: unknown; +}; + +export { WellknownResponse } + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/oidc-client/api-report/oidc-client.types.api.md b/packages/oidc-client/api-report/oidc-client.types.api.md index 6157741a15d..d9fe8e87bda 100644 --- a/packages/oidc-client/api-report/oidc-client.types.api.md +++ b/packages/oidc-client/api-report/oidc-client.types.api.md @@ -1,665 +1,417 @@ -## API Report File for "@forgerock/oidc-client" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionTypes } from '@forgerock/sdk-request-middleware'; -import { BaseQueryFn } from '@reduxjs/toolkit/query'; -import { BrowserStorageConfig } from '@forgerock/storage'; -import { CombinedState } from '@reduxjs/toolkit/query'; -import { CustomLogger } from '@forgerock/sdk-logger'; -import { CustomStorageConfig } from '@forgerock/storage'; -import { CustomStorageObject } from '@forgerock/sdk-types'; -import { EnhancedStore } from '@reduxjs/toolkit'; -import { FetchArgs } from '@reduxjs/toolkit/query'; -import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'; -import { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; -import { GenericError } from '@forgerock/sdk-types'; -import { GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; -import type { JWTPayload } from 'jose'; -import type { logger } from '@forgerock/sdk-logger'; -import { LogLevel } from '@forgerock/sdk-logger'; -import { LogMessage } from '@forgerock/sdk-logger'; -import { MutationDefinition } from '@reduxjs/toolkit/query'; -import { OidcConfig } from '@forgerock/sdk-types'; -import { QueryDefinition } from '@reduxjs/toolkit/query'; -import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import { ResponseType as ResponseType_2 } from '@forgerock/sdk-types'; -import { StorageConfig } from '@forgerock/storage'; -import { StoreEnhancer } from '@reduxjs/toolkit'; -import { ThunkDispatch } from '@reduxjs/toolkit'; -import { Tuple } from '@reduxjs/toolkit'; -import { UnknownAction } from '@reduxjs/toolkit'; -import { Unsubscribe } from '@reduxjs/toolkit'; -import { WellknownResponse } from '@forgerock/sdk-types'; - -export { ActionTypes }; - -// @public (undocumented) -export type AppDispatch = ReturnType; - -// @public (undocumented) -export interface AuthorizationError { - // (undocumented) - error: string; - // (undocumented) - error_description: string; - // (undocumented) - redirectUrl?: string; - // (undocumented) - type: 'auth_error' | 'argument_error' | 'network_error' | 'unknown_error' | 'wellknown_error'; -} - -// @public (undocumented) -export interface AuthorizationSuccess { - // (undocumented) - code: string; - // (undocumented) - state: string; -} - -// @public (undocumented) -export interface AuthorizeErrorResponse { - // (undocumented) - code?: string; - // (undocumented) - details?: [ - { - code: string; - message: string; - }, - ]; - // (undocumented) - id?: string; - // (undocumented) - message?: string; -} - -// @public (undocumented) -export interface AuthorizeSuccessResponse { - // (undocumented) - authorizeResponse?: { - code: string; - state: string; - }; - // (undocumented) - createdAt?: string; - // (undocumented) - _embedded?: { - [key: string]: unknown; - }; - // (undocumented) - environment?: { - id: string; - }; - // (undocumented) - expiresAt?: string; - // (undocumented) - id?: string; - // (undocumented) - _links?: { - [key: string]: { - href: string; - }; - }; - // (undocumented) - resumeUrl?: string; - // (undocumented) - session?: { - id: string; - }; - // (undocumented) - status?: string; -} - -export { BrowserStorageConfig }; - -// @public (undocumented) -export type BuildAuthorizationData = [string, GetAuthorizationUrlOptions]; - -// @public (undocumented) -export type ClientStore = ReturnType; - -// @public -export function createClientStore(input: { - requestMiddleware?: RequestMiddleware[]; - logger?: ReturnType; -}): EnhancedStore< - { - oidc: CombinedState< - { - authorizeFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - AuthorizeSuccessResponse, - 'oidc', - unknown - >; - par: MutationDefinition< - { - endpoint: string; - body: URLSearchParams; - }, - BaseQueryFn, - never, - PushAuthorizationResponse, - 'oidc', - unknown - >; - sessionCheckIframe: MutationDefinition< - { - url: string; - responseType: SessionCheckResponseType; - }, - BaseQueryFn, - never, - { - params: Record; - }, - 'oidc', - unknown - >; - sessionCheckFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - { - status: 204; - }, - 'oidc', - unknown - >; - authorizeIframe: MutationDefinition< - { - url: string; - }, - BaseQueryFn, - never, - AuthorizationSuccess, - 'oidc', - unknown - >; - endSession: MutationDefinition< - { - idToken: string; - endpoint: string; - signOutRedirectUri?: string; - }, - BaseQueryFn, - never, - null, - 'oidc', - unknown - >; - exchange: MutationDefinition< - { - code: string; - config: OidcConfig; - endpoint: string; - verifier?: string; - }, - BaseQueryFn, - never, - TokenExchangeResponse, - 'oidc', - unknown - >; - revoke: MutationDefinition< - { - accessToken: string; - clientId?: string; - endpoint: string; - }, - BaseQueryFn, - never, - object, - 'oidc', - unknown - >; - userInfo: MutationDefinition< - { - accessToken: string; - endpoint: string; - }, - BaseQueryFn, - never, - UserInfoResponse, - 'oidc', - unknown - >; - }, - never, - 'oidc' - >; - wellknown: CombinedState< - { - configuration: QueryDefinition< - string, - BaseQueryFn, - never, - WellknownResponse, - 'wellknown', - unknown - >; - }, - never, - 'wellknown' - >; - }, - UnknownAction, - Tuple< - [ - StoreEnhancer<{ - dispatch: ThunkDispatch< - { - oidc: CombinedState< - { - authorizeFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - AuthorizeSuccessResponse, - 'oidc', - unknown - >; - par: MutationDefinition< - { - endpoint: string; - body: URLSearchParams; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - PushAuthorizationResponse, - 'oidc', - unknown - >; - sessionCheckIframe: MutationDefinition< - { - url: string; - responseType: SessionCheckResponseType; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - { - params: Record; - }, - 'oidc', - unknown - >; - sessionCheckFetch: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - { - status: 204; - }, - 'oidc', - unknown - >; - authorizeIframe: MutationDefinition< - { - url: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - AuthorizationSuccess, - 'oidc', - unknown - >; - endSession: MutationDefinition< - { - idToken: string; - endpoint: string; - signOutRedirectUri?: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - null, - 'oidc', - unknown - >; - exchange: MutationDefinition< - { - code: string; - config: OidcConfig; - endpoint: string; - verifier?: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - TokenExchangeResponse, - 'oidc', - unknown - >; - revoke: MutationDefinition< - { - accessToken: string; - clientId?: string; - endpoint: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - object, - 'oidc', - unknown - >; - userInfo: MutationDefinition< - { - accessToken: string; - endpoint: string; - }, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - UserInfoResponse, - 'oidc', - unknown - >; - }, - never, - 'oidc' - >; - wellknown: CombinedState< - { - configuration: QueryDefinition< - string, - BaseQueryFn< - string | FetchArgs, - unknown, - FetchBaseQueryError, - {}, - FetchBaseQueryMeta - >, - never, - WellknownResponse, - 'wellknown', - unknown - >; - }, - never, - 'wellknown' - >; - }, - { - requestMiddleware: RequestMiddleware[] | undefined; - logger: - | { - changeLevel: (level: LogLevel) => void; - error: (...args: LogMessage[]) => void; - warn: (...args: LogMessage[]) => void; - info: (...args: LogMessage[]) => void; - debug: (...args: LogMessage[]) => void; - } - | undefined; - }, - UnknownAction - >; - }>, - StoreEnhancer, - ] - > ->; - -export { CustomLogger }; - -export { CustomStorageConfig }; - -export { CustomStorageObject }; - -export { GenericError }; - -export { GetAuthorizationUrlOptions }; - -// @public (undocumented) -export interface GetTokensOptions { - // (undocumented) - authorizeOptions?: GetAuthorizationUrlOptions; - // (undocumented) - backgroundRenew?: boolean; - // (undocumented) - forceRenew?: boolean; - // (undocumented) - storageOptions?: Partial; -} - -export { LogLevel }; - -// @public (undocumented) -export type LogoutErrorResult = { - error: string; - sessionResponse: GenericError | null; - revokeResponse: GenericError | null; - deleteResponse: GenericError | null; -}; - -// @public (undocumented) -export type LogoutSuccessResult = RevokeSuccessResult & { - sessionResponse: null; -}; - -// @public (undocumented) -export interface OauthTokens { - // (undocumented) - accessToken: string; - // (undocumented) - expiresAt?: number; - // (undocumented) - expiryTimestamp?: number; - // (undocumented) - idToken: string; - // (undocumented) - refreshToken?: string; -} - -// @public -export function oidc(input: { - config: OidcConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; - storage?: Partial; -}): Promise< - | { - error: string; - type: string; - subscribe?: undefined; - authorize?: undefined; - token?: undefined; - user?: undefined; - } - | { - subscribe: (listener: () => void) => Unsubscribe; - authorize: { - url: (options?: GetAuthorizationUrlOptions) => Promise; - background: ( - options?: GetAuthorizationUrlOptions, - ) => Promise; - }; - token: { - exchange: ( - code: string, - state: string, - options?: Partial, - ) => Promise; - get: ( - options?: GetTokensOptions, - ) => Promise; - revoke: () => Promise; - }; - user: { - info: () => Promise; - logout: () => Promise; - session: (options?: SessionCheckOptions) => Promise; - }; - error?: undefined; - type?: undefined; - } ->; - -// @public (undocumented) -export type OidcClient = Awaited>; - -export { OidcConfig }; - -// @public (undocumented) -export type OptionalAuthorizeOptions = Partial; - -// @public (undocumented) -export interface PushAuthorizationResponse { - // (undocumented) - expires_in: number; - // (undocumented) - request_uri: string; -} - -export { RequestMiddleware }; - -export { ResponseType_2 as ResponseType }; - -// @public (undocumented) -export type RevokeErrorResult = { - error: string; - revokeResponse: GenericError | null; - deleteResponse: GenericError | null; -}; - -// @public (undocumented) -export type RevokeSuccessResult = { - revokeResponse: null; - deleteResponse: null; -}; - -// @public (undocumented) -export type RootState = ReturnType; - -// @public -export interface SessionCheckOptions { - redirectUri?: string; - responseType?: SessionCheckResponseType; - scope?: string; - subject?: string; -} - -// @public (undocumented) -export type SessionCheckResponseType = 'id_token' | 'none'; - -// @public (undocumented) -export type SessionCheckSuccess = { - responseType: SessionCheckResponseType; - claims?: JWTPayload; -}; - -export { StorageConfig }; - -// @public (undocumented) -export interface TokenExchangeErrorResponse { - // (undocumented) - error: string; - // (undocumented) - message: string; - // (undocumented) - type: 'exchange_error' | 'network_error' | 'state_error' | 'unknown_error'; -} - -// @public (undocumented) -export interface TokenExchangeResponse { - // (undocumented) - access_token: string; - // (undocumented) - expires_in?: number; - // (undocumented) - id_token: string; - // (undocumented) - refresh_token?: string; - // (undocumented) - scope?: string; - // (undocumented) - token_type?: string; -} - -// @public (undocumented) -export interface TokenRequestOptions { - // (undocumented) - code: string; - // (undocumented) - config: OidcConfig; - // (undocumented) - endpoint: string; - // (undocumented) - verifier?: string; -} - -// @public (undocumented) -export type UserInfoResponse = { - sub: string; - [key: string]: unknown; -}; - -export { WellknownResponse }; - -// (No @packageDocumentation comment for this package) -``` +## API Report File for "@forgerock/oidc-client" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ActionTypes } from '@forgerock/sdk-request-middleware'; +import { BaseQueryFn } from '@reduxjs/toolkit/query'; +import { CombinedState } from '@reduxjs/toolkit/query'; +import { CustomLogger } from '@forgerock/sdk-logger'; +import { EnhancedStore } from '@reduxjs/toolkit'; +import { FetchArgs } from '@reduxjs/toolkit/query'; +import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'; +import { FetchBaseQueryMeta } from '@reduxjs/toolkit/query'; +import { GenericError } from '@forgerock/sdk-types'; +import { GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; +import type { JWTPayload } from 'jose'; +import { logger } from '@forgerock/sdk-logger'; +import { LogLevel } from '@forgerock/sdk-logger'; +import { LogMessage } from '@forgerock/sdk-logger'; +import { MutationDefinition } from '@reduxjs/toolkit/query'; +import { OidcConfig } from '@forgerock/sdk-types'; +import { QueryDefinition } from '@reduxjs/toolkit/query'; +import { RequestMiddleware } from '@forgerock/sdk-request-middleware'; +import { ResponseType as ResponseType_2 } from '@forgerock/sdk-types'; +import type { SdkStore } from '@forgerock/sdk-types'; +import { StorageConfig } from '@forgerock/storage'; +import { StoreEnhancer } from '@reduxjs/toolkit'; +import { ThunkDispatch } from '@reduxjs/toolkit'; +import { Tuple } from '@reduxjs/toolkit'; +import { UnknownAction } from '@reduxjs/toolkit'; +import { Unsubscribe } from '@reduxjs/toolkit'; +import { WellknownResponse } from '@forgerock/sdk-types'; + +export { ActionTypes } + +// @public (undocumented) +export type AppDispatch = ReturnType; + +// @public (undocumented) +export interface AuthorizationError { + // (undocumented) + error: string; + // (undocumented) + error_description: string; + // (undocumented) + redirectUrl?: string; + // (undocumented) + type: 'auth_error' | 'argument_error' | 'network_error' | 'unknown_error' | 'wellknown_error'; +} + +// @public (undocumented) +export interface AuthorizationSuccess { + // (undocumented) + code: string; + // (undocumented) + state: string; +} + +// @public (undocumented) +export interface AuthorizeErrorResponse { + // (undocumented) + code?: string; + // (undocumented) + details?: [ + { + code: string; + message: string; + } + ]; + // (undocumented) + id?: string; + // (undocumented) + message?: string; +} + +// @public (undocumented) +export interface AuthorizeSuccessResponse { + // (undocumented) + authorizeResponse?: { + code: string; + state: string; + }; + // (undocumented) + createdAt?: string; + // (undocumented) + _embedded?: { + [key: string]: unknown; + }; + // (undocumented) + environment?: { + id: string; + }; + // (undocumented) + expiresAt?: string; + // (undocumented) + id?: string; + // (undocumented) + _links?: { + [key: string]: { + href: string; + }; + }; + // (undocumented) + resumeUrl?: string; + // (undocumented) + session?: { + id: string; + }; + // (undocumented) + status?: string; +} + +// @public (undocumented) +export type BuildAuthorizationData = [string, GetAuthorizationUrlOptions]; + +// @public (undocumented) +export type ClientStore = ReturnType; + +// @public +export function createClientStore(input: { + requestMiddleware?: RequestMiddleware[]; + logger?: ReturnType; +}): EnhancedStore< { +oidc: CombinedState< { +authorizeFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizeSuccessResponse, "oidc", unknown>; +par: MutationDefinition< { +endpoint: string; +body: URLSearchParams; +}, BaseQueryFn, never, PushAuthorizationResponse, "oidc", unknown>; +sessionCheckIframe: MutationDefinition< { +url: string; +responseType: SessionCheckResponseType; +}, BaseQueryFn, never, { +params: Record; +}, "oidc", unknown>; +sessionCheckFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, { +status: 204; +}, "oidc", unknown>; +authorizeIframe: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizationSuccess, "oidc", unknown>; +endSession: MutationDefinition< { +idToken: string; +endpoint: string; +signOutRedirectUri?: string; +}, BaseQueryFn, never, null, "oidc", unknown>; +exchange: MutationDefinition< { +code: string; +config: OidcConfig; +endpoint: string; +verifier?: string; +}, BaseQueryFn, never, TokenExchangeResponse, "oidc", unknown>; +revoke: MutationDefinition< { +accessToken: string; +clientId?: string; +endpoint: string; +}, BaseQueryFn, never, object, "oidc", unknown>; +userInfo: MutationDefinition< { +accessToken: string; +endpoint: string; +}, BaseQueryFn, never, UserInfoResponse, "oidc", unknown>; +}, never, "oidc">; +wellknown: CombinedState< { +configuration: QueryDefinition, never, WellknownResponse, "wellknown", unknown>; +}, never, "wellknown">; +}, UnknownAction, Tuple<[StoreEnhancer< { +dispatch: ThunkDispatch< { +oidc: CombinedState< { +authorizeFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizeSuccessResponse, "oidc", unknown>; +par: MutationDefinition< { +endpoint: string; +body: URLSearchParams; +}, BaseQueryFn, never, PushAuthorizationResponse, "oidc", unknown>; +sessionCheckIframe: MutationDefinition< { +url: string; +responseType: SessionCheckResponseType; +}, BaseQueryFn, never, { +params: Record; +}, "oidc", unknown>; +sessionCheckFetch: MutationDefinition< { +url: string; +}, BaseQueryFn, never, { +status: 204; +}, "oidc", unknown>; +authorizeIframe: MutationDefinition< { +url: string; +}, BaseQueryFn, never, AuthorizationSuccess, "oidc", unknown>; +endSession: MutationDefinition< { +idToken: string; +endpoint: string; +signOutRedirectUri?: string; +}, BaseQueryFn, never, null, "oidc", unknown>; +exchange: MutationDefinition< { +code: string; +config: OidcConfig; +endpoint: string; +verifier?: string; +}, BaseQueryFn, never, TokenExchangeResponse, "oidc", unknown>; +revoke: MutationDefinition< { +accessToken: string; +clientId?: string; +endpoint: string; +}, BaseQueryFn, never, object, "oidc", unknown>; +userInfo: MutationDefinition< { +accessToken: string; +endpoint: string; +}, BaseQueryFn, never, UserInfoResponse, "oidc", unknown>; +}, never, "oidc">; +wellknown: CombinedState< { +configuration: QueryDefinition, never, WellknownResponse, "wellknown", unknown>; +}, never, "wellknown">; +}, { +requestMiddleware: RequestMiddleware[] | undefined; +logger: { +changeLevel: (level: LogLevel) => void; +error: (...args: LogMessage[]) => void; +warn: (...args: LogMessage[]) => void; +info: (...args: LogMessage[]) => void; +debug: (...args: LogMessage[]) => void; +} | undefined; +}, UnknownAction>; +}>, StoreEnhancer]>>; + +export { CustomLogger } + +export { GenericError } + +export { GetAuthorizationUrlOptions } + +// @public (undocumented) +export interface GetTokensOptions { + // (undocumented) + authorizeOptions?: GetAuthorizationUrlOptions; + // (undocumented) + backgroundRenew?: boolean; + // (undocumented) + forceRenew?: boolean; + // (undocumented) + storageOptions?: Partial; +} + +export { LogLevel } + +// @public (undocumented) +export type LogoutErrorResult = { + error: string; + sessionResponse: GenericError | null; + revokeResponse: GenericError | null; + deleteResponse: GenericError | null; +}; + +// @public (undocumented) +export type LogoutSuccessResult = RevokeSuccessResult & { + sessionResponse: null; +}; + +// @public (undocumented) +export interface OauthTokens { + // (undocumented) + accessToken: string; + // (undocumented) + expiresAt?: number; + // (undocumented) + expiryTimestamp?: number; + // (undocumented) + idToken: string; + // (undocumented) + refreshToken?: string; +} + +// @public +export function oidc(input: { + config: OidcConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; + storage?: Partial; +}, sharedStore?: SdkStore): Promise<{ + error: string; + type: string; + subscribe?: undefined; + authorize?: undefined; + token?: undefined; + user?: undefined; +} | { + subscribe: (listener: () => void) => Unsubscribe; + authorize: { + url: (options?: GetAuthorizationUrlOptions) => Promise; + background: (options?: GetAuthorizationUrlOptions) => Promise; + }; + token: { + exchange: (code: string, state: string, options?: Partial) => Promise; + get: (options?: GetTokensOptions) => Promise; + revoke: () => Promise; + }; + user: { + info: () => Promise; + logout: () => Promise; + session: (options?: SessionCheckOptions) => Promise; + }; + error?: undefined; + type?: undefined; +}>; + +// @public (undocumented) +export type OidcClient = Awaited>; + +export { OidcConfig } + +// @public (undocumented) +export type OptionalAuthorizeOptions = Partial; + +// @public (undocumented) +export interface PushAuthorizationResponse { + // (undocumented) + expires_in: number; + // (undocumented) + request_uri: string; +} + +export { RequestMiddleware } + +export { ResponseType_2 as ResponseType } + +// @public (undocumented) +export type RevokeErrorResult = { + error: string; + revokeResponse: GenericError | null; + deleteResponse: GenericError | null; +}; + +// @public (undocumented) +export type RevokeSuccessResult = { + revokeResponse: null; + deleteResponse: null; +}; + +// @public (undocumented) +export type RootState = ReturnType; + +// @public +export interface SessionCheckOptions { + redirectUri?: string; + responseType?: SessionCheckResponseType; + scope?: string; + subject?: string; +} + +// @public (undocumented) +export type SessionCheckResponseType = 'id_token' | 'none'; + +// @public (undocumented) +export type SessionCheckSuccess = { + responseType: SessionCheckResponseType; + claims?: JWTPayload; +}; + +export { StorageConfig } + +// @public (undocumented) +export interface TokenExchangeErrorResponse { + // (undocumented) + error: string; + // (undocumented) + message: string; + // (undocumented) + type: 'exchange_error' | 'network_error' | 'state_error' | 'unknown_error'; +} + +// @public (undocumented) +export interface TokenExchangeResponse { + // (undocumented) + access_token: string; + // (undocumented) + expires_in?: number; + // (undocumented) + id_token: string; + // (undocumented) + refresh_token?: string; + // (undocumented) + scope?: string; + // (undocumented) + token_type?: string; +} + +// @public (undocumented) +export interface TokenRequestOptions { + // (undocumented) + code: string; + // (undocumented) + config: OidcConfig; + // (undocumented) + endpoint: string; + // (undocumented) + verifier?: string; +} + +// @public (undocumented) +export type UserInfoResponse = { + sub: string; + [key: string]: unknown; +}; + +export { WellknownResponse } + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/oidc-client/package.json b/packages/oidc-client/package.json index 93e7dd09676..4f33ed5d3f5 100644 --- a/packages/oidc-client/package.json +++ b/packages/oidc-client/package.json @@ -33,6 +33,7 @@ "@forgerock/sdk-request-middleware": "workspace:*", "@forgerock/sdk-types": "workspace:*", "@forgerock/sdk-utilities": "workspace:*", + "@forgerock/sdk-wellknown": "workspace:*", "@forgerock/storage": "workspace:*", "@reduxjs/toolkit": "catalog:", "effect": "catalog:effect", diff --git a/packages/oidc-client/src/__tests__/types-reexport.typecheck.ts b/packages/oidc-client/src/__tests__/types-reexport.typecheck.ts index 5be171257b3..52724c04fae 100644 --- a/packages/oidc-client/src/__tests__/types-reexport.typecheck.ts +++ b/packages/oidc-client/src/__tests__/types-reexport.typecheck.ts @@ -4,14 +4,13 @@ */ import type { ActionTypes, - BrowserStorageConfig, CustomLogger, - CustomStorageConfig, - CustomStorageObject, + // Already re-exported (regression guard) GenericError, GetAuthorizationUrlOptions, LogLevel, RequestMiddleware, + // Should be re-exported but is not yet ResponseType, StorageConfig, WellknownResponse, @@ -23,9 +22,6 @@ type _Assert = [ GetAuthorizationUrlOptions, WellknownResponse, StorageConfig, - BrowserStorageConfig, - CustomStorageConfig, - CustomStorageObject, ActionTypes, RequestMiddleware, CustomLogger, diff --git a/packages/oidc-client/src/lib/authorize.request.micros.test.ts b/packages/oidc-client/src/lib/authorize.request.micros.test.ts index 079ab93df0f..a54e4e4a37d 100644 --- a/packages/oidc-client/src/lib/authorize.request.micros.test.ts +++ b/packages/oidc-client/src/lib/authorize.request.micros.test.ts @@ -7,7 +7,7 @@ import { expect, it } from '@effect/vitest'; import * as sdkOidc from '@forgerock/sdk-oidc'; import * as sdkUtilities from '@forgerock/sdk-utilities'; -import { Micro } from 'effect'; +import { Cause, Effect, Exit, Option } from 'effect'; import { afterEach, vi } from 'vitest'; import { @@ -62,7 +62,7 @@ afterEach(() => { // ─── generateAuthValuesµ ─────────────────────────────────────────────────────── it.effect('generateAuthValuesµ returns auth URL options and store function', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.stubGlobal('sessionStorage', sessionStorageStub); const result = yield* generateAuthValuesµ(config, wellknown); const [opts, storeFn] = result; @@ -74,22 +74,24 @@ it.effect('generateAuthValuesµ returns auth URL options and store function', () ); it.effect('generateAuthValuesµ fails with auth_error when sessionStorage throws', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkOidc, 'generateAndStoreAuthUrlValues').mockImplementation(() => { throw new Error('storage unavailable'); }); - const exit = yield* Micro.exit(generateAuthValuesµ(config, wellknown)); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('auth_error'); - expect(exit.cause.error.error).toBe('PAR_PARAM_BUILD_ERROR'); + const exit = yield* Effect.exit(generateAuthValuesµ(config, wellknown)); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('auth_error'); + expect(errorOpt.value.error).toBe('PAR_PARAM_BUILD_ERROR'); }), ); // ─── generatePkceChallengeµ ──────────────────────────────────────────────────── it.effect('generatePkceChallengeµ returns a non-empty challenge string', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.stubGlobal('crypto', { subtle: { digest: vi.fn().mockResolvedValue(new ArrayBuffer(32)), @@ -103,20 +105,22 @@ it.effect('generatePkceChallengeµ returns a non-empty challenge string', () => ); it.effect('generatePkceChallengeµ fails with auth_error when createChallenge throws', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkUtilities, 'createChallenge').mockRejectedValue(new Error('crypto unavailable')); - const exit = yield* Micro.exit(generatePkceChallengeµ('bad-verifier')); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('auth_error'); - expect(exit.cause.error.error).toBe('PAR_CHALLENGE_ERROR'); + const exit = yield* Effect.exit(generatePkceChallengeµ('bad-verifier')); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('auth_error'); + expect(errorOpt.value.error).toBe('PAR_CHALLENGE_ERROR'); }), ); // ─── buildParBodyµ ───────────────────────────────────────────────────────────── it.effect('buildParBodyµ returns URLSearchParams with expected fields', () => - Micro.gen(function* () { + Effect.gen(function* () { const params = yield* buildParBodyµ(config, {}, 'challenge-abc', 'state-xyz'); expect(params.get('client_id')).toBe(clientId); expect(params.get('code_challenge')).toBe('challenge-abc'); @@ -127,29 +131,31 @@ it.effect('buildParBodyµ returns URLSearchParams with expected fields', () => ); it.effect('buildParBodyµ includes prompt when provided', () => - Micro.gen(function* () { + Effect.gen(function* () { const params = yield* buildParBodyµ(config, {}, 'challenge-abc', 'state-xyz', 'login'); expect(params.get('prompt')).toBe('login'); }), ); it.effect('buildParBodyµ fails with auth_error when buildAuthorizeParams throws', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkOidc, 'buildAuthorizeParams').mockImplementation(() => { throw new Error('build failed'); }); - const exit = yield* Micro.exit(buildParBodyµ(config, {}, 'ch', 'st')); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('auth_error'); - expect(exit.cause.error.error).toBe('PAR_PARAM_BUILD_ERROR'); + const exit = yield* Effect.exit(buildParBodyµ(config, {}, 'ch', 'st')); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('auth_error'); + expect(errorOpt.value.error).toBe('PAR_PARAM_BUILD_ERROR'); }), ); // ─── buildParSlimUrlµ ────────────────────────────────────────────────────────── it.effect('buildParSlimUrlµ returns URL with only client_id and request_uri', () => - Micro.gen(function* () { + Effect.gen(function* () { const url = yield* buildParSlimUrlµ( wellknown.authorization_endpoint, clientId, @@ -163,7 +169,7 @@ it.effect('buildParSlimUrlµ returns URL with only client_id and request_uri', ( ); it.effect('buildParSlimUrlµ includes prompt when provided', () => - Micro.gen(function* () { + Effect.gen(function* () { const url = yield* buildParSlimUrlµ( wellknown.authorization_endpoint, clientId, @@ -177,7 +183,7 @@ it.effect('buildParSlimUrlµ includes prompt when provided', () => // ─── storeAuthOptionsµ ───────────────────────────────────────────────────────── it.effect('storeAuthOptionsµ calls the provided store function', () => - Micro.gen(function* () { + Effect.gen(function* () { const storeFn = vi.fn(); yield* storeAuthOptionsµ(storeFn); expect(storeFn).toHaveBeenCalledOnce(); @@ -185,23 +191,25 @@ it.effect('storeAuthOptionsµ calls the provided store function', () => ); it.effect('storeAuthOptionsµ fails with unknown_error when store function throws', () => - Micro.gen(function* () { - const exit = yield* Micro.exit( + Effect.gen(function* () { + const exit = yield* Effect.exit( storeAuthOptionsµ(() => { throw new Error('storage write failed'); }), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('unknown_error'); - expect(exit.cause.error.error).toBe('PAR_STORAGE_ERROR'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('unknown_error'); + expect(errorOpt.value.error).toBe('PAR_STORAGE_ERROR'); }), ); // ─── validateParResponseµ ────────────────────────────────────────────────────── it.effect('validateParResponseµ succeeds when request_uri is present', () => - Micro.gen(function* () { + Effect.gen(function* () { const result = yield* validateParResponseµ({ data: { request_uri: 'urn:ietf:params:oauth:request_uri:xyz', expires_in: 60 }, }); @@ -210,8 +218,8 @@ it.effect('validateParResponseµ succeeds when request_uri is present', () => ); it.effect('validateParResponseµ fails with network_error on RTK error', () => - Micro.gen(function* () { - const exit = yield* Micro.exit( + Effect.gen(function* () { + const exit = yield* Effect.exit( validateParResponseµ({ error: { status: 400, @@ -219,26 +227,30 @@ it.effect('validateParResponseµ fails with network_error on RTK error', () => }, }), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.error).toBe('invalid_client'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('invalid_client'); }), ); it.effect('validateParResponseµ fails with network_error when request_uri is absent', () => - Micro.gen(function* () { - const exit = yield* Micro.exit(validateParResponseµ({ data: { expires_in: 60 } })); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('network_error'); - expect(exit.cause.error.error_description).toContain('request_uri'); + Effect.gen(function* () { + const exit = yield* Effect.exit(validateParResponseµ({ data: { expires_in: 60 } })); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('network_error'); + expect(errorOpt.value.error_description).toContain('request_uri'); }), ); // ─── createAuthorizeUrlµ ────────────────────────────────────────────────── it.effect('createAuthorizeUrlµ returns [url, options] tuple', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.stubGlobal('sessionStorage', sessionStorageStub); const opts = { clientId, @@ -258,9 +270,9 @@ it.effect('createAuthorizeUrlµ returns [url, options] tuple', () => ); it.effect('createAuthorizeUrlµ fails with auth_error when createAuthorizeUrl rejects', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkOidc, 'createAuthorizeUrl').mockRejectedValue(new Error('url build failed')); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( createAuthorizeUrlµ(wellknown.authorization_endpoint, { clientId, redirectUri, @@ -268,18 +280,20 @@ it.effect('createAuthorizeUrlµ fails with auth_error when createAuthorizeUrl re responseType, }), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('auth_error'); - expect(exit.cause.error.error).toBe('AuthorizationUrlError'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('auth_error'); + expect(errorOpt.value.error).toBe('AuthorizationUrlError'); }), ); // ─── handleDispatchErrorµ ────────────────────────────────────────────────────── it.effect('handleDispatchErrorµ fails immediately for CONFIGURATION_ERROR', () => - Micro.gen(function* () { - const exit = yield* Micro.exit( + Effect.gen(function* () { + const exit = yield* Effect.exit( handleDispatchErrorµ( { status: 'CUSTOM_ERROR', @@ -291,18 +305,20 @@ it.effect('handleDispatchErrorµ fails immediately for CONFIGURATION_ERROR', () { clientId, redirectUri, scope, responseType }, ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('unknown_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('unknown_error'); }), ); it.effect('handleDispatchErrorµ builds redirect URL for non-config errors', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkOidc, 'createAuthorizeUrl').mockResolvedValue( 'https://example.com/authorize?error=login_required', ); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( handleDispatchErrorµ( { status: 400, @@ -316,17 +332,19 @@ it.effect('handleDispatchErrorµ builds redirect URL for non-config errors', () { clientId, redirectUri, scope, responseType }, ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.error).toBe('login_required'); - expect(exit.cause.error).toHaveProperty('redirectUrl'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('login_required'); + expect(errorOpt.value).toHaveProperty('redirectUrl'); }), ); // ─── dispatchAuthorizeFetchµ ─────────────────────────────────────────────────── it.effect('dispatchAuthorizeFetchµ succeeds with authorizeResponse', () => - Micro.gen(function* () { + Effect.gen(function* () { const authorizeResponse = { code: 'auth-code-abc', state: 'state-xyz' }; vi.mocked(mockStore.dispatch).mockResolvedValueOnce({ data: { authorizeResponse }, @@ -345,12 +363,12 @@ it.effect('dispatchAuthorizeFetchµ succeeds with authorizeResponse', () => it.effect( 'dispatchAuthorizeFetchµ fails with unknown_error when data has no authorizeResponse', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.mocked(mockStore.dispatch).mockResolvedValueOnce({ data: {}, } as unknown as ReturnType); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchAuthorizeFetchµ(mockStore, 'https://example.com/authorize', wellknown, { clientId, redirectUri, @@ -358,16 +376,18 @@ it.effect( responseType, }), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('unknown_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('unknown_error'); }), ); // ─── dispatchAuthorizeIframeµ ────────────────────────────────────────────────── it.effect('dispatchAuthorizeIframeµ succeeds with iframe data', () => - Micro.gen(function* () { + Effect.gen(function* () { const iframeData = { code: 'iframe-code', state: 'state-abc' }; vi.mocked(mockStore.dispatch).mockResolvedValueOnce({ data: iframeData, @@ -384,12 +404,12 @@ it.effect('dispatchAuthorizeIframeµ succeeds with iframe data', () => ); it.effect('dispatchAuthorizeIframeµ fails with unknown_error when data is undefined', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.mocked(mockStore.dispatch).mockResolvedValueOnce({ data: undefined, } as unknown as ReturnType); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchAuthorizeIframeµ(mockStore, 'https://example.com/authorize', wellknown, { clientId, redirectUri, @@ -397,19 +417,21 @@ it.effect('dispatchAuthorizeIframeµ fails with unknown_error when data is undef responseType, }), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('unknown_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('unknown_error'); }), ); it.effect('dispatchAuthorizeIframeµ fails with unknown_error when data has no code or state', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.mocked(mockStore.dispatch).mockResolvedValueOnce({ data: { unexpected: 'shape' }, } as unknown as ReturnType); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchAuthorizeIframeµ( mockStore, 'https://example.com/authorize?foo=bar', @@ -417,9 +439,11 @@ it.effect('dispatchAuthorizeIframeµ fails with unknown_error when data has no c {} as GetAuthorizationUrlOptions, ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; - expect(exit.cause.error.type).toBe('unknown_error'); - expect(exit.cause.error.error).toBe('Unknown_Error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('unknown_error'); + expect(errorOpt.value.error).toBe('Unknown_Error'); }), ); diff --git a/packages/oidc-client/src/lib/authorize.request.micros.ts b/packages/oidc-client/src/lib/authorize.request.micros.ts index 53098144839..547b2e01c69 100644 --- a/packages/oidc-client/src/lib/authorize.request.micros.ts +++ b/packages/oidc-client/src/lib/authorize.request.micros.ts @@ -10,7 +10,7 @@ import { generateAndStoreAuthUrlValues, } from '@forgerock/sdk-oidc'; import { createChallenge } from '@forgerock/sdk-utilities'; -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { buildParAuthorizeUrl, @@ -39,8 +39,8 @@ export const generateAuthValuesµ = ( config: OidcConfig, wellknown: WellknownResponse, options?: OptionalAuthorizeOptions, -): Micro.Micro, AuthorizationError, never> => { - return Micro.try({ +): Effect.Effect, AuthorizationError, never> => { + return Effect.try({ try: () => generateAndStoreAuthUrlValues({ clientId: config.clientId, @@ -60,8 +60,8 @@ export const generateAuthValuesµ = ( export const generatePkceChallengeµ = ( verifier: string, -): Micro.Micro => { - return Micro.tryPromise({ +): Effect.Effect => { + return Effect.tryPromise({ try: () => createChallenge(verifier), catch: (err): AuthorizationError => ({ error: 'PAR_CHALLENGE_ERROR', @@ -73,8 +73,8 @@ export const generatePkceChallengeµ = ( export const storeAuthOptionsµ = ( storeOptions: () => void, -): Micro.Micro => { - return Micro.try({ +): Effect.Effect => { + return Effect.try({ try: () => storeOptions(), catch: (err): AuthorizationError => ({ error: 'PAR_STORAGE_ERROR', @@ -92,8 +92,8 @@ export const buildParBodyµ = ( challenge: string, state: string, prompt?: AuthPromptValue, -): Micro.Micro => { - return Micro.try({ +): Effect.Effect => { + return Effect.try({ try: () => buildAuthorizeParams({ clientId: config.clientId, @@ -116,8 +116,8 @@ export const buildParBodyµ = ( export const createAuthorizeUrlµ = ( path: string, options: GetAuthorizationUrlOptions, -): Micro.Micro<[string, GetAuthorizationUrlOptions], AuthorizationError, never> => { - return Micro.tryPromise({ +): Effect.Effect<[string, GetAuthorizationUrlOptions], AuthorizationError, never> => { + return Effect.tryPromise({ try: async () => [await createAuthorizeUrl(path, { ...options, prompt: 'none' }), options] as [ string, @@ -136,8 +136,8 @@ export const buildAuthorizeRedirectUrlµ = ( res: { error: string; error_description: string }, wellknown: WellknownResponse, options: GetAuthorizationUrlOptions, -): Micro.Micro => { - return Micro.tryPromise({ +): Effect.Effect => { + return Effect.tryPromise({ try: () => { const { prompt: _prompt, ...interactiveOptions } = options; return createAuthorizeUrl(wellknown.authorization_endpoint, interactiveOptions); @@ -149,8 +149,8 @@ export const buildAuthorizeRedirectUrlµ = ( type: 'auth_error', }), }).pipe( - Micro.flatMap((url) => - Micro.fail({ + Effect.flatMap((url) => + Effect.fail({ error: res.error, error_description: res.error_description, type: 'auth_error', @@ -163,26 +163,26 @@ export const buildAuthorizeRedirectUrlµ = ( export const validateParResponseµ = (result: { error?: FetchBaseQueryError | SerializedError; data?: unknown; -}): Micro.Micro<{ request_uri: string; expires_in: number }, AuthorizationError, never> => { +}): Effect.Effect<{ request_uri: string; expires_in: number }, AuthorizationError, never> => { if (result.error) { - return Micro.fail(toDispatchError(result.error)); + return Effect.fail(toDispatchError(result.error)); } if (!hasPushRequestUri(result.data)) { - return Micro.fail({ + return Effect.fail({ error: 'PAR_ERROR', error_description: "PAR response missing required 'request_uri' field", type: 'network_error', } as const); } const d = result.data as { request_uri: string; expires_in?: number }; - return Micro.succeed({ request_uri: d.request_uri, expires_in: d.expires_in ?? 60 }); + return Effect.succeed({ request_uri: d.request_uri, expires_in: d.expires_in ?? 60 }); }; export const handleDispatchErrorµ = ( error: FetchBaseQueryError | SerializedError, wellknown: WellknownResponse, options: GetAuthorizationUrlOptions, -): Micro.Micro => { +): Effect.Effect => { const errorDetails = toDispatchError(error); const isConfigError = isFetchBaseQueryError(error) && @@ -190,7 +190,7 @@ export const handleDispatchErrorµ = ( error.statusText === 'CONFIGURATION_ERROR'; return isConfigError - ? Micro.fail(errorDetails) + ? Effect.fail(errorDetails) : buildAuthorizeRedirectUrlµ(errorDetails, wellknown, options); }; @@ -200,12 +200,12 @@ export const dispatchParRequestµ = ( store: ClientStore, parEndpoint: string, body: URLSearchParams, -): Micro.Micro< +): Effect.Effect< { error?: FetchBaseQueryError | SerializedError; data?: unknown }, AuthorizationError, never > => { - return Micro.tryPromise({ + return Effect.tryPromise({ try: () => store.dispatch(oidcApi.endpoints.par.initiate({ endpoint: parEndpoint, body })), catch: (error): AuthorizationError => ({ error: 'PAR_DISPATCH_ERROR', @@ -220,8 +220,8 @@ export const buildParSlimUrlµ = ( clientId: string, requestUri: string, prompt?: AuthPromptValue, -): Micro.Micro => { - return Micro.try({ +): Effect.Effect => { + return Effect.try({ try: () => buildParAuthorizeUrl({ authorizationEndpoint, clientId, requestUri, prompt }), catch: (err): AuthorizationError => ({ error: 'PAR_URL_BUILD_ERROR', @@ -238,8 +238,8 @@ export const dispatchAuthorizeFetchµ = ( url: string, wellknown: WellknownResponse, options: GetAuthorizationUrlOptions, -): Micro.Micro => { - return Micro.tryPromise({ +): Effect.Effect => { + return Effect.tryPromise({ try: () => store.dispatch(oidcApi.endpoints.authorizeFetch.initiate({ url })), catch: (error): AuthorizationError => ({ error: 'AUTHORIZE_DISPATCH_ERROR', @@ -248,14 +248,14 @@ export const dispatchAuthorizeFetchµ = ( type: 'network_error', }), }).pipe( - Micro.flatMap(({ error, data }) => { + Effect.flatMap(({ error, data }) => { if (error) { return handleDispatchErrorµ(error, wellknown, options); } if (data?.authorizeResponse) { - return Micro.succeed(data.authorizeResponse); + return Effect.succeed(data.authorizeResponse); } - return Micro.fail({ + return Effect.fail({ error: 'Unknown_Error', error_description: 'Response schema was not recognized', type: 'unknown_error', @@ -269,8 +269,8 @@ export const dispatchAuthorizeIframeµ = ( url: string, wellknown: WellknownResponse, options: GetAuthorizationUrlOptions, -): Micro.Micro => { - return Micro.tryPromise({ +): Effect.Effect => { + return Effect.tryPromise({ try: () => store.dispatch(oidcApi.endpoints.authorizeIframe.initiate({ url })), catch: (error): AuthorizationError => ({ error: 'AUTHORIZE_DISPATCH_ERROR', @@ -279,15 +279,15 @@ export const dispatchAuthorizeIframeµ = ( type: 'network_error', }), }).pipe( - Micro.flatMap(({ error, data }) => { + Effect.flatMap(({ error, data }) => { if (error) { return handleDispatchErrorµ(error, wellknown, options); } const d = data as { code?: unknown; state?: unknown } | undefined; if (d !== undefined && typeof d.code === 'string' && typeof d.state === 'string') { - return Micro.succeed(d as AuthorizationSuccess); + return Effect.succeed(d as AuthorizationSuccess); } - return Micro.fail({ + return Effect.fail({ error: 'Unknown_Error', error_description: 'Response data did not contain expected code and state fields', type: 'unknown_error', diff --git a/packages/oidc-client/src/lib/authorize.request.ts b/packages/oidc-client/src/lib/authorize.request.ts index 0b3d34dfc77..6c74e4dfe3b 100644 --- a/packages/oidc-client/src/lib/authorize.request.ts +++ b/packages/oidc-client/src/lib/authorize.request.ts @@ -1,10 +1,10 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { buildParBodyµ, @@ -44,16 +44,20 @@ function dispatchAuthorizeµ( wellknown: WellknownResponse, store: ClientStore, log: CustomLogger, -): Micro.Micro { +): Effect.Effect { if (options.responseMode === 'pi.flow') { const { responseMode: _, ...redirectOptions } = options; return dispatchAuthorizeFetchµ(store, url, wellknown, redirectOptions).pipe( - Micro.tap(() => log.debug('Received success response from authorize fetch endpoint')), + Effect.tap(() => + Effect.sync(() => log.debug('Received success response from authorize fetch endpoint')), + ), ); } return dispatchAuthorizeIframeµ(store, url, wellknown, options).pipe( - Micro.tap(() => log.debug('Received success response from authorize iframe endpoint')), + Effect.tap(() => + Effect.sync(() => log.debug('Received success response from authorize iframe endpoint')), + ), ); } @@ -73,7 +77,7 @@ function dispatchAuthorizeµ( * @param options - Optional request-level overrides; `prompt` is split out * so it appears on the slim URL while the rest of the params go in the * PAR POST body. - * @returns A `Micro` that resolves to the slim authorize URL string or + * @returns An `Effect` that resolves to the slim authorize URL string or * fails with a typed `AuthorizationError`. */ export function createParAuthorizeUrlµ( @@ -82,11 +86,11 @@ export function createParAuthorizeUrlµ( log: CustomLogger, store: ClientStore, options?: OptionalAuthorizeOptions, -): Micro.Micro { +): Effect.Effect { const parEndpoint = wellknown.pushed_authorization_request_endpoint; if (!parEndpoint) { - return Micro.fail({ + return Effect.fail({ error: 'PAR_NOT_CONFIGURED', error_description: 'PAR endpoint not found in server configuration', type: 'wellknown_error', @@ -95,7 +99,7 @@ export function createParAuthorizeUrlµ( const { prompt, ...parBodyOptions } = options ?? {}; - return Micro.gen(function* () { + return Effect.gen(function* () { const [authUrlOptions, storeOptions] = yield* generateAuthValuesµ(config, wellknown, options); const challenge = yield* generatePkceChallengeµ(authUrlOptions.verifier); const body = yield* buildParBodyµ( @@ -108,7 +112,7 @@ export function createParAuthorizeUrlµ( const parResult = yield* dispatchParRequestµ(store, parEndpoint, body); const { request_uri, expires_in } = yield* validateParResponseµ(parResult); if (expires_in < 30) { - yield* Micro.sync(() => + yield* Effect.sync(() => log.warn( `PAR request_uri expires in ${expires_in}s — authorize must complete before expiry`, ), @@ -144,7 +148,7 @@ export function createParAuthorizeUrlµ( * indicating whether to use the PAR flow. The caller owns the derivation * logic (`config.par ?? require_pushed_authorization_requests === true`); * this function simply routes on the resolved value. - * @returns A `Micro` that resolves to an `AuthorizationSuccess` containing + * @returns An `Effect` that resolves to an `AuthorizationSuccess` containing * the `code` and `state`, or fails with a typed `AuthorizationError`. */ export function authorizeµ( @@ -154,7 +158,7 @@ export function authorizeµ( store: ClientStore, options: GetAuthorizationUrlOptions | undefined, useParFlow: boolean, -): Micro.Micro { +): Effect.Effect { const parDispatchOptions: GetAuthorizationUrlOptions = { clientId: config.clientId, redirectUri: config.redirectUri, @@ -164,14 +168,14 @@ export function authorizeµ( }; const parFlow = createParAuthorizeUrlµ(wellknown, config, log, store, options).pipe( - Micro.tap((url) => log.debug('PAR authorize URL created', url)), - Micro.tapError((err) => - Micro.sync(() => log.error(`PAR authorize failed [${err.type}]: ${err.error}`, err)), + Effect.tap((url) => Effect.sync(() => log.debug('PAR authorize URL created', url))), + Effect.tapError((err) => + Effect.sync(() => log.error(`PAR authorize failed [${err.type}]: ${err.error}`, err)), ), - Micro.flatMap((url) => + Effect.flatMap((url) => dispatchAuthorizeµ(url, parDispatchOptions, wellknown, store, log).pipe( - Micro.tapError((err) => - Micro.sync(() => log.error('Error dispatching PAR authorize request', err)), + Effect.tapError((err) => + Effect.sync(() => log.error('Error dispatching PAR authorize request', err)), ), ), ), @@ -179,13 +183,13 @@ export function authorizeµ( const [path, opts] = buildAuthorizeOptions(wellknown, config, options); const standardFlow = createAuthorizeUrlµ(path, opts).pipe( - Micro.tap(([url]) => log.debug('Authorize URL created', url)), - Micro.tapError((err) => Micro.sync(() => log.error('Error creating authorize URL', err))), - Micro.flatMap(([url, dispatchOpts]) => + Effect.tap(([url]) => Effect.sync(() => log.debug('Authorize URL created', url))), + Effect.tapError((err) => Effect.sync(() => log.error('Error creating authorize URL', err))), + Effect.flatMap(([url, dispatchOpts]) => dispatchAuthorizeµ(url, dispatchOpts, wellknown, store, log), ), - Micro.tapError((err) => - Micro.sync(() => log.error('Error dispatching authorize request', err)), + Effect.tapError((err) => + Effect.sync(() => log.error('Error dispatching authorize request', err)), ), ); diff --git a/packages/oidc-client/src/lib/authorize.request.utils.test.ts b/packages/oidc-client/src/lib/authorize.request.utils.test.ts index 3f774cc348d..fab9f740cdd 100644 --- a/packages/oidc-client/src/lib/authorize.request.utils.test.ts +++ b/packages/oidc-client/src/lib/authorize.request.utils.test.ts @@ -6,8 +6,8 @@ */ import { it } from '@effect/vitest'; import * as sdkOidc from '@forgerock/sdk-oidc'; -import { Micro } from 'effect'; -import { afterEach, beforeEach, expect, vi } from 'vitest'; +import { Cause, Effect, Exit, Option } from 'effect'; +import { afterEach, expect, vi } from 'vitest'; import { authorizeµ, createParAuthorizeUrlµ } from './authorize.request.js'; import { @@ -76,6 +76,7 @@ beforeEach(() => { afterEach(() => { vi.unstubAllGlobals(); + vi.clearAllMocks(); vi.restoreAllMocks(); }); @@ -141,26 +142,23 @@ it('toDispatchError delegates to toAuthorizationError for FetchBaseQueryError', // ─── createParAuthorizeUrlµ ─────────────────────────────────────────────────────────── it.effect('createParAuthorizeUrlµ fails with PAR_NOT_CONFIGURED when par endpoint is missing', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithPar: OidcConfig = { ...config, par: true }; - const result = yield* Micro.exit( + const result = yield* Effect.exit( createParAuthorizeUrlµ(wellknown, configWithPar, mockLog, mockStore), ); - expect(Micro.exitIsFailure(result)).toBe(true); - if (!Micro.exitIsFailure(result)) return; - expect(Micro.causeIsFail(result.cause)).toBe(true); - if (Micro.causeIsFail(result.cause)) { - expect(result.cause.error.error).toBe('PAR_NOT_CONFIGURED'); - expect(result.cause.error.type).toBe('wellknown_error'); - expect(result.cause.error.error_description).toBe( - 'PAR endpoint not found in server configuration', - ); - } + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('PAR_NOT_CONFIGURED'); + expect(errorOpt.value.type).toBe('wellknown_error'); + expect(errorOpt.value.error_description).toBe('PAR endpoint not found in server configuration'); }), ); it.effect('createParAuthorizeUrlµ succeeds and returns slim authorize URL', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithPar: OidcConfig = { ...config, par: true }; const requestUri = 'urn:ietf:params:oauth:request_uri:abc123'; @@ -180,7 +178,7 @@ it.effect('createParAuthorizeUrlµ succeeds and returns slim authorize URL', () ); it.effect('createParAuthorizeUrlµ fails with network_error when PAR POST returns error', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithPar: OidcConfig = { ...config, par: true }; vi.stubGlobal('sessionStorage', sessionStorageStub); @@ -192,16 +190,15 @@ it.effect('createParAuthorizeUrlµ fails with network_error when PAR POST return }, } as unknown as ReturnType); - const result = yield* Micro.exit( + const result = yield* Effect.exit( createParAuthorizeUrlµ(wellknownWithPar, configWithPar, mockLog, mockStore), ); - expect(Micro.exitIsFailure(result)).toBe(true); - if (!Micro.exitIsFailure(result)) return; - expect(Micro.causeIsFail(result.cause)).toBe(true); - if (Micro.causeIsFail(result.cause)) { - expect(result.cause.error.type).toBe('network_error'); - } + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('network_error'); expect(sessionStorageStub.setItem).not.toHaveBeenCalled(); }), ); @@ -209,7 +206,7 @@ it.effect('createParAuthorizeUrlµ fails with network_error when PAR POST return it.effect( 'createParAuthorizeUrlµ fails with network_error when PAR response is missing request_uri', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithPar: OidcConfig = { ...config, par: true }; vi.stubGlobal('sessionStorage', sessionStorageStub); @@ -217,19 +214,18 @@ it.effect( data: {}, } as unknown as ReturnType); - const result = yield* Micro.exit( + const result = yield* Effect.exit( createParAuthorizeUrlµ(wellknownWithPar, configWithPar, mockLog, mockStore), ); - expect(Micro.exitIsFailure(result)).toBe(true); - if (!Micro.exitIsFailure(result)) return; - expect(Micro.causeIsFail(result.cause)).toBe(true); - if (Micro.causeIsFail(result.cause)) { - expect(result.cause.error.type).toBe('network_error'); - expect(result.cause.error.error_description).toBe( - "PAR response missing required 'request_uri' field", - ); - } + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('network_error'); + expect(errorOpt.value.error_description).toBe( + "PAR response missing required 'request_uri' field", + ); expect(sessionStorageStub.setItem).not.toHaveBeenCalled(); }), ); @@ -237,7 +233,7 @@ it.effect( it.effect( 'createParAuthorizeUrlµ with prompt=none includes prompt on slim authorize URL and in PAR body', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithPar: OidcConfig = { ...config, par: true }; const requestUri = 'urn:ietf:params:oauth:request_uri:prompt-none-test'; @@ -298,13 +294,15 @@ it('hasPushRequestUri returns false when request_uri is missing', () => { import { validateParResponseµ } from './authorize.request.micros.js'; it.effect('validateParResponseµ with SerializedError preserves error message', () => - Micro.gen(function* () { + Effect.gen(function* () { const serializedError = { name: 'Error', message: 'network timeout', code: 'FETCH_ERROR' }; - const exit = yield* Micro.exit(validateParResponseµ({ error: serializedError })); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) return; + const exit = yield* Effect.exit(validateParResponseµ({ error: serializedError })); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; // Should surface the actual message, not generic "Unknown_Error" - expect(exit.cause.error.error_description).toContain('network timeout'); + expect(errorOpt.value.error_description).toContain('network timeout'); }), ); @@ -388,7 +386,7 @@ it('buildAuthorizeOptions falls back to "openid" scope and "code" responseType w // ─── authorizeµ flow routing ────────────────────────────────────────────────── it.effect('authorizeµ uses PAR flow when useParFlow=true', () => - Micro.gen(function* () { + Effect.gen(function* () { const requestUri = 'urn:ietf:params:oauth:request_uri:par-routing-test'; const authorizeResponse = { code: 'par-code', state: 'par-state' }; @@ -411,7 +409,7 @@ it.effect('authorizeµ uses PAR flow when useParFlow=true', () => ); it.effect('authorizeµ uses standard flow when useParFlow=false', () => - Micro.gen(function* () { + Effect.gen(function* () { const authorizeResponse = { code: 'std-code', state: 'std-state' }; vi.stubGlobal('sessionStorage', sessionStorageStub); @@ -432,7 +430,7 @@ it.effect('authorizeµ uses standard flow when useParFlow=false', () => it.effect( 'authorizeµ uses PAR flow when caller passes useParFlow=true (e.g. server requires PAR)', () => - Micro.gen(function* () { + Effect.gen(function* () { const requestUri = 'urn:ietf:params:oauth:request_uri:required-par-test'; const authorizeResponse = { code: 'req-par-code', state: 'req-par-state' }; @@ -462,7 +460,7 @@ it.effect( it.effect( 'authorizeµ routes to pi.flow fetch when options.responseMode is pi.flow (unwraps authorizeResponse)', () => - Micro.gen(function* () { + Effect.gen(function* () { // pi.flow dispatch goes through dispatchAuthorizeFetch which unwraps { authorizeResponse } const requestUri = 'urn:ietf:params:oauth:request_uri:pi-flow-test'; const authorizeResponse = { code: 'pi-code', state: 'pi-state' }; diff --git a/packages/oidc-client/src/lib/client.store.ts b/packages/oidc-client/src/lib/client.store.ts index e971a35ea7d..21d9df2f22e 100644 --- a/packages/oidc-client/src/lib/client.store.ts +++ b/packages/oidc-client/src/lib/client.store.ts @@ -6,23 +6,22 @@ */ import { logger as loggerFn } from '@forgerock/sdk-logger'; import { createAuthorizeUrl } from '@forgerock/sdk-oidc'; -import { handleMicroExit } from '@forgerock/sdk-utilities'; +import { handleExit } from '@forgerock/sdk-utilities'; +import { wellknownApi, wellknownSelector } from '@forgerock/sdk-wellknown'; import { createStorage } from '@forgerock/storage'; -import { Micro } from 'effect'; -import { causeIsDie, exitIsFail, exitIsSuccess } from 'effect/Micro'; +import { Cause, Effect, Exit, Option } from 'effect'; import { authorizeµ, createParAuthorizeUrlµ } from './authorize.request.js'; -import { createClientStore, createTokenError } from './client.store.utils.js'; +import { createClientStore, createTokenError, injectIntoStore } from './client.store.utils.js'; import { buildTokenExchangeµ } from './exchange.request.js'; import { logoutµ } from './logout.request.js'; import { oidcApi } from './oidc.api.js'; import { sessionCheckIdTokenµ, sessionCheckNoneµ } from './session.micros.js'; import { isExpiryWithinThreshold } from './token.utils.js'; -import { wellknownApi, wellknownSelector } from './wellknown.api.js'; import type { CustomLogger, LogLevel } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; -import type { GenericError, GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; +import type { GenericError, GetAuthorizationUrlOptions, SdkStore } from '@forgerock/sdk-types'; import type { StorageConfig } from '@forgerock/storage'; import type { AuthorizationError, AuthorizationSuccess } from './authorize.request.types.js'; @@ -51,20 +50,23 @@ import type { SessionCheckOptions, SessionCheckSuccess } from './session.types.j * @param {Partial} param.storage - optional storage configuration for persisting OIDC tokens. * @returns {ReturnType} - Returns an object with methods for authorization, token exchange, user info retrieval, and logout. */ -export async function oidc({ - config, - requestMiddleware, - logger, - storage, -}: { - config: OidcConfig; - requestMiddleware?: RequestMiddleware[]; - logger?: { - level: LogLevel; - custom?: CustomLogger; - }; - storage?: Partial; -}) { +export async function oidc( + { + config, + requestMiddleware, + logger, + storage, + }: { + config: OidcConfig; + requestMiddleware?: RequestMiddleware[]; + logger?: { + level: LogLevel; + custom?: CustomLogger; + }; + storage?: Partial; + }, + sharedStore?: SdkStore, +) { const log = loggerFn({ level: logger?.level ?? config.log ?? 'error', custom: logger?.custom, @@ -76,7 +78,15 @@ export async function oidc({ prefix: storage?.prefix || 'pic', ...storage, } as StorageConfig); - const store = createClientStore({ requestMiddleware, logger: log }); + if (sharedStore && requestMiddleware?.length) { + log.warn( + '`requestMiddleware` is ignored when a `sharedStore` is provided. ' + + 'Pass request middleware to the davinci() or journey() factory that owns the store.', + ); + } + const store = sharedStore + ? injectIntoStore(sharedStore) + : createClientStore({ requestMiddleware, logger: log }); if (!config?.serverConfig?.wellknown) { return { @@ -140,34 +150,37 @@ export async function oidc({ } if (useParFlow) { - const result = await Micro.runPromiseExit( + const result = await Effect.runPromiseExit( createParAuthorizeUrlµ(wellknown, config, log, store, options).pipe( - Micro.tapError((err) => - Micro.sync(() => + Effect.tapError((err) => + Effect.sync(() => log.error(`PAR authorize.url() failed [${err.type}]: ${err.error}`, err), ), ), ), ); - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; - } else if (exitIsFail(result)) { - const authErr = result.cause.error; + } + const authUrlFailure = Cause.findErrorOption(result.cause); + if (Option.isSome(authUrlFailure)) { + const authErr = authUrlFailure.value; return { error: authErr.error, message: authErr.error_description, type: authErr.type, }; - } else { - const defect = causeIsDie(result.cause) ? result.cause.defect : undefined; - return { - error: 'PAR authorization failure', - message: - defect instanceof Error ? defect.message : String(defect ?? 'Unknown defect'), - type: 'auth_error', - }; } + const authUrlDefect = Cause.squash(result.cause); + return { + error: 'PAR authorization failure', + message: + authUrlDefect instanceof Error + ? authUrlDefect.message + : String(authUrlDefect ?? 'Unknown defect'), + type: 'auth_error', + }; } const optionsWithDefaults = { @@ -207,7 +220,7 @@ export async function oidc({ }; } - const result = await Micro.runPromiseExit( + const result = await Effect.runPromiseExit( authorizeµ( wellknown, config, @@ -218,19 +231,22 @@ export async function oidc({ ), ); - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; - } else if (exitIsFail(result)) { - return result.cause.error; - } else { - const defect = causeIsDie(result.cause) ? result.cause.defect : undefined; - return { - error: 'Authorization failure', - error_description: - defect instanceof Error ? defect.message : String(defect ?? 'Unknown defect'), - type: 'auth_error', - }; } + const bgAuthFailure = Cause.findErrorOption(result.cause); + if (Option.isSome(bgAuthFailure)) { + return bgAuthFailure.value; + } + const bgAuthDefect = Cause.squash(result.cause); + return { + error: 'Authorization failure', + error_description: + bgAuthDefect instanceof Error + ? bgAuthDefect.message + : String(bgAuthDefect ?? 'Unknown defect'), + type: 'auth_error', + }; }, }, /** @@ -269,14 +285,10 @@ export async function oidc({ endpoint: wellknown.token_endpoint, store, options, - }).pipe( - Micro.tap(async (tokens) => { - await storageClient.set(tokens); - }), - ); + }).pipe(Effect.tap((tokens) => Effect.promise(() => storageClient.set(tokens)))); - const result = await Micro.runPromiseExit(getTokensµ); - return handleMicroExit(result, 'Token Exchange failure', 'exchange_error'); + const result = await Effect.runPromiseExit(getTokensµ); + return handleExit(result, 'Token Exchange failure', 'exchange_error'); }, /** @@ -338,47 +350,54 @@ export async function oidc({ { ...(authorizeOptions ?? ({} as GetAuthorizationUrlOptions)), prompt: 'none' as const }, useParFlow, ).pipe( - Micro.flatMap((response): Micro.Micro => { - return buildTokenExchangeµ({ - code: response.code, - config, - log, - state: response.state, - endpoint: wellknown.token_endpoint, - store, - options: storageOptions, - }); - }), - Micro.tap(async (newTokens) => { - if (tokens && 'accessToken' in tokens) { - await store.dispatch( - oidcApi.endpoints.revoke.initiate({ - accessToken: tokens.accessToken, - clientId: config.clientId, - endpoint: wellknown.revocation_endpoint, - }), - ); - await storageClient.remove(); - } - await storageClient.set(newTokens); - }), + Effect.flatMap( + (response): Effect.Effect => { + return buildTokenExchangeµ({ + code: response.code, + config, + log, + state: response.state, + endpoint: wellknown.token_endpoint, + store, + options: storageOptions, + }); + }, + ), + Effect.tap((newTokens) => + Effect.promise(async () => { + if (tokens && 'accessToken' in tokens) { + await store.dispatch( + oidcApi.endpoints.revoke.initiate({ + accessToken: tokens.accessToken, + clientId: config.clientId, + endpoint: wellknown.revocation_endpoint, + }), + ); + await storageClient.remove(); + } + await storageClient.set(newTokens); + }), + ), ); - const result = await Micro.runPromiseExit(attemptAuthorizeGetTokensµ); + const result = await Effect.runPromiseExit(attemptAuthorizeGetTokensµ); - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; - } else if (exitIsFail(result)) { - return result.cause.error; - } else { - const defect = causeIsDie(result.cause) ? result.cause.defect : undefined; - return { - error: 'Background token renewal failed', - error_description: - defect instanceof Error ? defect.message : String(defect ?? 'Unknown defect'), - type: 'auth_error', - }; } + const tokenGetFailure = Cause.findErrorOption(result.cause); + if (Option.isSome(tokenGetFailure)) { + return tokenGetFailure.value; + } + const tokenGetDefect = Cause.squash(result.cause); + return { + error: 'Background token renewal failed', + error_description: + tokenGetDefect instanceof Error + ? tokenGetDefect.message + : String(tokenGetDefect ?? 'Unknown defect'), + type: 'auth_error', + }; }, /** * @method revoke @@ -406,7 +425,7 @@ export async function oidc({ }; } - const revokeµ = Micro.promise(() => + const revokeµ = Effect.promise(() => store.dispatch( oidcApi.endpoints.revoke.initiate({ accessToken: tokens.accessToken, @@ -415,7 +434,7 @@ export async function oidc({ }), ), ).pipe( - Micro.map(({ error }) => { + Effect.map(({ error }) => { if (error) { let message = 'An error occurred while revoking the token'; let status: number | string = 'unknown'; @@ -436,9 +455,9 @@ export async function oidc({ return null; }), // Delete local token and return combined results - Micro.flatMap((revokeResponse) => - Micro.promise(() => storageClient.remove()).pipe( - Micro.flatMap((deleteResponse) => { + Effect.flatMap((revokeResponse) => + Effect.promise(() => storageClient.remove()).pipe( + Effect.flatMap((deleteResponse) => { const isInnerRequestError = (revokeResponse && 'error' in revokeResponse) || (deleteResponse && 'error' in deleteResponse); @@ -449,21 +468,21 @@ export async function oidc({ revokeResponse, deleteResponse, }; - return Micro.fail(result); + return Effect.fail(result); } else { const result: RevokeSuccessResult = { revokeResponse: null, deleteResponse: null, }; - return Micro.succeed(result); + return Effect.succeed(result); } }), ), ), ); - const result = await Micro.runPromiseExit(revokeµ); - return handleMicroExit(result, 'Token revocation failure', 'auth_error'); + const result = await Effect.runPromiseExit(revokeµ); + return handleExit(result, 'Token revocation failure', 'auth_error'); }, }, @@ -497,7 +516,7 @@ export async function oidc({ }; } - const info = Micro.promise(() => + const info = Effect.promise(() => store.dispatch( oidcApi.endpoints.userInfo.initiate({ accessToken: tokens.accessToken, @@ -505,7 +524,7 @@ export async function oidc({ }), ), ).pipe( - Micro.flatMap(({ data, error }) => { + Effect.flatMap(({ data, error }) => { if (error) { let message = 'An error occurred while fetching user info'; let status: number | string = 'unknown'; @@ -515,19 +534,19 @@ export async function oidc({ if ('status' in error) { status = error.status; } - return Micro.fail({ + return Effect.fail({ error: 'User Info retrieval failure', message, type: 'auth_error', status, } as const); } - return Micro.succeed(data); + return Effect.succeed(data); }), ); - const result = await Micro.runPromiseExit(info); - return handleMicroExit(result, 'User Info retrieval failure', 'auth_error'); + const result = await Effect.runPromiseExit(info); + return handleExit(result, 'User Info retrieval failure', 'auth_error'); }, /** @@ -568,10 +587,10 @@ export async function oidc({ return createTokenError('no_id_token'); } - const result = await Micro.runPromiseExit( + const result = await Effect.runPromiseExit( logoutµ({ tokens, config, wellknown, store, storageClient }), ); - return handleMicroExit(result, 'Logout_Failure', 'auth_error'); + return handleExit(result, 'Logout_Failure', 'auth_error'); }, /** @@ -596,13 +615,13 @@ export async function oidc({ }; } - const micro = + const effect = options?.responseType === 'id_token' ? sessionCheckIdTokenµ(wellknown, config, store, storageClient, log, options) : sessionCheckNoneµ(wellknown, config, store, storageClient, log, options); - const result = await Micro.runPromiseExit(micro); - return handleMicroExit(result, 'Session check failure', 'unknown_error'); + const result = await Effect.runPromiseExit(effect); + return handleExit(result, 'Session check failure', 'unknown_error'); }, }, }; diff --git a/packages/oidc-client/src/lib/client.store.utils.ts b/packages/oidc-client/src/lib/client.store.utils.ts index be2f53eb7cb..8ffe671d9cf 100644 --- a/packages/oidc-client/src/lib/client.store.utils.ts +++ b/packages/oidc-client/src/lib/client.store.utils.ts @@ -4,10 +4,10 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ +import { wellknownApi } from '@forgerock/sdk-wellknown'; import { configureStore } from '@reduxjs/toolkit'; import { oidcApi } from './oidc.api.js'; -import { wellknownApi } from './wellknown.api.js'; import type { logger as loggerFn } from '@forgerock/sdk-logger'; import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; @@ -15,6 +15,37 @@ import type { GenericError } from '@forgerock/sdk-types'; import type { SerializedError } from '@reduxjs/toolkit'; import type { FetchBaseQueryError } from '@reduxjs/toolkit/query'; +/** + * Internal InjectableStore shape — mirrored from davinci/journey-client. + * Only used within oidc-client for the shared-store injection path. + */ +interface InjectableStore { + readonly store: ReturnType; + readonly rootReducer: { inject: (api: unknown) => void }; + readonly dynamicMiddleware: { addMiddleware: (...mw: unknown[]) => void }; +} + +/** + * Recovers the InjectableStore from an opaque SdkStore handle so oidc-client + * can inject its own reducer and middleware into a store owned by another client. + */ +function fromSdkStore(sdkStore: object): InjectableStore { + return sdkStore as unknown as InjectableStore; +} + +/** + * Lazily injects oidcApi reducer and middleware into a store that was created + * by davinci() or journey(). Safe to call multiple times — RTK deduplicates injections. + * The cast is safe: after injection, the store's state will contain the oidc and wellknown + * slices, matching the shape produced by createClientStore. + */ +export function injectIntoStore(sdkStore: object): ReturnType { + const { store, rootReducer, dynamicMiddleware } = fromSdkStore(sdkStore); + rootReducer.inject(oidcApi); + dynamicMiddleware.addMiddleware(oidcApi.middleware); + return store as unknown as ReturnType; +} + /** * @function createClientStore * @description Creates a Redux store configured with OIDC and well-known APIs. diff --git a/packages/oidc-client/src/lib/client.types.ts b/packages/oidc-client/src/lib/client.types.ts index 7e091b84fc9..c2b9979b2fb 100644 --- a/packages/oidc-client/src/lib/client.types.ts +++ b/packages/oidc-client/src/lib/client.types.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/oidc-client/src/lib/exchange.request.ts b/packages/oidc-client/src/lib/exchange.request.ts index 4edded807c0..863182727f1 100644 --- a/packages/oidc-client/src/lib/exchange.request.ts +++ b/packages/oidc-client/src/lib/exchange.request.ts @@ -1,10 +1,10 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { createValuesµ, handleTokenResponseµ, validateValuesµ } from './exchange.utils.js'; import { oidcApi } from './oidc.api.js'; @@ -34,22 +34,22 @@ export function buildTokenExchangeµ({ state, store, options, -}: BuildTokenExchangeµParams): Micro.Micro { +}: BuildTokenExchangeµParams): Effect.Effect { return createValuesµ(code, config, state, endpoint, options).pipe( - Micro.flatMap((options) => validateValuesµ(options)), - Micro.tap((options) => log.debug('Token exchange values created', options)), - Micro.tapError((options) => - Micro.sync(() => log.error('Error creating token exchange values', options)), + Effect.flatMap((options) => validateValuesµ(options)), + Effect.tap((options) => Effect.sync(() => log.debug('Token exchange values created', options))), + Effect.tapError((options) => + Effect.sync(() => log.error('Error creating token exchange values', options)), ), - Micro.flatMap((requestOptions) => - Micro.promise(() => store.dispatch(oidcApi.endpoints.exchange.initiate(requestOptions))), + Effect.flatMap((requestOptions) => + Effect.promise(() => store.dispatch(oidcApi.endpoints.exchange.initiate(requestOptions))), ), - Micro.flatMap(({ data, error }) => handleTokenResponseµ(data, error)), - Micro.tap((data) => log.debug('Token exchange response handled', data)), - Micro.tapError((error) => - Micro.sync(() => log.error('Error handling token exchange response', error)), + Effect.flatMap(({ data, error }) => handleTokenResponseµ(data, error)), + Effect.tap((data) => Effect.sync(() => log.debug('Token exchange response handled', data))), + Effect.tapError((error) => + Effect.sync(() => log.error('Error handling token exchange response', error)), ), - Micro.map((data) => { + Effect.map((data) => { const tokens = { accessToken: data.access_token, idToken: data.id_token, diff --git a/packages/oidc-client/src/lib/exchange.utils.test.ts b/packages/oidc-client/src/lib/exchange.utils.test.ts index 903b70829cb..b8272b15b06 100644 --- a/packages/oidc-client/src/lib/exchange.utils.test.ts +++ b/packages/oidc-client/src/lib/exchange.utils.test.ts @@ -1,11 +1,11 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ import { expect, it } from '@effect/vitest'; -import { Micro } from 'effect'; +import { Cause, Effect, Exit, Option } from 'effect'; import { handleTokenResponseµ, validateValuesµ } from './exchange.utils.js'; @@ -38,7 +38,7 @@ const storedValues: GetAuthorizationUrlOptions = { }; it.effect('validateValuesµ succeeds with TokenRequestOptions', () => - Micro.gen(function* () { + Effect.gen(function* () { const result = yield* validateValuesµ({ code, state, @@ -56,7 +56,7 @@ it.effect('validateValuesµ succeeds with TokenRequestOptions', () => ); it.effect('validateValuesµ with verifier succeeds with TokenRequestOptions', () => - Micro.gen(function* () { + Effect.gen(function* () { const verifier = 'verifier123'; const result = yield* validateValuesµ({ code, @@ -79,8 +79,8 @@ it.effect('validateValuesµ with verifier succeeds with TokenRequestOptions', () ); it.effect('validateValuesµ fails with state mismatch', () => - Micro.gen(function* () { - const result = yield* Micro.exit( + Effect.gen(function* () { + const result = yield* Effect.exit( validateValuesµ({ code, state: 'abcState', @@ -93,14 +93,17 @@ it.effect('validateValuesµ fails with state mismatch', () => }), ); - expect(result).toStrictEqual( - Micro.fail({ - error: 'State mismatch', - message: - 'The provided state does not match the stored state. This is likely due to passing in used, returned, authorize parameters.', - type: 'state_error', - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + expect(Option.isSome(errorOpt)).toBe(true); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value).toStrictEqual({ + error: 'State mismatch', + message: + 'The provided state does not match the stored state. This is likely due to passing in used, returned, authorize parameters.', + type: 'state_error', + }); }), ); @@ -110,7 +113,7 @@ it.effect('handleTokenResponseµ with data succeeds', () => { id_token: '67890', }; - return Micro.gen(function* () { + return Effect.gen(function* () { const result = yield* handleTokenResponseµ(data); expect(result).toStrictEqual(data); @@ -118,35 +121,41 @@ it.effect('handleTokenResponseµ with data succeeds', () => { }); it.effect('handleTokenResponseµ with no data fails', () => { - return Micro.gen(function* () { - const result = yield* Micro.exit(handleTokenResponseµ(undefined)); - - expect(result).toStrictEqual( - Micro.fail({ - error: 'Token Exchange failure', - message: 'No data returned from token exchange', - type: 'exchange_error', - }), - ); + return Effect.gen(function* () { + const result = yield* Effect.exit(handleTokenResponseµ(undefined)); + + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + expect(Option.isSome(errorOpt)).toBe(true); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value).toStrictEqual({ + error: 'Token Exchange failure', + message: 'No data returned from token exchange', + type: 'exchange_error', + }); }); }); it.effect('handleTokenResponseµ with error fails', () => { const errMessage = 'Fetch error message'; - return Micro.gen(function* () { - const result = yield* Micro.exit( + return Effect.gen(function* () { + const result = yield* Effect.exit( handleTokenResponseµ(undefined, { status: 'FETCH_ERROR', error: errMessage, }), ); - expect(result).toStrictEqual( - Micro.fail({ - error: 'Token Exchange failure', - message: errMessage, - type: 'exchange_error', - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + expect(Option.isSome(errorOpt)).toBe(true); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value).toStrictEqual({ + error: 'Token Exchange failure', + message: errMessage, + type: 'exchange_error', + }); }); }); diff --git a/packages/oidc-client/src/lib/exchange.utils.ts b/packages/oidc-client/src/lib/exchange.utils.ts index 6cb64234767..4ccebbf111f 100644 --- a/packages/oidc-client/src/lib/exchange.utils.ts +++ b/packages/oidc-client/src/lib/exchange.utils.ts @@ -1,11 +1,11 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ import { getStoredAuthUrlValues } from '@forgerock/sdk-oidc'; -import { Micro } from 'effect'; +import { Effect } from 'effect'; import type { GetAuthorizationUrlOptions } from '@forgerock/sdk-types'; import type { StorageConfig } from '@forgerock/storage'; @@ -23,7 +23,7 @@ export function createValuesµ( endpoint: string, options?: Partial, ) { - return Micro.sync(() => { + return Effect.sync(() => { const storedValues = getStoredAuthUrlValues(config.clientId, options?.prefix); return { @@ -39,7 +39,7 @@ export function createValuesµ( export function handleTokenResponseµ( data: TokenExchangeResponse | undefined, error?: FetchBaseQueryError | SerializedError, -): Micro.Micro { +): Effect.Effect { if (error) { let message; if ('status' in error) { @@ -48,7 +48,7 @@ export function handleTokenResponseµ( message = error.message; } - return Micro.fail({ + return Effect.fail({ error: 'Token Exchange failure', message: message || 'Unknown error during token exchange', type: 'exchange_error', @@ -56,14 +56,14 @@ export function handleTokenResponseµ( } if (!data) { - return Micro.fail({ + return Effect.fail({ error: 'Token Exchange failure', message: 'No data returned from token exchange', type: 'exchange_error', } as TokenExchangeErrorResponse); } - return Micro.succeed(data); + return Effect.succeed(data); } export function validateValuesµ({ @@ -87,9 +87,9 @@ export function validateValuesµ({ type: 'state_error', } as const; - return Micro.fail(err); + return Effect.fail(err); } - return Micro.succeed({ + return Effect.succeed({ code, config, endpoint, diff --git a/packages/oidc-client/src/lib/logout.request.test.ts b/packages/oidc-client/src/lib/logout.request.test.ts index e0591ceebac..df51827f76e 100644 --- a/packages/oidc-client/src/lib/logout.request.test.ts +++ b/packages/oidc-client/src/lib/logout.request.test.ts @@ -6,7 +6,7 @@ */ import { logger as loggerFn } from '@forgerock/sdk-logger'; import { createStorage } from '@forgerock/storage'; -import { Micro } from 'effect'; +import { Cause, Effect, Exit, Option } from 'effect'; import { http, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; import { deepStrictEqual } from 'node:assert'; @@ -103,8 +103,8 @@ const partialWellknown = { describe('signOutRedirectUri', () => { it('logoutµ appends post_logout_redirect_uri when signOutRedirectUri is set in config', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const end_session_endpoint = 'https://example.com/am/oauth2/alpha/connect/endSession'; const revocation_endpoint = 'https://example.com/am/oauth2/alpha/token/revoke'; let capturedUrl = ''; @@ -134,8 +134,8 @@ describe('signOutRedirectUri', () => { )); it('logoutµ omits post_logout_redirect_uri when signOutRedirectUri is absent', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const end_session_endpoint = 'https://example.com/am/oauth2/alpha/connect/endSession'; const revocation_endpoint = 'https://example.com/am/oauth2/alpha/token/revoke'; let capturedUrl = ''; @@ -167,8 +167,8 @@ describe('signOutRedirectUri', () => { describe('Ping AM', () => { it('logoutµ succeeds with valid wellknown endpoints', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const end_session_endpoint = 'https://example.com/am/oauth2/alpha/connect/endSession'; const revocation_endpoint = 'https://example.com/am/oauth2/alpha/token/revoke'; @@ -193,12 +193,12 @@ describe('Ping AM', () => { )); it('logoutµ fails on bad endSession', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const end_session_endpoint = 'https://example.com/am/oauth2/fake-realm/connect/endSession'; const revocation_endpoint = 'https://example.com/am/oauth2/alpha/token/revoke'; - const result = yield* Micro.exit( + const result = yield* Effect.exit( logoutµ({ tokens, config, @@ -212,30 +212,31 @@ describe('Ping AM', () => { }), ); - deepStrictEqual( - result, - Micro.exitFail({ - error: 'Inner request error', - sessionResponse: { - error: 'End Session failure', - message: 'An error occurred while ending the session', - type: 'auth_error', - status: 400, - }, - revokeResponse: null, - deleteResponse: null, - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + deepStrictEqual(errorOpt.value, { + error: 'Inner request error', + sessionResponse: { + error: 'End Session failure', + message: 'An error occurred while ending the session', + type: 'auth_error', + status: 400, + }, + revokeResponse: null, + deleteResponse: null, + }); }), )); it('logoutµ fails on bad revoke', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const end_session_endpoint = 'https://example.com/am/oauth2/alpha/connect/endSession'; const revocation_endpoint = 'https://example.com/am/oauth2/fake-realm/token/revoke'; - const result = yield* Micro.exit( + const result = yield* Effect.exit( logoutµ({ tokens, config, @@ -249,20 +250,21 @@ describe('Ping AM', () => { }), ); - deepStrictEqual( - result, - Micro.exitFail({ - error: 'Inner request error', - sessionResponse: null, - revokeResponse: { - error: 'End Session failure', - message: 'An error occurred while ending the session', - type: 'auth_error', - status: 400, - }, - deleteResponse: null, - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + deepStrictEqual(errorOpt.value, { + error: 'Inner request error', + sessionResponse: null, + revokeResponse: { + error: 'End Session failure', + message: 'An error occurred while ending the session', + type: 'auth_error', + status: 400, + }, + deleteResponse: null, + }); }), )); }); @@ -271,8 +273,8 @@ describe('PingOne', () => { const fakeEndSessionEndpoint = 'https://example.com/endSession'; it('logoutµ succeeds with valid wellknown endpoints', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const ping_end_idp_session_endpoint = 'https://example.com/as/idpSignoff'; const revocation_endpoint = 'https://example.com/as/revoke'; @@ -298,12 +300,12 @@ describe('PingOne', () => { )); it('logoutµ fails on bad endSession', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const ping_end_idp_session_endpoint = 'https://example.com/as/badIdpSignoff'; const revocation_endpoint = 'https://example.com/as/revoke'; - const result = yield* Micro.exit( + const result = yield* Effect.exit( logoutµ({ tokens, config, @@ -318,30 +320,31 @@ describe('PingOne', () => { }), ); - deepStrictEqual( - result, - Micro.exitFail({ - error: 'Inner request error', - sessionResponse: { - error: 'End Session failure', - message: 'An error occurred while ending the session', - type: 'auth_error', - status: 400, - }, - revokeResponse: null, - deleteResponse: null, - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + deepStrictEqual(errorOpt.value, { + error: 'Inner request error', + sessionResponse: { + error: 'End Session failure', + message: 'An error occurred while ending the session', + type: 'auth_error', + status: 400, + }, + revokeResponse: null, + deleteResponse: null, + }); }), )); it('logoutµ fails on bad revoke', () => - Micro.runPromise( - Micro.gen(function* () { + Effect.runPromise( + Effect.gen(function* () { const ping_end_idp_session_endpoint = 'https://example.com/as/idpSignoff'; const revocation_endpoint = 'https://example.com/as/badRevoke'; - const result = yield* Micro.exit( + const result = yield* Effect.exit( logoutµ({ tokens, config, @@ -356,20 +359,21 @@ describe('PingOne', () => { }), ); - deepStrictEqual( - result, - Micro.exitFail({ - error: 'Inner request error', - sessionResponse: null, - revokeResponse: { - error: 'End Session failure', - message: 'An error occurred while ending the session', - type: 'auth_error', - status: 400, - }, - deleteResponse: null, - }), - ); + expect(Exit.isFailure(result)).toBe(true); + if (!Exit.isFailure(result)) return; + const errorOpt = Cause.findErrorOption(result.cause); + if (!Option.isSome(errorOpt)) return; + deepStrictEqual(errorOpt.value, { + error: 'Inner request error', + sessionResponse: null, + revokeResponse: { + error: 'End Session failure', + message: 'An error occurred while ending the session', + type: 'auth_error', + status: 400, + }, + deleteResponse: null, + }); }), )); }); diff --git a/packages/oidc-client/src/lib/logout.request.ts b/packages/oidc-client/src/lib/logout.request.ts index 6804d9fea61..935fafd3a79 100644 --- a/packages/oidc-client/src/lib/logout.request.ts +++ b/packages/oidc-client/src/lib/logout.request.ts @@ -4,7 +4,7 @@ * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { createLogoutError } from './client.store.utils.js'; import { oidcApi } from './oidc.api.js'; @@ -28,9 +28,9 @@ export function logoutµ({ store: ClientStore; storageClient: StorageClient; }) { - return Micro.zip( + return Effect.zip( // End session with the ID token - Micro.promise(() => + Effect.promise(() => store.dispatch( oidcApi.endpoints.endSession.initiate({ idToken: tokens.idToken, @@ -38,10 +38,10 @@ export function logoutµ({ signOutRedirectUri: config.signOutRedirectUri, }), ), - ).pipe(Micro.map(({ data, error }) => createLogoutError(data, error))), + ).pipe(Effect.map(({ data, error }) => createLogoutError(data, error))), // Revoke the access token - Micro.promise(() => + Effect.promise(() => store.dispatch( oidcApi.endpoints.revoke.initiate({ accessToken: tokens.accessToken, @@ -49,12 +49,12 @@ export function logoutµ({ endpoint: wellknown.revocation_endpoint, }), ), - ).pipe(Micro.map(({ data, error }) => createLogoutError(data, error))), + ).pipe(Effect.map(({ data, error }) => createLogoutError(data, error))), ).pipe( // Delete local token and return combined results - Micro.flatMap(([sessionResponse, revokeResponse]) => - Micro.promise(() => storageClient.remove()).pipe( - Micro.flatMap((deleteResponse) => { + Effect.flatMap(([sessionResponse, revokeResponse]) => + Effect.promise(() => storageClient.remove()).pipe( + Effect.flatMap((deleteResponse) => { const isInnerRequestError = (sessionResponse && 'error' in sessionResponse) || (revokeResponse && 'error' in revokeResponse) || @@ -67,14 +67,14 @@ export function logoutµ({ revokeResponse, deleteResponse, }; - return Micro.fail(result); + return Effect.fail(result); } else { const result: LogoutSuccessResult = { sessionResponse: null, revokeResponse: null, deleteResponse: null, }; - return Micro.succeed(result); + return Effect.succeed(result); } }), ), diff --git a/packages/oidc-client/src/lib/oidc.api.ts b/packages/oidc-client/src/lib/oidc.api.ts index 7618f86285e..9c798c80f44 100644 --- a/packages/oidc-client/src/lib/oidc.api.ts +++ b/packages/oidc-client/src/lib/oidc.api.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright © 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/oidc-client/src/lib/oidc.api.utils.ts b/packages/oidc-client/src/lib/oidc.api.utils.ts index 9e85a69b3ba..47e27041738 100644 --- a/packages/oidc-client/src/lib/oidc.api.utils.ts +++ b/packages/oidc-client/src/lib/oidc.api.utils.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/oidc-client/src/lib/session.micros.test.ts b/packages/oidc-client/src/lib/session.micros.test.ts index 12817cb8c1e..add027cb0c8 100644 --- a/packages/oidc-client/src/lib/session.micros.test.ts +++ b/packages/oidc-client/src/lib/session.micros.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2026 Ping Identity Corporation. All rights reserved. + * Copyright © 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -7,7 +7,7 @@ import { expect, it } from '@effect/vitest'; import { logger as loggerFn } from '@forgerock/sdk-logger'; import * as sdkUtilities from '@forgerock/sdk-utilities'; -import { Micro } from 'effect'; +import { Cause, Effect, Exit, Option } from 'effect'; import { afterEach, describe, vi } from 'vitest'; import { oidcApi } from './oidc.api.js'; @@ -182,32 +182,32 @@ describe('buildIdTokenUrl', () => { // ─── sessionCheckNoneµ (iframe path — with redirect_uri) ────────────────────── it.effect('sessionCheckNoneµ uses iframe path and succeeds when redirect_uri is configured', () => - Micro.gen(function* () { + Effect.gen(function* () { const { store, dispatch } = makeDispatchSetup({ data: { params: {} } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckNoneµ(wellknown, config, store, makeStorageClient(storedTokens), log), ); - expect(Micro.exitIsSuccess(exit)).toBe(true); + expect(Exit.isSuccess(exit)).toBe(true); expect(dispatch).toHaveBeenCalledOnce(); }), ); it.effect('sessionCheckNoneµ iframe path fails with no_id_token_hint when storage is empty', () => - Micro.gen(function* () { + Effect.gen(function* () { const { store, dispatch } = makeDispatchSetup({ data: { params: {} } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckNoneµ(wellknown, config, store, makeStorageClient(null), log), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('no_id_token_hint'); - expect(exit.cause.error.type).toBe('argument_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('no_id_token_hint'); + expect(errorOpt.value.type).toBe('argument_error'); expect(dispatch).not.toHaveBeenCalled(); }), ); @@ -215,11 +215,11 @@ it.effect('sessionCheckNoneµ iframe path fails with no_id_token_hint when stora // ─── sessionCheckNoneµ (fetch path — without redirect_uri) ─────────────────── it.effect('sessionCheckNoneµ uses fetch path and succeeds when no redirect_uri is configured', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithoutRedirectUri: OidcConfig = { ...config, redirectUri: '' }; const { store, dispatch } = makeFetchDispatchSetup({ data: { status: 204 } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckNoneµ( wellknown, configWithoutRedirectUri, @@ -229,36 +229,34 @@ it.effect('sessionCheckNoneµ uses fetch path and succeeds when no redirect_uri ), ); - expect(Micro.exitIsSuccess(exit)).toBe(true); - if (!Micro.exitIsSuccess(exit)) { - return; - } + expect(Exit.isSuccess(exit)).toBe(true); + if (!Exit.isSuccess(exit)) return; expect(exit.value).toStrictEqual({ responseType: 'none' }); expect(dispatch).toHaveBeenCalledOnce(); }), ); it.effect('sessionCheckNoneµ fetch path fails with no_id_token_hint when storage is empty', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithoutRedirectUri: OidcConfig = { ...config, redirectUri: '' }; const { store, dispatch } = makeFetchDispatchSetup({ data: { status: 204 } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckNoneµ(wellknown, configWithoutRedirectUri, store, makeStorageClient(null), log), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('no_id_token_hint'); - expect(exit.cause.error.type).toBe('argument_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('no_id_token_hint'); + expect(errorOpt.value.type).toBe('argument_error'); expect(dispatch).not.toHaveBeenCalled(); }), ); it.effect('sessionCheckNoneµ fetch path fails with login_required when AM returns 400', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithoutRedirectUri: OidcConfig = { ...config, redirectUri: '' }; const errorData: GenericError = { error: 'login_required', @@ -267,7 +265,7 @@ it.effect('sessionCheckNoneµ fetch path fails with login_required when AM retur }; const { store } = makeFetchDispatchSetup({ error: { data: errorData } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckNoneµ( wellknown, configWithoutRedirectUri, @@ -277,26 +275,26 @@ it.effect('sessionCheckNoneµ fetch path fails with login_required when AM retur ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('login_required'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('login_required'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); // ─── dispatchSessionCheckFetchµ ─────────────────────────────────────────────── it.effect('dispatchSessionCheckFetchµ succeeds when dispatch resolves with data', () => - Micro.gen(function* () { + Effect.gen(function* () { const { store, dispatch } = makeFetchDispatchSetup({ data: { status: 204 } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckFetchµ(store, 'https://example.com/authorize?prompt=none'), ); - expect(Micro.exitIsSuccess(exit)).toBe(true); + expect(Exit.isSuccess(exit)).toBe(true); expect(dispatch).toHaveBeenCalledOnce(); }), ); @@ -304,7 +302,7 @@ it.effect('dispatchSessionCheckFetchµ succeeds when dispatch resolves with data it.effect( 'dispatchSessionCheckFetchµ fails with auth_error when dispatch resolves with an error result', () => - Micro.gen(function* () { + Effect.gen(function* () { const errorData: GenericError = { error: 'login_required', message: 'The request requires login.', @@ -312,21 +310,21 @@ it.effect( }; const { store } = makeFetchDispatchSetup({ error: { data: errorData } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckFetchµ(store, 'https://example.com/authorize?prompt=none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('login_required'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('login_required'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('dispatchSessionCheckFetchµ fails with network_error when dispatch rejects', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(oidcApi.endpoints.sessionCheckFetch, 'initiate').mockReturnValue( Symbol('sentinel') as unknown as ReturnType< typeof oidcApi.endpoints.sessionCheckFetch.initiate @@ -335,23 +333,23 @@ it.effect('dispatchSessionCheckFetchµ fails with network_error when dispatch re const dispatch = vi.fn().mockRejectedValue(new Error('network failure')); const store: ClientStore = { dispatch } as unknown as ClientStore; - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckFetchµ(store, 'https://example.com/authorize?prompt=none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.type).toBe('network_error'); - expect(exit.cause.error.error).toBe('dispatch_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('network_error'); + expect(errorOpt.value.error).toBe('dispatch_error'); }), ); it.effect( 'dispatchSessionCheckFetchµ fails with network_error when queryFn receives a string-status error (e.g. FETCH_ERROR)', () => - Micro.gen(function* () { + Effect.gen(function* () { const errorData: GenericError = { error: 'session_check_error', message: 'A network error occurred during session check', @@ -359,23 +357,23 @@ it.effect( }; const { store } = makeFetchDispatchSetup({ error: { data: errorData } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckFetchµ(store, 'https://example.com/authorize?prompt=none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('session_check_error'); - expect(exit.cause.error.type).toBe('network_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('session_check_error'); + expect(errorOpt.value.type).toBe('network_error'); }), ); it.effect( 'dispatchSessionCheckFetchµ fails with network_error when queryFn receives an unexpected 2xx status', () => - Micro.gen(function* () { + Effect.gen(function* () { const errorData: GenericError = { error: 'session_check_error', message: 'Unexpected response status: 200', @@ -383,23 +381,23 @@ it.effect( }; const { store } = makeFetchDispatchSetup({ error: { data: errorData } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckFetchµ(store, 'https://example.com/authorize?prompt=none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('session_check_error'); - expect(exit.cause.error.type).toBe('network_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('session_check_error'); + expect(errorOpt.value.type).toBe('network_error'); }), ); // ─── sessionCheckIdTokenµ ───────────────────────────────────────────────────── it.effect('sessionCheckIdTokenµ returns claims on valid JWT', () => - Micro.gen(function* () { + Effect.gen(function* () { const knownNonce = 'test-nonce-value-12345678901234'; const knownState = 'known-state-value'; vi.spyOn(sdkUtilities, 'createRandomString').mockReturnValue(knownNonce); @@ -416,72 +414,68 @@ it.effect('sessionCheckIdTokenµ returns claims on valid JWT', () => data: { params: { id_token: validJwt, state: knownState } }, }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckIdTokenµ(wellknown, config, store, makeStorageClient(storedTokens), log), ); - expect(Micro.exitIsSuccess(exit)).toBe(true); - if (!Micro.exitIsSuccess(exit)) { - return; - } + expect(Exit.isSuccess(exit)).toBe(true); + if (!Exit.isSuccess(exit)) return; expect(exit.value.responseType).toBe('id_token'); expect(exit.value.claims).toBeDefined(); - if (!exit.value.claims) { - return; - } + if (!exit.value.claims) return; expect(exit.value.claims['nonce']).toBe(knownNonce); }), ); it.effect('sessionCheckIdTokenµ fails with state_mismatch when response state does not match', () => - Micro.gen(function* () { + Effect.gen(function* () { vi.spyOn(sdkUtilities, 'createState').mockReturnValue('known-state-value'); const { store } = makeDispatchSetup({ data: { params: { id_token: 'some.jwt.token', state: 'tampered-state' } }, }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckIdTokenµ(wellknown, config, store, makeStorageClient(storedTokens), log), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('state_mismatch'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('state_mismatch'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('sessionCheckIdTokenµ fails with no_id_token when iframe returns no id_token param', () => - Micro.gen(function* () { + Effect.gen(function* () { const knownState = 'known-state-value'; vi.spyOn(sdkUtilities, 'createState').mockReturnValue(knownState); const { store } = makeDispatchSetup({ data: { params: { state: knownState } } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckIdTokenµ(wellknown, config, store, makeStorageClient(storedTokens), log), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('no_id_token'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('no_id_token'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect( 'sessionCheckIdTokenµ fails with missing_redirect_uri when no redirect_uri is configured', () => - Micro.gen(function* () { + Effect.gen(function* () { const configWithoutRedirectUri: OidcConfig = { ...config, redirectUri: '' }; const { store, dispatch } = makeDispatchSetup({ data: { params: {} } }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( sessionCheckIdTokenµ( wellknown, configWithoutRedirectUri, @@ -491,12 +485,12 @@ it.effect( ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('missing_redirect_uri'); - expect(exit.cause.error.type).toBe('argument_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('missing_redirect_uri'); + expect(errorOpt.value.type).toBe('argument_error'); expect(dispatch).not.toHaveBeenCalled(); }), ); @@ -504,33 +498,33 @@ it.effect( // ─── readStoredIdTokenµ ─────────────────────────────────────────────────────── it.effect('readStoredIdTokenµ returns idToken string when tokens are stored', () => - Micro.gen(function* () { + Effect.gen(function* () { const result = yield* readStoredIdTokenµ(makeStorageClient(storedTokens)); expect(result).toBe(storedTokens.idToken); }), ); it.effect('readStoredIdTokenµ returns null when storage is empty', () => - Micro.gen(function* () { + Effect.gen(function* () { const result = yield* readStoredIdTokenµ(makeStorageClient(null)); expect(result).toBeNull(); }), ); it.effect('readStoredIdTokenµ fails with argument_error when storageClient.get rejects', () => - Micro.gen(function* () { + Effect.gen(function* () { const failingStorage: StorageClient = { get: vi.fn().mockRejectedValue(new Error('storage unavailable')), set: vi.fn(), remove: vi.fn(), }; - const exit = yield* Micro.exit(readStoredIdTokenµ(failingStorage)); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.type).toBe('argument_error'); - expect(exit.cause.error.error).toBe('storage_error'); + const exit = yield* Effect.exit(readStoredIdTokenµ(failingStorage)); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('argument_error'); + expect(errorOpt.value.error).toBe('storage_error'); }), ); @@ -539,7 +533,7 @@ it.effect('readStoredIdTokenµ fails with argument_error when storageClient.get it.effect( 'dispatchSessionCheckIframeµ succeeds and returns params when dispatch resolves with data', () => - Micro.gen(function* () { + Effect.gen(function* () { const params = { state: 'ok' }; const dispatch = vi.fn().mockResolvedValue({ data: { params } }); const store: ClientStore = { dispatch } as unknown as ClientStore; @@ -561,7 +555,7 @@ it.effect( it.effect( 'dispatchSessionCheckIframeµ fails with auth_error when dispatch resolves with an error result', () => - Micro.gen(function* () { + Effect.gen(function* () { const errorData: GenericError = { error: 'login_required', message: 'User must authenticate', @@ -575,20 +569,20 @@ it.effect( >, ); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckIframeµ(store, 'https://example.com/authorize?prompt=none', 'none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('login_required'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('login_required'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('dispatchSessionCheckIframeµ fails with network_error when dispatch rejects', () => - Micro.gen(function* () { + Effect.gen(function* () { const dispatch = vi.fn().mockRejectedValue(new Error('network failure')); const store: ClientStore = { dispatch } as unknown as ClientStore; vi.spyOn(oidcApi.endpoints.sessionCheckIframe, 'initiate').mockReturnValue( @@ -597,15 +591,15 @@ it.effect('dispatchSessionCheckIframeµ fails with network_error when dispatch r >, ); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( dispatchSessionCheckIframeµ(store, 'https://example.com/authorize?prompt=none', 'none'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.type).toBe('network_error'); - expect(exit.cause.error.error).toBe('dispatch_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.type).toBe('network_error'); + expect(errorOpt.value.error).toBe('dispatch_error'); }), ); @@ -622,7 +616,7 @@ function makeJwtWithClaims(claims: JWTPayload): string { it.effect( 'validateSessionCheckResponseµ succeeds and returns claims when state and nonce match', () => - Micro.gen(function* () { + Effect.gen(function* () { const nonce = 'expected-nonce'; const state = 'expected-state'; const jwt = makeJwtWithClaims({ nonce, sub: 'user1' }); @@ -632,7 +626,7 @@ it.effect( ); it.effect('validateSessionCheckResponseµ succeeds when state, nonce, and subject all match', () => - Micro.gen(function* () { + Effect.gen(function* () { const nonce = 'nonce-abc'; const state = 'state-abc'; const jwt = makeJwtWithClaims({ nonce, sub: 'user1' }); @@ -647,81 +641,81 @@ it.effect('validateSessionCheckResponseµ succeeds when state, nonce, and subjec ); it.effect('validateSessionCheckResponseµ fails with state_mismatch when state does not match', () => - Micro.gen(function* () { + Effect.gen(function* () { const jwt = makeJwtWithClaims({ nonce: 'nonce', sub: 'user1' }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( validateSessionCheckResponseµ( { id_token: jwt, state: 'tampered' }, 'expected-state', 'nonce', ), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('state_mismatch'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('state_mismatch'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('validateSessionCheckResponseµ fails with no_id_token when id_token is absent', () => - Micro.gen(function* () { + Effect.gen(function* () { const state = 'expected-state'; - const exit = yield* Micro.exit(validateSessionCheckResponseµ({ state }, state, 'nonce')); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('no_id_token'); - expect(exit.cause.error.type).toBe('auth_error'); + const exit = yield* Effect.exit(validateSessionCheckResponseµ({ state }, state, 'nonce')); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('no_id_token'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('validateSessionCheckResponseµ fails with nonce_mismatch when nonce does not match', () => - Micro.gen(function* () { + Effect.gen(function* () { const state = 'expected-state'; const jwt = makeJwtWithClaims({ nonce: 'wrong-nonce', sub: 'user1' }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( validateSessionCheckResponseµ({ id_token: jwt, state }, state, 'expected-nonce'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('nonce_mismatch'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('nonce_mismatch'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('validateSessionCheckResponseµ fails with subject_mismatch when sub does not match', () => - Micro.gen(function* () { + Effect.gen(function* () { const nonce = 'valid-nonce'; const state = 'expected-state'; const jwt = makeJwtWithClaims({ nonce, sub: 'user2' }); - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( validateSessionCheckResponseµ({ id_token: jwt, state }, state, nonce, 'user1'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('subject_mismatch'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('subject_mismatch'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); it.effect('validateSessionCheckResponseµ fails with invalid_jwt when JWT is malformed', () => - Micro.gen(function* () { + Effect.gen(function* () { const state = 'expected-state'; - const exit = yield* Micro.exit( + const exit = yield* Effect.exit( validateSessionCheckResponseµ({ id_token: 'not.a.valid.jwt.payload', state }, state, 'nonce'), ); - expect(Micro.exitIsFailure(exit)).toBe(true); - if (!Micro.exitIsFailure(exit) || !Micro.causeIsFail(exit.cause)) { - return; - } - expect(exit.cause.error.error).toBe('invalid_jwt'); - expect(exit.cause.error.type).toBe('auth_error'); + expect(Exit.isFailure(exit)).toBe(true); + if (!Exit.isFailure(exit)) return; + const errorOpt = Cause.findErrorOption(exit.cause); + if (!Option.isSome(errorOpt)) return; + expect(errorOpt.value.error).toBe('invalid_jwt'); + expect(errorOpt.value.type).toBe('auth_error'); }), ); diff --git a/packages/oidc-client/src/lib/session.micros.ts b/packages/oidc-client/src/lib/session.micros.ts index 7c61f25ffa3..753b8ba21dd 100644 --- a/packages/oidc-client/src/lib/session.micros.ts +++ b/packages/oidc-client/src/lib/session.micros.ts @@ -1,11 +1,11 @@ /* - * Copyright (c) 2026 Ping Identity Corporation. All rights reserved. + * Copyright © 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ import { createRandomString, createState } from '@forgerock/sdk-utilities'; -import { Micro } from 'effect'; +import { Effect } from 'effect'; import { decodeJwt } from 'jose/jwt/decode'; import { oidcApi } from './oidc.api.js'; @@ -23,15 +23,15 @@ import type { SessionCheckOptions, SessionCheckSuccess } from './session.types.j export const readStoredIdTokenµ = ( storageClient: StorageClient, -): Micro.Micro => - Micro.tryPromise({ +): Effect.Effect => + Effect.tryPromise({ try: () => storageClient.get(), catch: (): GenericError => ({ error: 'storage_error', message: 'Failed to read tokens from storage', type: 'argument_error', }), - }).pipe(Micro.map((tokens) => (tokens && 'idToken' in tokens ? tokens.idToken : null))); + }).pipe(Effect.map((tokens) => (tokens && 'idToken' in tokens ? tokens.idToken : null))); // ─── Dispatch ──────────────────────────────────────────────────────────────── @@ -39,8 +39,8 @@ export const dispatchSessionCheckIframeµ = ( store: ClientStore, url: string, responseType: 'id_token' | 'none', -): Micro.Micro, GenericError, never> => - Micro.tryPromise({ +): Effect.Effect, GenericError, never> => + Effect.tryPromise({ try: () => store.dispatch(oidcApi.endpoints.sessionCheckIframe.initiate({ url, responseType })), catch: (err): GenericError => ({ error: 'dispatch_error', @@ -48,27 +48,27 @@ export const dispatchSessionCheckIframeµ = ( type: 'network_error', }), }).pipe( - Micro.flatMap((result) => { + Effect.flatMap((result) => { if ('error' in result && result.error) { const errData = result.error as { data?: { error?: string; message?: string; type?: string }; }; - return Micro.fail({ + return Effect.fail({ error: errData.data?.error ?? 'session_check_error', message: errData.data?.message ?? 'An error occurred during session check', type: (errData.data?.type as GenericError['type']) ?? 'network_error', }); } const { params } = (result as { data: { params: Record } }).data; - return Micro.succeed(params); + return Effect.succeed(params); }), ); export const dispatchSessionCheckFetchµ = ( store: ClientStore, url: string, -): Micro.Micro => - Micro.tryPromise({ +): Effect.Effect => + Effect.tryPromise({ try: () => store.dispatch(oidcApi.endpoints.sessionCheckFetch.initiate({ url })), catch: (err): GenericError => ({ error: 'dispatch_error', @@ -76,18 +76,18 @@ export const dispatchSessionCheckFetchµ = ( type: 'network_error', }), }).pipe( - Micro.flatMap((result) => { + Effect.flatMap((result) => { if ('error' in result && result.error) { const errData = result.error as { data?: { error?: string; message?: string; type?: string }; }; - return Micro.fail({ + return Effect.fail({ error: errData.data?.error ?? 'login_required', message: errData.data?.message ?? 'The request requires login.', type: (errData.data?.type as GenericError['type']) ?? 'auth_error', }); } - return Micro.void; + return Effect.void; }), ); @@ -98,10 +98,10 @@ export const validateSessionCheckResponseµ = ( state: string, nonce: string, subject?: string, -): Micro.Micro => { - return Micro.gen(function* () { +): Effect.Effect => { + return Effect.gen(function* () { if (iframeParams.state !== state) { - return yield* Micro.fail({ + return yield* Effect.fail({ error: 'state_mismatch', message: 'State parameter in response does not match the expected value', type: 'auth_error', @@ -110,14 +110,14 @@ export const validateSessionCheckResponseµ = ( const idToken = iframeParams.id_token; if (!idToken) { - return yield* Micro.fail({ + return yield* Effect.fail({ error: 'no_id_token', message: 'No id_token found in iframe response', type: 'auth_error', }); } - const claims = yield* Micro.try({ + const claims = yield* Effect.try({ try: () => decodeJwt(idToken), catch: (): GenericError => ({ error: 'invalid_jwt', @@ -127,7 +127,7 @@ export const validateSessionCheckResponseµ = ( }); if (claims.nonce !== nonce) { - return yield* Micro.fail({ + return yield* Effect.fail({ error: 'nonce_mismatch', message: 'Nonce in id_token does not match the expected value', type: 'auth_error', @@ -135,7 +135,7 @@ export const validateSessionCheckResponseµ = ( } if (subject !== undefined && claims.sub !== subject) { - return yield* Micro.fail({ + return yield* Effect.fail({ error: 'subject_mismatch', message: 'Subject claim in id_token does not match the expected value', type: 'auth_error', @@ -197,11 +197,11 @@ export const sessionCheckNoneµ = ( storageClient: StorageClient, log: CustomLogger, options?: SessionCheckOptions, -): Micro.Micro => { +): Effect.Effect => { return readStoredIdTokenµ(storageClient).pipe( - Micro.flatMap((storedIdToken) => { + Effect.flatMap((storedIdToken) => { if (!storedIdToken) { - return Micro.fail({ + return Effect.fail({ error: 'no_id_token_hint', message: 'response_type=none requires a stored id_token; authenticate first', type: 'argument_error', @@ -223,8 +223,8 @@ export const sessionCheckNoneµ = ( ? dispatchSessionCheckIframeµ(store, url, 'none') : dispatchSessionCheckFetchµ(store, url); }), - Micro.tap(() => log.debug('Session check (none) completed successfully')), - Micro.map((): SessionCheckSuccess => ({ responseType: 'none' })), + Effect.tap(() => Effect.sync(() => log.debug('Session check (none) completed successfully'))), + Effect.map((): SessionCheckSuccess => ({ responseType: 'none' })), ); }; @@ -237,11 +237,11 @@ export const sessionCheckIdTokenµ = ( storageClient: StorageClient, log: CustomLogger, options?: SessionCheckOptions, -): Micro.Micro => { +): Effect.Effect => { const redirectUri = options?.redirectUri ?? config.redirectUri; if (!redirectUri) { - return Micro.fail({ + return Effect.fail({ error: 'missing_redirect_uri', message: 'redirect_uri is required for session check with response_type=id_token', type: 'argument_error', @@ -249,7 +249,7 @@ export const sessionCheckIdTokenµ = ( } return readStoredIdTokenµ(storageClient).pipe( - Micro.flatMap((storedIdToken) => { + Effect.flatMap((storedIdToken) => { const { url, nonce, state } = buildIdTokenUrl( wellknown.authorization_endpoint, config, @@ -258,12 +258,14 @@ export const sessionCheckIdTokenµ = ( options, ); return dispatchSessionCheckIframeµ(store, url, 'id_token').pipe( - Micro.flatMap((iframeParams) => + Effect.flatMap((iframeParams) => validateSessionCheckResponseµ(iframeParams, state, nonce, options?.subject), ), ); }), - Micro.tap(() => log.debug('Session check (id_token) completed successfully')), - Micro.map((claims): SessionCheckSuccess => ({ responseType: 'id_token', claims })), + Effect.tap(() => + Effect.sync(() => log.debug('Session check (id_token) completed successfully')), + ), + Effect.map((claims): SessionCheckSuccess => ({ responseType: 'id_token', claims })), ); }; diff --git a/packages/oidc-client/src/lib/session.types.ts b/packages/oidc-client/src/lib/session.types.ts index 0611fa195f2..132c972250b 100644 --- a/packages/oidc-client/src/lib/session.types.ts +++ b/packages/oidc-client/src/lib/session.types.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2026 Ping Identity Corporation. All rights reserved. + * Copyright © 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/oidc-client/src/lib/shared-store.test.ts b/packages/oidc-client/src/lib/shared-store.test.ts new file mode 100644 index 00000000000..227a5eb0e35 --- /dev/null +++ b/packages/oidc-client/src/lib/shared-store.test.ts @@ -0,0 +1,290 @@ +// @vitest-environment node +/* + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ +import { wellknownApi } from '@forgerock/sdk-wellknown'; +import { combineSlices, configureStore, createDynamicMiddleware } from '@reduxjs/toolkit'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { oidc } from './client.store.js'; +import { injectIntoStore } from './client.store.utils.js'; +import { oidcApi } from './oidc.api.js'; + +import type { SdkStore } from '@forgerock/sdk-types'; + +import type { OidcConfig } from './config.types.js'; + +// --------------------------------------------------------------------------- +// Fixtures +// --------------------------------------------------------------------------- + +const TEST_WELLKNOWN_URL = + 'https://example.pingone.com/test-env/as/.well-known/openid-configuration'; + +const mockWellknownResponse = { + issuer: 'https://example.pingone.com/test-env/as', + authorization_endpoint: 'https://example.pingone.com/test-env/as/authorize', + token_endpoint: 'https://example.pingone.com/test-env/as/token', + userinfo_endpoint: 'https://example.pingone.com/test-env/as/userinfo', + jwks_uri: 'https://example.pingone.com/test-env/as/jwks', + revocation_endpoint: 'https://example.pingone.com/test-env/as/revoke', + introspection_endpoint: 'https://example.pingone.com/test-env/as/introspect', + pushed_authorization_request_endpoint: 'https://example.pingone.com/test-env/as/par', +}; + +const oidcConfig: OidcConfig = { + clientId: 'test-client-id', + redirectUri: 'http://localhost/callback', + scope: 'openid profile', + serverConfig: { wellknown: TEST_WELLKNOWN_URL }, + responseType: 'code', +}; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +function makeStorageStub() { + const store = new Map(); + return { + getItem: (key: string) => store.get(key) ?? null, + setItem: (key: string, value: string) => store.set(key, value), + removeItem: (key: string) => store.delete(key), + clear: () => store.clear(), + get length() { + return store.size; + }, + key: (i: number) => [...store.keys()][i] ?? null, + }; +} + +/** + * Constructs a minimal InjectableStore that mirrors what davinci()/journey() creates, + * but without importing those packages. Uses only RTK primitives. + */ +function makeSharedStore(): SdkStore { + const dynamicMiddleware = createDynamicMiddleware(); + const rootReducer = combineSlices(wellknownApi).withLazyLoadedSlices(); + const store = configureStore({ + reducer: rootReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(wellknownApi.middleware).concat(dynamicMiddleware.middleware), + }); + return { store, rootReducer, dynamicMiddleware } as unknown as SdkStore; +} + +function makeFetchMock(onCall?: (url: string) => void) { + return vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => { + const url = typeof input === 'string' ? input : (input as Request).url; + onCall?.(url); + + if (url.includes('.well-known')) { + return new Response(JSON.stringify(mockWellknownResponse), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + } + + return new Response(JSON.stringify({}), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + }); +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('injectIntoStore()', () => { + it('calls rootReducer.inject with oidcApi', () => { + const dynamicMiddleware = createDynamicMiddleware(); + const rootReducer = combineSlices(wellknownApi).withLazyLoadedSlices(); + const store = configureStore({ + reducer: rootReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(dynamicMiddleware.middleware), + }); + + const injectable = { store, rootReducer, dynamicMiddleware } as unknown as SdkStore; + + const injectSpy = vi.spyOn(rootReducer, 'inject'); + injectIntoStore(injectable); + + expect(injectSpy).toHaveBeenCalledWith(oidcApi); + }); + + it('calls dynamicMiddleware.addMiddleware with oidcApi.middleware', () => { + const dynamicMiddleware = createDynamicMiddleware(); + const rootReducer = combineSlices(wellknownApi).withLazyLoadedSlices(); + const store = configureStore({ + reducer: rootReducer, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(dynamicMiddleware.middleware), + }); + + const injectable = { store, rootReducer, dynamicMiddleware } as unknown as SdkStore; + + const addMiddlewareSpy = vi.spyOn(dynamicMiddleware, 'addMiddleware'); + injectIntoStore(injectable); + + expect(addMiddlewareSpy).toHaveBeenCalledWith(oidcApi.middleware); + }); + + it('oidcApi slice is readable from store state after injection', () => { + const sharedStore = makeSharedStore(); + const typedStore = injectIntoStore(sharedStore); + + // combineSlices registers the reducer on inject(), but state is only recomputed + // on the next dispatch. Trigger a no-op action to force state recalculation. + typedStore.dispatch({ type: '@@test/init' }); + const state = typedStore.getState() as Record; + + expect(state).toHaveProperty(oidcApi.reducerPath); + }); + + it('is idempotent — calling twice does not throw or corrupt state', () => { + const sharedStore = makeSharedStore(); + + expect(() => { + injectIntoStore(sharedStore); + injectIntoStore(sharedStore); + }).not.toThrow(); + + const typedStore = injectIntoStore(sharedStore); + typedStore.dispatch({ type: '@@test/init' }); + const state = typedStore.getState() as Record; + expect(state).toHaveProperty(oidcApi.reducerPath); + }); +}); + +describe('oidc() standalone — no shared store', () => { + let fetchCallCount = 0; + + beforeEach(() => { + fetchCallCount = 0; + vi.stubGlobal('localStorage', makeStorageStub()); + vi.stubGlobal('sessionStorage', makeStorageStub()); + makeFetchMock((url) => { + if (url.includes('.well-known')) fetchCallCount++; + }); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it('creates its own store and returns a working client', async () => { + const client = await oidc({ config: oidcConfig }); + + expect('error' in client).toBe(false); + if ('error' in client) throw new Error('Expected oidc client, got error'); + + expect(client.subscribe).toBeInstanceOf(Function); + expect(client.token).toBeDefined(); + expect(client.authorize).toBeDefined(); + }); + + it('fetches wellknown during init', async () => { + await oidc({ config: oidcConfig }); + + expect(fetchCallCount).toBeGreaterThan(0); + }); +}); + +describe('oidc() with shared store', () => { + let wellknownFetchCount = 0; + + beforeEach(() => { + wellknownFetchCount = 0; + vi.stubGlobal('localStorage', makeStorageStub()); + vi.stubGlobal('sessionStorage', makeStorageStub()); + makeFetchMock((url) => { + if (url.includes('.well-known')) wellknownFetchCount++; + }); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it('resolves without error when given a shared SdkStore', async () => { + const sharedStore = makeSharedStore(); + const client = await oidc({ config: oidcConfig }, sharedStore); + + expect('error' in client).toBe(false); + if ('error' in client) throw new Error('Expected oidc client, got error'); + + expect(client.subscribe).toBeInstanceOf(Function); + expect(client.token).toBeDefined(); + expect(client.authorize).toBeDefined(); + }); + + it('subscribe() fires when oidcApi state changes on the shared store', async () => { + const sharedStore = makeSharedStore(); + const client = await oidc({ config: oidcConfig }, sharedStore); + + if ('error' in client) throw new Error('Expected oidc client, got error'); + + const listener = vi.fn(); + client.subscribe(listener); + + // Dispatch an oidcApi mutation — any action that causes a state change will notify the subscriber + const typedStore = injectIntoStore(sharedStore); + typedStore.dispatch({ type: 'test/action' }); + + expect(listener).toHaveBeenCalled(); + }); + + it('reuses cached wellknown response — no additional fetch when store already has it', async () => { + const sharedStore = makeSharedStore(); + + // Simulate the owning store (davinci/journey) having already fetched wellknown + const typedStore = injectIntoStore(sharedStore); + await typedStore.dispatch(wellknownApi.endpoints.configuration.initiate(TEST_WELLKNOWN_URL)); + const fetchesAfterOwnerInit = wellknownFetchCount; + + // oidc() using the same wellknown URL should hit the RTK Query cache + await oidc({ config: oidcConfig }, sharedStore); + + expect(wellknownFetchCount).toBe(fetchesAfterOwnerInit); + }); + + it('warns when requestMiddleware is passed alongside sharedStore', async () => { + const sharedStore = makeSharedStore(); + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(vi.fn()); + + // Set log level to 'warn' so the logger actually emits the warning to console.warn. + // The default level is 'error', which silently suppresses warn/info/debug messages. + await oidc( + { + config: oidcConfig, + logger: { level: 'warn' }, + requestMiddleware: [() => () => (action: unknown) => action], + }, + sharedStore, + ); + + const warnCalls = warnSpy.mock.calls.map((args) => args.join(' ')); + expect(warnCalls.some((msg) => msg.includes('requestMiddleware'))).toBe(true); + + warnSpy.mockRestore(); + }); + + it('does not warn when no requestMiddleware is passed with sharedStore', async () => { + const sharedStore = makeSharedStore(); + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(vi.fn()); + + await oidc({ config: oidcConfig, logger: { level: 'warn' } }, sharedStore); + + const warnCalls = warnSpy.mock.calls.map((args) => args.join(' ')); + expect(warnCalls.some((msg) => msg.includes('requestMiddleware'))).toBe(false); + + warnSpy.mockRestore(); + }); +}); diff --git a/packages/oidc-client/src/types.ts b/packages/oidc-client/src/types.ts index 9496a4ae6c4..6a17dcbfef9 100644 --- a/packages/oidc-client/src/types.ts +++ b/packages/oidc-client/src/types.ts @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. +/* Copyright © 2025 - 2026 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -19,8 +18,7 @@ export type { } from '@forgerock/sdk-types'; export type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware'; export type { CustomLogger, LogLevel } from '@forgerock/sdk-logger'; -export type { BrowserStorageConfig, CustomStorageConfig, StorageConfig } from '@forgerock/storage'; -export type { CustomStorageObject } from '@forgerock/sdk-types'; +export type { StorageConfig } from '@forgerock/storage'; // Re-export functions needed to resolve OidcClient and ClientStore type aliases export { oidc } from './lib/client.store.js'; diff --git a/packages/oidc-client/tsconfig.lib.json b/packages/oidc-client/tsconfig.lib.json index d689866941f..920e9ccdc8f 100644 --- a/packages/oidc-client/tsconfig.lib.json +++ b/packages/oidc-client/tsconfig.lib.json @@ -39,6 +39,9 @@ }, { "path": "../sdk-effects/iframe-manager/tsconfig.lib.json" + }, + { + "path": "../sdk-effects/wellknown/tsconfig.lib.json" } ], "exclude": [ diff --git a/packages/sdk-effects/wellknown/eslint.config.mjs b/packages/sdk-effects/wellknown/eslint.config.mjs new file mode 100644 index 00000000000..980b6a3e9d3 --- /dev/null +++ b/packages/sdk-effects/wellknown/eslint.config.mjs @@ -0,0 +1,22 @@ +import baseConfig from '../../../eslint.config.mjs'; + +export default [ + ...baseConfig, + { + files: ['**/*.json'], + rules: { + '@nx/dependency-checks': [ + 'warn', + { + ignoredFiles: [ + '{projectRoot}/eslint.config.{js,cjs,mjs}', + '{projectRoot}/vite.config.{js,ts,mjs,mts}', + ], + }, + ], + }, + languageOptions: { + parser: (await import('jsonc-eslint-parser')).default, + }, + }, +]; diff --git a/packages/sdk-effects/wellknown/package.json b/packages/sdk-effects/wellknown/package.json new file mode 100644 index 00000000000..18e9feff217 --- /dev/null +++ b/packages/sdk-effects/wellknown/package.json @@ -0,0 +1,41 @@ +{ + "name": "@forgerock/sdk-wellknown", + "version": "1.0.0", + "private": false, + "repository": { + "type": "git", + "url": "git+https://github.com/ForgeRock/ping-javascript-sdk.git", + "directory": "packages/sdk-effects/wellknown" + }, + "description": "Shared wellknown/OpenID Connect discovery API for the Ping JavaScript SDK", + "license": "MIT", + "author": "ForgeRock", + "sideEffects": false, + "type": "module", + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js", + "default": "./dist/src/index.js" + }, + "./package.json": "./package.json" + }, + "main": "./dist/src/index.js", + "module": "./dist/src/index.js", + "types": "./dist/src/index.d.ts", + "files": ["dist"], + "scripts": { + "build": "pnpm nx nxBuild", + "lint": "pnpm nx nxLint", + "test": "pnpm nx nxTest", + "test:watch": "pnpm nx nxTest --watch" + }, + "dependencies": { + "@forgerock/sdk-oidc": "workspace:*", + "@forgerock/sdk-types": "workspace:*", + "@reduxjs/toolkit": "catalog:" + }, + "nx": { + "tags": ["scope:sdk-effects"] + } +} diff --git a/packages/sdk-effects/wellknown/src/index.ts b/packages/sdk-effects/wellknown/src/index.ts new file mode 100644 index 00000000000..04f4e2c35be --- /dev/null +++ b/packages/sdk-effects/wellknown/src/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +export { wellknownApi, wellknownSelector, createWellknownSelector } from './lib/wellknown.api.js'; +export type { WellknownState } from './lib/wellknown.api.js'; diff --git a/packages/oidc-client/src/lib/wellknown.api.ts b/packages/sdk-effects/wellknown/src/lib/wellknown.api.ts similarity index 78% rename from packages/oidc-client/src/lib/wellknown.api.ts rename to packages/sdk-effects/wellknown/src/lib/wellknown.api.ts index 44a5ba10f82..b3d5c538448 100644 --- a/packages/oidc-client/src/lib/wellknown.api.ts +++ b/packages/sdk-effects/wellknown/src/lib/wellknown.api.ts @@ -16,14 +16,15 @@ import type { QueryReturnValue, } from '@reduxjs/toolkit/query'; -import type { RootState } from './client.types.js'; - /** * RTK Query API for well-known endpoint discovery. * * Uses the `initWellknownQuery` builder pattern from `@forgerock/sdk-oidc`. * The builder constructs the request and validates the response; * `fetchBaseQuery` handles the HTTP transport through RTK Query's pipeline. + * + * This is the canonical single instance — all SDK client packages import from here + * so that a shared Redux store gets a single cache entry per URL. */ export const wellknownApi = createApi({ reducerPath: 'wellknown', @@ -45,6 +46,11 @@ export const wellknownApi = createApi({ }), }); +/** Minimum state shape required to use wellknown selectors. */ +export type WellknownState = { + [wellknownApi.reducerPath]: ReturnType; +}; + /** * Creates a memoized selector for cached well-known data. * @@ -59,19 +65,16 @@ export function createWellknownSelector(wellknownUrl: string) { } /** - * Convenience selector for oidc-client's RootState type. + * Convenience selector for any state that contains the wellknown slice. * * Unlike {@link createWellknownSelector}, this immediately evaluates the * selector against the provided state rather than returning a reusable selector. * * @param wellknownUrl - The well-known endpoint URL used as the cache key - * @param state - The oidc-client Redux root state + * @param state - Any Redux state that includes the wellknown slice * @returns The cached WellknownResponse or undefined if not yet fetched */ -export function wellknownSelector(wellknownUrl: string, state: RootState) { - const selector = createSelector( - wellknownApi.endpoints.configuration.select(wellknownUrl), - (result) => result?.data, - ); +export function wellknownSelector(wellknownUrl: string, state: S) { + const selector = createWellknownSelector(wellknownUrl); return selector(state); } diff --git a/packages/sdk-effects/wellknown/tsconfig.json b/packages/sdk-effects/wellknown/tsconfig.json new file mode 100644 index 00000000000..3a5af05d8ed --- /dev/null +++ b/packages/sdk-effects/wellknown/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "nx": { + "addTypecheckTarget": false + } +} diff --git a/packages/sdk-effects/wellknown/tsconfig.lib.json b/packages/sdk-effects/wellknown/tsconfig.lib.json new file mode 100644 index 00000000000..3ded6219727 --- /dev/null +++ b/packages/sdk-effects/wellknown/tsconfig.lib.json @@ -0,0 +1,37 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist", + "tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo", + "emitDeclarationOnly": false, + "module": "nodenext", + "moduleResolution": "nodenext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "importHelpers": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "references": [ + { "path": "../../sdk-types/tsconfig.lib.json" }, + { "path": "../oidc/tsconfig.lib.json" } + ], + "exclude": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx" + ] +} diff --git a/packages/sdk-effects/wellknown/tsconfig.spec.json b/packages/sdk-effects/wellknown/tsconfig.spec.json new file mode 100644 index 00000000000..c8fc6b21fa7 --- /dev/null +++ b/packages/sdk-effects/wellknown/tsconfig.spec.json @@ -0,0 +1,41 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./out-tsc/vitest", + "types": [ + "vitest/globals", + "vitest/importMeta", + "vite/client", + "node", + "vitest" + ], + "module": "nodenext", + "moduleResolution": "nodenext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "importHelpers": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "include": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/packages/sdk-effects/wellknown/vite.config.ts b/packages/sdk-effects/wellknown/vite.config.ts new file mode 100644 index 00000000000..cef160f8ba6 --- /dev/null +++ b/packages/sdk-effects/wellknown/vite.config.ts @@ -0,0 +1,44 @@ +import { defineConfig } from 'vite'; + +export default defineConfig(() => ({ + root: __dirname, + cacheDir: '../../../node_modules/.vite/packages/effects/wellknown', + plugins: [], + test: { + watch: false, + globals: true, + passWithNoTests: true, + environment: 'node', + include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + coverage: { + include: ['src/**/*.{js,ts}'], + exclude: [ + 'src/**/*.mock.{js,ts}', + 'src/**/*.data.{js,ts}', + 'src/**/*.test.{js,ts}', + 'coverage/**', + 'dist/**', + '**/node_modules/**', + '**/[.]**', + 'packages/*/test?(s)/**', + '**/*.d.ts', + '**/virtual:*', + '**/__x00__*', + '**/ *', + 'cypress/**', + 'test?(s)/**', + 'test?(-*).?(c|m)[jt]s?(x)', + '**/*{.,-}{test,spec,bench,benchmark}?(-d).?(c|m)[jt]s?(x)', + '**/__tests__/**', + '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*', + '**/vitest.{workspace,projects}.[jt]s?(on)', + '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}', + ], + reporter: ['text', 'html', 'json'], + enabled: Boolean(process.env['CI']), + reportsDirectory: './coverage', + provider: 'v8' as const, + }, + }, +})); diff --git a/packages/sdk-types/src/index.ts b/packages/sdk-types/src/index.ts index 54036b802a7..10b862df1d5 100644 --- a/packages/sdk-types/src/index.ts +++ b/packages/sdk-types/src/index.ts @@ -15,3 +15,4 @@ export * from './lib/tokens.types.js'; export * from './lib/config.types.js'; export * from './lib/authorize.types.js'; export * from './lib/policy.types.js'; +export * from './lib/store.types.js'; diff --git a/packages/sdk-types/src/lib/store.types.ts b/packages/sdk-types/src/lib/store.types.ts new file mode 100644 index 00000000000..6653db7c680 --- /dev/null +++ b/packages/sdk-types/src/lib/store.types.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * + * This software may be modified and distributed under the terms + * of the MIT license. See the LICENSE file for details. + */ + +/** + * Opaque handle to a shared SDK Redux store. + * + * Consumers can pass this between SDK client factories but cannot access + * Redux internals (dispatch, getState, etc.) through this type — by design. + */ +export interface SdkStore { + readonly __sdkStoreBrand: symbol; +} diff --git a/packages/sdk-utilities/src/index.ts b/packages/sdk-utilities/src/index.ts index d89e9f96d5f..f5dc55eb175 100644 --- a/packages/sdk-utilities/src/index.ts +++ b/packages/sdk-utilities/src/index.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 - 2026 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/config/config.effects.ts b/packages/sdk-utilities/src/lib/config/config.effects.ts index 29add60d505..907b233503b 100644 --- a/packages/sdk-utilities/src/lib/config/config.effects.ts +++ b/packages/sdk-utilities/src/lib/config/config.effects.ts @@ -5,24 +5,24 @@ * of the MIT license. See the LICENSE file for details. */ -import * as Either from 'effect/Either'; +import { Result } from 'effect'; import { parseToDavinciConfig, parseToJourneyConfig, parseToOidcConfig } from './config.utils.js'; import type { DaVinciConfig, JourneyClientConfig, OidcConfig } from './config.types.js'; -function throwOnLeft(result: Either.Either): T { - if (Either.isLeft(result)) { - const messages = result.left.map((e) => `${e.field}: ${e.message}`).join(', '); +function throwOnFail(result: Result.Result): T { + if (Result.isFailure(result)) { + const messages = result.failure.map((e) => `${e.field}: ${e.message}`).join(', '); throw new Error(`Invalid unified SDK config: ${messages}`); } - return result.right; + return result.success; } -export const makeOidcConfig = (json: unknown): OidcConfig => throwOnLeft(parseToOidcConfig(json)); +export const makeOidcConfig = (json: unknown): OidcConfig => throwOnFail(parseToOidcConfig(json)); export const makeJourneyConfig = (json: unknown): JourneyClientConfig => - throwOnLeft(parseToJourneyConfig(json)); + throwOnFail(parseToJourneyConfig(json)); export const makeDavinciConfig = (json: unknown): DaVinciConfig => - throwOnLeft(parseToDavinciConfig(json)); + throwOnFail(parseToDavinciConfig(json)); diff --git a/packages/sdk-utilities/src/lib/config/config.test.ts b/packages/sdk-utilities/src/lib/config/config.test.ts index cd69d4b99c1..30e076b4a77 100644 --- a/packages/sdk-utilities/src/lib/config/config.test.ts +++ b/packages/sdk-utilities/src/lib/config/config.test.ts @@ -5,7 +5,7 @@ * of the MIT license. See the LICENSE file for details. */ -import * as Either from 'effect/Either'; +import { Result } from 'effect'; import { describe, expect, it } from 'vitest'; import { makeDavinciConfig, makeJourneyConfig, makeOidcConfig } from './config.effects.js'; @@ -18,6 +18,8 @@ import { parseUnifiedSdkConfig, } from './config.utils.js'; +import type { JourneyServerConfig } from '@forgerock/sdk-types'; + const minimalOidc = { clientId: 'my-client', discoveryEndpoint: 'https://example.com/.well-known/openid-configuration', @@ -60,31 +62,31 @@ const journeyOnlyConfig = { describe('parseUnifiedSdkConfig', () => { it('parseUnifiedSdkConfig_ValidFullConfig_ReturnsSuccess', () => { - expect(Either.isRight(parseUnifiedSdkConfig(fullConfig))).toBe(true); + expect(Result.isSuccess(parseUnifiedSdkConfig(fullConfig))).toBe(true); }); it('parseUnifiedSdkConfig_JourneyOnlyConfig_ReturnsSuccess', () => { - expect(Either.isRight(parseUnifiedSdkConfig(journeyOnlyConfig))).toBe(true); + expect(Result.isSuccess(parseUnifiedSdkConfig(journeyOnlyConfig))).toBe(true); }); it('parseUnifiedSdkConfig_NoOidcOrJourneySection_ReturnsSuccess', () => { - expect(Either.isRight(parseUnifiedSdkConfig({ timeout: 5000 }))).toBe(true); + expect(Result.isSuccess(parseUnifiedSdkConfig({ timeout: 5000 }))).toBe(true); }); it('parseUnifiedSdkConfig_UnknownTopLevelField_Ignored', () => { - expect(Either.isRight(parseUnifiedSdkConfig({ timeout: 5000, surprise: 'kept' }))).toBe(true); + expect(Result.isSuccess(parseUnifiedSdkConfig({ timeout: 5000, surprise: 'kept' }))).toBe(true); }); it('parseUnifiedSdkConfig_TimeoutNotNumber_ReturnsTypeError', () => { - const errors = Either.getOrThrow( - Either.flip(parseUnifiedSdkConfig({ ...fullConfig, timeout: 'thirty' })), + const errors = Result.getOrThrow( + Result.flip(parseUnifiedSdkConfig({ ...fullConfig, timeout: 'thirty' })), ); expect(errors.some((e) => e.field === 'timeout')).toBe(true); }); it('parseUnifiedSdkConfig_JourneyMissingServerUrl_ReturnsError', () => { - const errors = Either.getOrThrow( - Either.flip( + const errors = Result.getOrThrow( + Result.flip( parseUnifiedSdkConfig({ journey: { realm: 'alpha' }, oidc: { discoveryEndpoint: 'https://example.com/.well-known/openid-configuration' }, @@ -95,15 +97,15 @@ describe('parseUnifiedSdkConfig', () => { }); it('parseUnifiedSdkConfig_InvalidOidcNested_PropagatesErrors', () => { - const errors = Either.getOrThrow( - Either.flip(parseUnifiedSdkConfig({ ...fullConfig, oidc: { ...minimalOidc, clientId: 42 } })), + const errors = Result.getOrThrow( + Result.flip(parseUnifiedSdkConfig({ ...fullConfig, oidc: { ...minimalOidc, clientId: 42 } })), ); expect(errors.some((e) => e.field === 'oidc.clientId')).toBe(true); }); it('parseUnifiedSdkConfig_MultipleErrors_AllAccumulated', () => { - const errors = Either.getOrThrow( - Either.flip(parseUnifiedSdkConfig({ timeout: 'thirty', oidc: { scopes: 'not-an-array' } })), + const errors = Result.getOrThrow( + Result.flip(parseUnifiedSdkConfig({ timeout: 'thirty', oidc: { scopes: 'not-an-array' } })), ); expect(errors.length).toBeGreaterThanOrEqual(2); expect(errors.some((e) => e.field === 'timeout')).toBe(true); @@ -113,14 +115,14 @@ describe('parseUnifiedSdkConfig', () => { describe('parseToOidcConfig', () => { it('parseToOidcConfig_NoOidcBlock_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToOidcConfig({ journey: { serverUrl: 'https://example.com/am' } })), + const errors = Result.getOrThrow( + Result.flip(parseToOidcConfig({ journey: { serverUrl: 'https://example.com/am' } })), ); expect(errors.some((e) => e.field === 'oidc')).toBe(true); }); it('parseToOidcConfig_MinimalConfig_MapsRequiredFields', () => { - const data = Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })); + const data = Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })); expect(data.clientId).toBe('my-client'); expect(data.redirectUri).toBe('https://app.example.com/callback'); expect(data.scope).toBe('openid profile'); @@ -130,14 +132,14 @@ describe('parseToOidcConfig', () => { }); it('parseToOidcConfig_ScopesJoinedWithSpace', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToOidcConfig({ oidc: { ...minimalOidc, scopes: ['openid', 'email'] } }), ); expect(data.scope).toBe('openid email'); }); it('parseToOidcConfig_RefreshThresholdConvertedToMs', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToOidcConfig({ oidc: { ...minimalOidc, refreshThreshold: 60 } }), ); expect(data.oauthThreshold).toBe(60000); @@ -145,12 +147,12 @@ describe('parseToOidcConfig', () => { it('parseToOidcConfig_NoRefreshThreshold_OauthThresholdAbsent', () => { expect( - Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).oauthThreshold, + Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).oauthThreshold, ).toBeUndefined(); }); it('parseToOidcConfig_RealmMappedToRealmPath', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToOidcConfig({ journey: { serverUrl: 'https://example.com/am', realm: 'alpha' }, oidc: minimalOidc, @@ -160,22 +162,22 @@ describe('parseToOidcConfig', () => { }); it('parseToOidcConfig_NoRealm_RealmPathAbsent', () => { - expect(Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).realmPath).toBeUndefined(); + expect(Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).realmPath).toBeUndefined(); }); it('parseToOidcConfig_TimeoutPassedToServerConfig', () => { - const data = Either.getOrThrow(parseToOidcConfig({ timeout: 5000, oidc: minimalOidc })); + const data = Result.getOrThrow(parseToOidcConfig({ timeout: 5000, oidc: minimalOidc })); expect(data.serverConfig.timeout).toBe(5000); }); it('parseToOidcConfig_NoTimeout_TimeoutAbsentInServerConfig', () => { expect( - Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).serverConfig.timeout, + Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).serverConfig.timeout, ).toBeUndefined(); }); it('parseToOidcConfig_AuthorizeParamsMapped', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToOidcConfig({ oidc: { ...minimalOidc, @@ -199,22 +201,22 @@ describe('parseToOidcConfig', () => { }); it('parseToOidcConfig_EmptyScopes_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToOidcConfig({ oidc: { ...minimalOidc, scopes: [] } })), + const errors = Result.getOrThrow( + Result.flip(parseToOidcConfig({ oidc: { ...minimalOidc, scopes: [] } })), ); expect(errors.some((e) => e.field === 'oidc.scopes')).toBe(true); }); it('parseToOidcConfig_NoAuthorizeParams_AllAbsent', () => { - const data = Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })); + const data = Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })); expect(data.loginHint).toBeUndefined(); expect(data.nonce).toBeUndefined(); expect(data.query).toBeUndefined(); }); it('parseToOidcConfig_OidcMissingDiscoveryEndpoint_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip( + const errors = Result.getOrThrow( + Result.flip( parseToOidcConfig({ oidc: { clientId: 'x', redirectUri: 'x', scopes: ['openid'] } }), ), ); @@ -222,36 +224,34 @@ describe('parseToOidcConfig', () => { }); it('parseToOidcConfig_NullInput_ReturnsFailure', () => { - expect(Either.isLeft(parseToOidcConfig(null))).toBe(true); + expect(Result.isFailure(parseToOidcConfig(null))).toBe(true); }); }); describe('parseToJourneyConfig', () => { it('parseToJourneyConfig_NoOidcBlock_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToJourneyConfig({ journey: { serverUrl: 'https://example.com/am' } })), + const errors = Result.getOrThrow( + Result.flip(parseToJourneyConfig({ journey: { serverUrl: 'https://example.com/am' } })), ); expect(errors.some((e) => e.field === 'oidc')).toBe(true); }); it('parseToJourneyConfig_MinimalConfig_MapsWellknown', () => { - const data = Either.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })); - expect(data.serverConfig).toHaveProperty( - 'wellknown', + const data = Result.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })); + expect((data.serverConfig as JourneyServerConfig).wellknown).toBe( 'https://example.com/.well-known/openid-configuration', ); }); it('parseToJourneyConfig_JourneyOnlyConfig_MapsWellknown', () => { - const data = Either.getOrThrow(parseToJourneyConfig(journeyOnlyConfig)); - expect(data.serverConfig).toHaveProperty( - 'wellknown', + const data = Result.getOrThrow(parseToJourneyConfig(journeyOnlyConfig)); + expect((data.serverConfig as JourneyServerConfig).wellknown).toBe( 'https://example.com/.well-known/openid-configuration', ); }); it('parseToJourneyConfig_RealmMappedToRealmPath', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToJourneyConfig({ journey: { serverUrl: 'https://example.com/am', realm: 'beta' }, oidc: minimalOidc, @@ -262,17 +262,17 @@ describe('parseToJourneyConfig', () => { it('parseToJourneyConfig_NoRealm_RealmPathAbsent', () => { expect( - Either.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })).realmPath, + Result.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })).realmPath, ).toBeUndefined(); }); it('parseToJourneyConfig_TimeoutPassedToServerConfig', () => { - const data = Either.getOrThrow(parseToJourneyConfig({ timeout: 10000, oidc: minimalOidc })); + const data = Result.getOrThrow(parseToJourneyConfig({ timeout: 10000, oidc: minimalOidc })); expect(data.serverConfig.timeout).toBe(10000); }); it('parseToJourneyConfig_OidcFieldsNotLeakedToResult', () => { - const data = Either.getOrThrow(parseToJourneyConfig(fullConfig)) as unknown as Record< + const data = Result.getOrThrow(parseToJourneyConfig(fullConfig)) as unknown as Record< string, unknown >; @@ -282,27 +282,27 @@ describe('parseToJourneyConfig', () => { }); it('parseToJourneyConfig_OidcMissingDiscoveryEndpoint_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToJourneyConfig({ oidc: { realm: 'alpha' } })), + const errors = Result.getOrThrow( + Result.flip(parseToJourneyConfig({ oidc: { realm: 'alpha' } })), ); expect(errors.some((e) => e.field === 'oidc.discoveryEndpoint')).toBe(true); }); it('parseToJourneyConfig_NullInput_ReturnsFailure', () => { - expect(Either.isLeft(parseToJourneyConfig(null))).toBe(true); + expect(Result.isFailure(parseToJourneyConfig(null))).toBe(true); }); }); describe('parseToDavinciConfig', () => { it('parseToDavinciConfig_NoOidcBlock_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToDavinciConfig({ journey: { serverUrl: 'https://example.com/am' } })), + const errors = Result.getOrThrow( + Result.flip(parseToDavinciConfig({ journey: { serverUrl: 'https://example.com/am' } })), ); expect(errors.some((e) => e.field === 'oidc')).toBe(true); }); it('parseToDavinciConfig_MinimalConfig_MapsRequiredFields', () => { - const data = Either.getOrThrow(parseToDavinciConfig({ oidc: minimalOidc })); + const data = Result.getOrThrow(parseToDavinciConfig({ oidc: minimalOidc })); expect(data.clientId).toBe('my-client'); expect(data.redirectUri).toBe('https://app.example.com/callback'); expect(data.scope).toBe('openid profile'); @@ -312,21 +312,21 @@ describe('parseToDavinciConfig', () => { }); it('parseToDavinciConfig_ScopesJoinedWithSpace', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToDavinciConfig({ oidc: { ...minimalOidc, scopes: ['openid', 'email'] } }), ); expect(data.scope).toBe('openid email'); }); it('parseToDavinciConfig_RefreshThresholdConvertedToMs', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToDavinciConfig({ oidc: { ...minimalOidc, refreshThreshold: 30 } }), ); expect(data.oauthThreshold).toBe(30000); }); it('parseToDavinciConfig_RealmMappedToRealmPath', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToDavinciConfig({ journey: { serverUrl: 'https://example.com/am', realm: 'alpha' }, oidc: minimalOidc, @@ -336,20 +336,20 @@ describe('parseToDavinciConfig', () => { }); it('parseToDavinciConfig_EmptyScopes_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip(parseToDavinciConfig({ oidc: { ...minimalOidc, scopes: [] } })), + const errors = Result.getOrThrow( + Result.flip(parseToDavinciConfig({ oidc: { ...minimalOidc, scopes: [] } })), ); expect(errors.some((e) => e.field === 'oidc.scopes')).toBe(true); }); it('parseToDavinciConfig_TimeoutPassedToServerConfig', () => { - const data = Either.getOrThrow(parseToDavinciConfig({ timeout: 7000, oidc: minimalOidc })); + const data = Result.getOrThrow(parseToDavinciConfig({ timeout: 7000, oidc: minimalOidc })); expect(data.serverConfig.timeout).toBe(7000); }); it('parseToDavinciConfig_OidcMissingDiscoveryEndpoint_ReturnsFailure', () => { - const errors = Either.getOrThrow( - Either.flip( + const errors = Result.getOrThrow( + Result.flip( parseToDavinciConfig({ oidc: { clientId: 'x', redirectUri: 'x', scopes: ['openid'] } }), ), ); @@ -357,23 +357,23 @@ describe('parseToDavinciConfig', () => { }); it('parseToDavinciConfig_NullInput_ReturnsFailure', () => { - expect(Either.isLeft(parseToDavinciConfig(null))).toBe(true); + expect(Result.isFailure(parseToDavinciConfig(null))).toBe(true); }); }); describe('parseToOidcConfig log mapping', () => { it('parseToOidcConfig_LogFieldMapped_ToLogLevel', () => { - expect(Either.getOrThrow(parseToOidcConfig({ log: 'DEBUG', oidc: minimalOidc })).log).toBe( + expect(Result.getOrThrow(parseToOidcConfig({ log: 'DEBUG', oidc: minimalOidc })).log).toBe( 'debug', ); }); it('parseToOidcConfig_NoLogField_LogLevelAbsent', () => { - expect(Either.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).log).toBeUndefined(); + expect(Result.getOrThrow(parseToOidcConfig({ oidc: minimalOidc })).log).toBeUndefined(); }); it('parseToOidcConfig_CookieName_NotMappedToResult', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToOidcConfig({ journey: { serverUrl: 'https://example.com/am', cookieName: 'iPlanetDirectoryPro' }, oidc: minimalOidc, @@ -385,17 +385,17 @@ describe('parseToOidcConfig log mapping', () => { describe('parseToJourneyConfig log mapping', () => { it('parseToJourneyConfig_LogFieldMapped_ToLogLevel', () => { - expect(Either.getOrThrow(parseToJourneyConfig({ log: 'WARN', oidc: minimalOidc })).log).toBe( + expect(Result.getOrThrow(parseToJourneyConfig({ log: 'WARN', oidc: minimalOidc })).log).toBe( 'warn', ); }); it('parseToJourneyConfig_NoLogField_LogLevelAbsent', () => { - expect(Either.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })).log).toBeUndefined(); + expect(Result.getOrThrow(parseToJourneyConfig({ oidc: minimalOidc })).log).toBeUndefined(); }); it('parseToJourneyConfig_CookieName_NotMappedToResult', () => { - const data = Either.getOrThrow( + const data = Result.getOrThrow( parseToJourneyConfig({ journey: { serverUrl: 'https://example.com/am', cookieName: 'iPlanetDirectoryPro' }, oidc: minimalOidc, @@ -407,13 +407,13 @@ describe('parseToJourneyConfig log mapping', () => { describe('parseToDavinciConfig log mapping', () => { it('parseToDavinciConfig_LogFieldMapped_ToLogLevel', () => { - expect(Either.getOrThrow(parseToDavinciConfig({ log: 'ERROR', oidc: minimalOidc })).log).toBe( + expect(Result.getOrThrow(parseToDavinciConfig({ log: 'ERROR', oidc: minimalOidc })).log).toBe( 'error', ); }); it('parseToDavinciConfig_NoLogField_LogLevelAbsent', () => { - expect(Either.getOrThrow(parseToDavinciConfig({ oidc: minimalOidc })).log).toBeUndefined(); + expect(Result.getOrThrow(parseToDavinciConfig({ oidc: minimalOidc })).log).toBeUndefined(); }); }); @@ -466,8 +466,7 @@ describe('makeOidcConfig', () => { describe('makeJourneyConfig', () => { it('makeJourneyConfig_ValidConfig_ReturnsMappedJourneyConfig', () => { const result = makeJourneyConfig(fullConfig); - expect(result.serverConfig).toHaveProperty( - 'wellknown', + expect((result.serverConfig as JourneyServerConfig).wellknown).toBe( 'https://example.com/.well-known/openid-configuration', ); expect(result.realmPath).toBe('alpha'); @@ -524,22 +523,22 @@ describe('makeDavinciConfig', () => { describe('collectErrors', () => { it('collectErrors_AllRight_ReturnsEmpty', () => { - expect(collectErrors([Either.right(1), Either.right('a')])).toEqual([]); + expect(collectErrors([Result.succeed(1), Result.succeed('a')])).toEqual([]); }); it('collectErrors_MultipleLeft_AccumulatesAllErrors', () => { const errors = collectErrors([ - Either.right(1), - Either.left([{ field: 'a', message: 'bad a' }]), - Either.left([{ field: 'b', message: 'bad b' }]), + Result.succeed(1), + Result.fail([{ field: 'a', message: 'bad a' }]), + Result.fail([{ field: 'b', message: 'bad b' }]), ]); expect(errors.map((e) => e.field)).toEqual(['a', 'b']); }); it('collectErrors_DoesNotShortCircuit', () => { const errors = collectErrors([ - Either.left([{ field: 'first', message: 'x' }]), - Either.left([{ field: 'second', message: 'y' }]), + Result.fail([{ field: 'first', message: 'x' }]), + Result.fail([{ field: 'second', message: 'y' }]), ]); expect(errors).toHaveLength(2); }); @@ -552,7 +551,7 @@ describe('parseOidcSection', () => { clientId: 'my-client', scopes: ['openid'], }); - expect(Either.getOrThrow(result).clientId).toBe('my-client'); + expect(Result.getOrThrow(result).clientId).toBe('my-client'); }); it('parseOidcSection_UnknownField_Ignored', () => { @@ -560,11 +559,11 @@ describe('parseOidcSection', () => { discoveryEndpoint: 'https://example.com/.well-known', unknownField: 'kept', }); - expect(Either.isRight(result)).toBe(true); + expect(Result.isSuccess(result)).toBe(true); }); it('parseOidcSection_MissingDiscoveryEndpoint_ReturnsError', () => { - const errors = Either.getOrThrow(Either.flip(parseOidcSection({ clientId: 'my-client' }))); + const errors = Result.getOrThrow(Result.flip(parseOidcSection({ clientId: 'my-client' }))); expect(errors.some((e) => e.field === 'oidc.discoveryEndpoint')).toBe(true); }); }); diff --git a/packages/sdk-utilities/src/lib/config/config.types.ts b/packages/sdk-utilities/src/lib/config/config.types.ts index 03f1ded49bd..1ed1c3ace55 100644 --- a/packages/sdk-utilities/src/lib/config/config.types.ts +++ b/packages/sdk-utilities/src/lib/config/config.types.ts @@ -6,7 +6,7 @@ */ import type { AuthDisplayValue, AuthPromptValue, LogLevel } from '@forgerock/sdk-types'; -import type * as Either from 'effect/Either'; +import type { Result } from 'effect'; export type { OidcConfig } from '@forgerock/sdk-types'; export type { AuthDisplayValue, AuthPromptValue }; @@ -49,10 +49,10 @@ export type ConfigValidationError = { }; /** - * A parsed result over the accumulating-error channel. Effect's `Either` is - * `Either`, so the SECOND type parameter is the error channel. + * A parsed result over the accumulating-error channel. Effect's `Result` is + * `Result`, so the SECOND type parameter is the error channel. */ -export type ParseResult = Either.Either; +export type ParseResult = Result.Result; /** Parses a record of unknown values into `A`. Unknown fields are silently ignored. */ export type Parser = (input: Readonly>) => ParseResult; diff --git a/packages/sdk-utilities/src/lib/config/config.utils.ts b/packages/sdk-utilities/src/lib/config/config.utils.ts index 0e04e8138f6..0101c0f708b 100644 --- a/packages/sdk-utilities/src/lib/config/config.utils.ts +++ b/packages/sdk-utilities/src/lib/config/config.utils.ts @@ -10,8 +10,7 @@ import { AUTH_PROMPT_VALUES, LOG_LEVEL_UPPERCASE_VALUES, } from '@forgerock/sdk-types'; -import { pipe } from 'effect'; -import * as Either from 'effect/Either'; +import { pipe, Result } from 'effect'; import type { LogLevel } from '@forgerock/sdk-types'; @@ -69,22 +68,22 @@ function isAbsent(value: unknown): value is undefined | null { /** * Gather every error from a list of parsed results without short-circuiting (unlike - * `Either.all`, which stops at the first `Left`). Returns all accumulated errors so a + * `Result.all`, which stops at the first failure). Returns all accumulated errors so a * section parser can report every invalid field in one pass. */ export function collectErrors( results: ReadonlyArray>, ): ConfigValidationError[] { - return results.flatMap((result) => (Either.isLeft(result) ? result.left : [])); + return results.flatMap((result) => (Result.isFailure(result) ? result.failure : [])); } /** * Unwraps a `ParseResult`, then returns `{ [key]: value }` when the value is defined, `{}` otherwise. * Spread into an object literal to conditionally include a property without an inline ternary. - * Safe to call after `collectErrors` — every result is guaranteed `Right` past the error guard. + * Safe to call after `collectErrors` — every result is guaranteed `Success` past the error guard. */ function parsedProp(key: K, result: ParseResult): ParsedProp { - const value = Either.getOrThrow(result); + const value = Result.getOrThrow(result); return (value !== undefined ? { [key]: value } : {}) as ParsedProp; } @@ -94,21 +93,21 @@ function parsedProp(key: K, result: ParseResult): Parsed const requiredString: FieldParser = (value, fieldPath) => { if (isAbsent(value)) { - return Either.left([{ field: fieldPath, message: 'Required field is missing' }]); + return Result.fail([{ field: fieldPath, message: 'Required field is missing' }]); } return typeof value === 'string' - ? Either.right(value) - : Either.left([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); + ? Result.succeed(value) + : Result.fail([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); }; /** Required, non-empty string — treats `''` as missing (a blank value can't satisfy a requirement). */ const requiredNonEmptyString: FieldParser = (value, fieldPath) => { if (isAbsent(value) || value === '') { - return Either.left([{ field: fieldPath, message: 'Required field is missing' }]); + return Result.fail([{ field: fieldPath, message: 'Required field is missing' }]); } return typeof value === 'string' - ? Either.right(value) - : Either.left([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); + ? Result.succeed(value) + : Result.fail([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); }; /** Parse each element of an array as a string, accumulating one error per non-string element. */ @@ -125,46 +124,46 @@ function parseStringElements(value: readonly unknown[], fieldPath: string): Pars }); } }); - return errors.length > 0 ? Either.left(errors) : Either.right(parsed); + return errors.length > 0 ? Result.fail(errors) : Result.succeed(parsed); } /** Required, non-empty array of strings — treats absent or `[]` as missing. */ const requiredNonEmptyStringArray: FieldParser = (value, fieldPath) => { if (isAbsent(value) || (Array.isArray(value) && value.length === 0)) { - return Either.left([{ field: fieldPath, message: 'Required field is missing' }]); + return Result.fail([{ field: fieldPath, message: 'Required field is missing' }]); } if (!Array.isArray(value)) { - return Either.left([{ field: fieldPath, message: `Expected array, got ${typeName(value)}` }]); + return Result.fail([{ field: fieldPath, message: `Expected array, got ${typeName(value)}` }]); } return parseStringElements(value, fieldPath); }; const optionalString: FieldParser = (value, fieldPath) => { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); return typeof value === 'string' - ? Either.right(value) - : Either.left([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); + ? Result.succeed(value) + : Result.fail([{ field: fieldPath, message: `Expected string, got ${typeName(value)}` }]); }; /** Finite, non-negative number (rejects NaN, Infinity, negatives). Optional-aware. */ const finiteNonNegativeNumber: FieldParser = (value, fieldPath) => { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) { - return Either.left([ + return Result.fail([ { field: fieldPath, message: `Expected a finite, non-negative number, got ${typeName(value)}`, }, ]); } - return Either.right(value); + return Result.succeed(value); }; /** Optional array of strings, accumulating one error per non-string element. */ const optionalStringArray: FieldParser = (value, fieldPath) => { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); if (!Array.isArray(value)) { - return Either.left([{ field: fieldPath, message: `Expected array, got ${typeName(value)}` }]); + return Result.fail([{ field: fieldPath, message: `Expected array, got ${typeName(value)}` }]); } return parseStringElements(value, fieldPath); }; @@ -174,9 +173,9 @@ const optionalStringRecord: FieldParser | undefined> = ( value, fieldPath, ) => { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); if (typeof value !== 'object' || Array.isArray(value)) { - return Either.left([{ field: fieldPath, message: `Expected object, got ${typeName(value)}` }]); + return Result.fail([{ field: fieldPath, message: `Expected object, got ${typeName(value)}` }]); } const parsed: Record = {}; const errors: ConfigValidationError[] = []; @@ -190,7 +189,7 @@ const optionalStringRecord: FieldParser | undefined> = ( }); } } - return errors.length > 0 ? Either.left(errors) : Either.right(parsed); + return errors.length > 0 ? Result.fail(errors) : Result.succeed(parsed); }; /** @@ -201,16 +200,16 @@ function optionalLiteralUnion( members: Members, ): FieldParser { return (value, fieldPath) => { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); if (typeof value !== 'string') { - return Either.left([ + return Result.fail([ { field: fieldPath, message: `Expected string, got ${typeName(value)}` }, ]); } const matched = members.find((member): member is Members[number] => member === value); return matched !== undefined - ? Either.right(matched) - : Either.left([ + ? Result.succeed(matched) + : Result.fail([ { field: fieldPath, message: `Expected one of ${members.join(', ')}, got ${value}` }, ]); }; @@ -260,10 +259,10 @@ export const parseOidcSection: Parser = (input) => { acrValues, additionalParameters, ]); - if (errors.length > 0) return Either.left(errors); + if (errors.length > 0) return Result.fail(errors); const oidc: UnifiedOidcConfig = { - discoveryEndpoint: Either.getOrThrow(discoveryEndpoint), + discoveryEndpoint: Result.getOrThrow(discoveryEndpoint), ...parsedProp('clientId', clientId), ...parsedProp('redirectUri', redirectUri), ...parsedProp('scopes', scopes), @@ -277,7 +276,7 @@ export const parseOidcSection: Parser = (input) => { ...parsedProp('acrValues', acrValues), ...parsedProp('additionalParameters', additionalParameters), }; - return Either.right(oidc); + return Result.succeed(oidc); }; /** Parse the `journey` block. `serverUrl` required; `realm`/`cookieName` optional. */ @@ -287,28 +286,28 @@ export const parseJourneySection: Parser = (input) => { const cookieName = optionalString(input['cookieName'], 'journey.cookieName'); const errors = collectErrors([serverUrl, realm, cookieName]); - if (errors.length > 0) return Either.left(errors); + if (errors.length > 0) return Result.fail(errors); const journey: UnifiedJourneyConfig = { - serverUrl: Either.getOrThrow(serverUrl), + serverUrl: Result.getOrThrow(serverUrl), ...parsedProp('realm', realm), ...parsedProp('cookieName', cookieName), }; - return Either.right(journey); + return Result.succeed(journey); }; /** - * Run a section parser against an optional nested object: absent → `Right(undefined)`; - * present-but-not-an-object → `Left`; present object → delegate to `parser`. + * Run a section parser against an optional nested object: absent → `Result.succeed(undefined)`; + * present-but-not-an-object → failure; present object → delegate to `parser`. */ function parseOptionalSection( value: unknown, prefix: string, parser: Parser, ): ParseResult { - if (isAbsent(value)) return Either.right(undefined); + if (isAbsent(value)) return Result.succeed(undefined); if (typeof value !== 'object' || Array.isArray(value)) { - return Either.left([{ field: prefix, message: `Expected object, got ${typeName(value)}` }]); + return Result.fail([{ field: prefix, message: `Expected object, got ${typeName(value)}` }]); } return parser({ ...value }); } @@ -321,7 +320,7 @@ export const parseUnifiedSdkConfig: Parser = (input) => { const oidc = parseOptionalSection(input['oidc'], 'oidc', parseOidcSection); const errors = collectErrors([timeout, log, journey, oidc]); - if (errors.length > 0) return Either.left(errors); + if (errors.length > 0) return Result.fail(errors); const config: UnifiedSdkConfig = { ...parsedProp('timeout', timeout), @@ -329,7 +328,7 @@ export const parseUnifiedSdkConfig: Parser = (input) => { ...parsedProp('journey', journey), ...parsedProp('oidc', oidc), }; - return Either.right(config); + return Result.succeed(config); }; /* ------------------------------------------------------------------ * @@ -344,14 +343,14 @@ export const parseUnifiedSdkConfig: Parser = (input) => { */ function parseClientSdkConfig(config: UnifiedSdkConfig): ParseResult { if (!config.oidc) { - return Either.left([{ field: 'oidc', message: 'Required block is missing' }]); + return Result.fail([{ field: 'oidc', message: 'Required block is missing' }]); } const oidc = config.oidc; - // All three are required and non-optional, so `Either.all` (first-error) is enough — the + // All three are required and non-optional, so `Result.all` (first-error) is enough — the // struct form keeps field/value paired by key. Section parsers collect errors across many // optional fields instead, so they accumulate via `collectErrors`. - return Either.map( - Either.all({ + return Result.map( + Result.all({ clientId: requiredNonEmptyString(oidc.clientId, 'oidc.clientId'), redirectUri: requiredNonEmptyString(oidc.redirectUri, 'oidc.redirectUri'), scopes: requiredNonEmptyStringArray(oidc.scopes, 'oidc.scopes'), @@ -367,8 +366,8 @@ function parseClientSdkConfig(config: UnifiedSdkConfig): ParseResult { return config.oidc - ? Either.right({ ...config, oidc: config.oidc }) - : Either.left([{ field: 'oidc', message: 'Required block is missing' }]); + ? Result.succeed({ ...config, oidc: config.oidc }) + : Result.fail([{ field: 'oidc', message: 'Required block is missing' }]); } /* ------------------------------------------------------------------ * @@ -440,33 +439,33 @@ function buildDavinciConfig(config: ClientSdkConfig): DaVinciConfig { function assertObject( input: unknown, -): Either.Either>, ConfigValidationError[]> { +): Result.Result>, ConfigValidationError[]> { if (typeof input !== 'object' || input === null || Array.isArray(input)) { - return Either.left([{ field: 'config', message: `Expected object, got ${typeName(input)}` }]); + return Result.fail([{ field: 'config', message: `Expected object, got ${typeName(input)}` }]); } - return Either.right(input as Readonly>); + return Result.succeed(input as Readonly>); } export const parseToOidcConfig = (input: unknown): ParseResult => pipe( assertObject(input), - Either.flatMap(parseUnifiedSdkConfig), - Either.flatMap(parseClientSdkConfig), - Either.map(buildOidcConfig), + Result.flatMap(parseUnifiedSdkConfig), + Result.flatMap(parseClientSdkConfig), + Result.map(buildOidcConfig), ); export const parseToJourneyConfig = (input: unknown): ParseResult => pipe( assertObject(input), - Either.flatMap(parseUnifiedSdkConfig), - Either.flatMap(parseJourneySdkConfig), - Either.map(buildJourneyConfig), + Result.flatMap(parseUnifiedSdkConfig), + Result.flatMap(parseJourneySdkConfig), + Result.map(buildJourneyConfig), ); export const parseToDavinciConfig = (input: unknown): ParseResult => pipe( assertObject(input), - Either.flatMap(parseUnifiedSdkConfig), - Either.flatMap(parseClientSdkConfig), - Either.map(buildDavinciConfig), + Result.flatMap(parseUnifiedSdkConfig), + Result.flatMap(parseClientSdkConfig), + Result.map(buildDavinciConfig), ); diff --git a/packages/sdk-utilities/src/lib/error/error.utils.test.ts b/packages/sdk-utilities/src/lib/error/error.utils.test.ts index 47ee41bcd8c..873dc204a07 100644 --- a/packages/sdk-utilities/src/lib/error/error.utils.test.ts +++ b/packages/sdk-utilities/src/lib/error/error.utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/micro.utils.ts b/packages/sdk-utilities/src/lib/micro.utils.ts index cf58145f3bd..fb9f06c3896 100644 --- a/packages/sdk-utilities/src/lib/micro.utils.ts +++ b/packages/sdk-utilities/src/lib/micro.utils.ts @@ -1,26 +1,36 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ -import { causeIsDie, exitIsFail, exitIsSuccess } from 'effect/Micro'; +import { Cause, Exit } from 'effect'; import type { GenericError } from '@forgerock/sdk-types'; -import type { MicroExit } from 'effect/Micro'; -export function handleMicroExit( - result: MicroExit, +/** + * Unwrap an {@link Exit.Exit} into a plain value. + * + * - **Success** → returns the wrapped value. + * - **Failure with a typed error** → returns the error value from the first `Fail` reason. + * - **Defect / Die** → returns a {@link GenericError} built from the defect message. + * - **Other failure** → returns a {@link GenericError} with an unknown defect message. + */ +export function handleExit( + result: Exit.Exit, defectError: string, defectType: GenericError['type'], ): T | E | GenericError { - if (exitIsSuccess(result)) { + if (Exit.isSuccess(result)) { return result.value; } - if (exitIsFail(result)) { - return result.cause.error; + const reasons = result.cause.reasons; + const failReason = reasons.find(Cause.isFailReason); + if (failReason !== undefined) { + return failReason.error; } - const defect = causeIsDie(result.cause) ? result.cause.defect : undefined; + const dieReason = reasons.find(Cause.isDieReason); + const defect = dieReason?.defect; return { error: defectError, message: defect instanceof Error ? defect.message : String(defect ?? 'Unknown defect'), diff --git a/packages/sdk-utilities/src/lib/oidc/pkce.test.ts b/packages/sdk-utilities/src/lib/oidc/pkce.test.ts index 7cb39136b8f..ca60e464d19 100644 --- a/packages/sdk-utilities/src/lib/oidc/pkce.test.ts +++ b/packages/sdk-utilities/src/lib/oidc/pkce.test.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/oidc/pkce.utils.ts b/packages/sdk-utilities/src/lib/oidc/pkce.utils.ts index 80cdc8be4b3..0331ea0ab54 100644 --- a/packages/sdk-utilities/src/lib/oidc/pkce.utils.ts +++ b/packages/sdk-utilities/src/lib/oidc/pkce.utils.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/url/am-url.test.ts b/packages/sdk-utilities/src/lib/url/am-url.test.ts index 20eef7e1247..b3b2b6eee07 100644 --- a/packages/sdk-utilities/src/lib/url/am-url.test.ts +++ b/packages/sdk-utilities/src/lib/url/am-url.test.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/url/am-url.types.ts b/packages/sdk-utilities/src/lib/url/am-url.types.ts index e7c5cb9e8f1..bdf0a020cc2 100644 --- a/packages/sdk-utilities/src/lib/url/am-url.types.ts +++ b/packages/sdk-utilities/src/lib/url/am-url.types.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/url/am-url.utils.ts b/packages/sdk-utilities/src/lib/url/am-url.utils.ts index 5f20ff8dd32..581d4f67efb 100644 --- a/packages/sdk-utilities/src/lib/url/am-url.utils.ts +++ b/packages/sdk-utilities/src/lib/url/am-url.utils.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/lib/wellknown/wellknown.utils.test.ts b/packages/sdk-utilities/src/lib/wellknown/wellknown.utils.test.ts index 8213ee7f6c0..22cfa62df61 100644 --- a/packages/sdk-utilities/src/lib/wellknown/wellknown.utils.test.ts +++ b/packages/sdk-utilities/src/lib/wellknown/wellknown.utils.test.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved. + * Copyright (c) 2025 Ping Identity Corporation. All rights reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/packages/sdk-utilities/src/types.ts b/packages/sdk-utilities/src/types.ts index 5827a331d36..4fdfe866b8c 100644 --- a/packages/sdk-utilities/src/types.ts +++ b/packages/sdk-utilities/src/types.ts @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2025 - 2026 Ping Identity Corporation. All right reserved. + * Copyright © 2025 Ping Identity Corporation. All right reserved. * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab4fbd9fe98..16819bf0960 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,41 +34,38 @@ catalogs: specifier: 5.8.3 version: 5.8.3 effect: - '@effect/cli': - specifier: ^0.69.0 - version: 0.69.2 '@effect/language-service': - specifier: ^0.35.2 - version: 0.35.2 + specifier: 0.87.3 + version: 0.87.3 '@effect/opentelemetry': - specifier: ^0.56.1 - version: 0.56.6 - '@effect/platform': - specifier: ^0.90.0 - version: 0.90.10 + specifier: 4.0.0 + version: 4.0.0 '@effect/platform-node': - specifier: 0.94.2 - version: 0.94.2 + specifier: 4.0.0 + version: 4.0.0 '@effect/vitest': - specifier: ^0.27.0 - version: 0.27.0 + specifier: 4.0.0 + version: 4.0.0 effect: - specifier: ^3.20.0 - version: 3.21.0 + specifier: 4.0.0 + version: 4.0.0 vite: vite: specifier: ^7.3.6 version: 7.3.6 vitest: '@vitest/coverage-v8': - specifier: ^4.1.11 - version: 4.1.11 + specifier: ^5.0.0 + version: 5.0.3 + '@vitest/ui': + specifier: ^5.0.0 + version: 5.0.3 vitest: - specifier: ^4.1.11 - version: 4.1.11 + specifier: ^5.0.0 + version: 5.0.3 vitest-canvas-mock: - specifier: ^1.1.3 - version: 1.1.3 + specifier: ^1.1.4 + version: 1.1.4 overrides: rollup: ^4.59.0 @@ -96,7 +93,7 @@ importers: version: 1.0.1 '@changesets/cli': specifier: ^3.0.2 - version: 3.0.2 + version: 3.0.3 '@commitlint/cli': specifier: ^20.0.0 version: 20.1.0(@types/node@24.9.2)(typescript@5.8.3) @@ -106,9 +103,6 @@ importers: '@commitlint/prompt': specifier: ^20.0.0 version: 20.1.0(@types/node@24.9.2)(typescript@5.8.3) - '@effect/cli': - specifier: catalog:effect - version: 0.69.2(@effect/platform@0.90.10(effect@3.21.0))(@effect/printer-ansi@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0))(@effect/printer@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) '@eslint/eslintrc': specifier: ^3.0.0 version: 3.3.5 @@ -141,16 +135,16 @@ importers: version: 23.2.0(2553f22623d1e3e88580369ec940991e) '@nx/plugin': specifier: 23.2.0 - version: 23.2.0(d9a0568ef46d9c1d8bfd3f0eb85080ca) + version: 23.2.0(b931ba6a884f9e3aa0720ec0e703a2e0) '@nx/vite': specifier: 23.2.0 - version: 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11) + version: 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3) '@nx/vitest': specifier: 23.2.0 - version: 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11) + version: 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3) '@nx/web': specifier: 23.2.0 - version: 23.2.0(4dc6bb3f7e748b9b328196f1867a756c) + version: 23.2.0(de233ffe8519ec6995a15390fd0ae989) '@nx/workspace': specifier: 23.2.0 version: 23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)) @@ -195,10 +189,10 @@ importers: version: 8.46.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.8.3) '@vitest/coverage-v8': specifier: catalog:vitest - version: 4.1.11(vitest@4.1.11) + version: 5.0.3(vitest@5.0.3) '@vitest/ui': - specifier: 4.1.11 - version: 4.1.11(vitest@4.1.11) + specifier: catalog:vitest + version: 5.0.3(vitest@5.0.3) conventional-changelog-conventionalcommits: specifier: ^8.0.0 version: 8.0.0 @@ -300,10 +294,10 @@ importers: version: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) vitest-canvas-mock: specifier: catalog:vitest - version: 1.1.3(vitest@4.1.11) + version: 1.1.4(vitest@5.0.3) e2e/am-mock-api: dependencies: @@ -363,11 +357,11 @@ importers: version: link:../../packages/sdk-types effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 devDependencies: '@effect/language-service': specifier: catalog:effect - version: 0.35.2 + version: 0.87.3 e2e/journey-app: dependencies: @@ -397,16 +391,13 @@ importers: dependencies: '@effect/language-service': specifier: catalog:effect - version: 0.35.2 + version: 0.87.3 '@effect/opentelemetry': specifier: catalog:effect - version: 0.56.6(@effect/platform@0.90.10(effect@3.21.0))(@opentelemetry/api@1.9.0)(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.207.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-web@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)(effect@3.21.0) - '@effect/platform': - specifier: catalog:effect - version: 0.90.10(effect@3.21.0) + version: 4.0.0(@opentelemetry/api-logs@0.207.0)(@opentelemetry/api@1.9.0)(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.207.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-web@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)(effect@4.0.0) '@effect/platform-node': specifier: catalog:effect - version: 0.94.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) + version: 4.0.0(effect@4.0.0)(redis@6.3.0(@opentelemetry/api@1.9.0)) '@opentelemetry/sdk-logs': specifier: 0.207.0 version: 0.207.0(@opentelemetry/api@1.9.0) @@ -424,20 +415,20 @@ importers: version: 2.2.0(@opentelemetry/api@1.9.0) effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 nanoid: specifier: ^5.1.16 version: 5.1.16 devDependencies: '@effect/vitest': specifier: catalog:effect - version: 0.27.0(effect@3.21.0)(vitest@4.1.11) + version: 4.0.0(effect@4.0.0)(vitest@5.0.3) typescript: specifier: 'catalog:' version: 5.8.3 vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) e2e/oidc-app: dependencies: @@ -473,6 +464,9 @@ importers: '@forgerock/sdk-utilities': specifier: workspace:* version: link:../sdk-utilities + '@forgerock/sdk-wellknown': + specifier: workspace:* + version: link:../sdk-effects/wellknown '@forgerock/storage': specifier: workspace:* version: link:../sdk-effects/storage @@ -481,20 +475,20 @@ importers: version: 2.10.1 effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 immer: specifier: 'catalog:' version: 10.2.0 devDependencies: '@effect/vitest': specifier: catalog:effect - version: 0.27.0(effect@3.21.0)(vitest@4.1.11) + version: 4.0.0(effect@4.0.0)(vitest@5.0.3) typescript: specifier: 'catalog:' version: 5.8.3 vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) packages/device-client: dependencies: @@ -529,6 +523,9 @@ importers: '@forgerock/sdk-utilities': specifier: workspace:* version: link:../sdk-utilities + '@forgerock/sdk-wellknown': + specifier: workspace:* + version: link:../sdk-effects/wellknown '@forgerock/storage': specifier: workspace:* version: link:../sdk-effects/storage @@ -537,14 +534,14 @@ importers: version: 2.10.1 effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 tslib: specifier: 'catalog:' version: 2.8.1 devDependencies: '@vitest/coverage-v8': specifier: catalog:vitest - version: 4.1.11(vitest@4.1.11) + version: 5.0.3(vitest@5.0.3) typescript: specifier: 'catalog:' version: 5.8.3 @@ -553,10 +550,10 @@ importers: version: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) vitest-canvas-mock: specifier: catalog:vitest - version: 1.1.3(vitest@4.1.11) + version: 1.1.4(vitest@5.0.3) packages/oidc-client: dependencies: @@ -578,6 +575,9 @@ importers: '@forgerock/sdk-utilities': specifier: workspace:* version: link:../sdk-utilities + '@forgerock/sdk-wellknown': + specifier: workspace:* + version: link:../sdk-effects/wellknown '@forgerock/storage': specifier: workspace:* version: link:../sdk-effects/storage @@ -586,14 +586,14 @@ importers: version: 2.10.1 effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 jose: specifier: 'catalog:' version: 6.2.3 devDependencies: '@effect/vitest': specifier: catalog:effect - version: 0.27.0(effect@3.21.0)(vitest@4.1.11) + version: 4.0.0(effect@4.0.0)(vitest@5.0.3) msw: specifier: 'catalog:' version: 2.12.1(@types/node@24.9.2)(typescript@5.8.3) @@ -642,6 +642,18 @@ importers: specifier: workspace:* version: link:../../sdk-types + packages/sdk-effects/wellknown: + dependencies: + '@forgerock/sdk-oidc': + specifier: workspace:* + version: link:../oidc + '@forgerock/sdk-types': + specifier: workspace:* + version: link:../../sdk-types + '@reduxjs/toolkit': + specifier: 'catalog:' + version: 2.10.1 + packages/sdk-types: {} packages/sdk-utilities: @@ -651,7 +663,7 @@ importers: version: link:../sdk-types effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 scratchpad: dependencies: @@ -682,7 +694,7 @@ importers: version: 28.0.0 vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) devDependencies: '@forgerock/javascript-sdk': specifier: 'catalog:' @@ -693,37 +705,31 @@ importers: tools/release: dependencies: - '@effect/platform': - specifier: catalog:effect - version: 0.90.10(effect@3.21.0) '@effect/platform-node': specifier: catalog:effect - version: 0.94.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) + version: 4.0.0(effect@4.0.0)(redis@6.3.0(@opentelemetry/api@1.9.0)) effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 tools/user-scripts: dependencies: - '@effect/platform': - specifier: catalog:effect - version: 0.90.10(effect@3.21.0) '@effect/platform-node': specifier: catalog:effect - version: 0.94.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) + version: 4.0.0(effect@4.0.0)(redis@6.3.0(@opentelemetry/api@1.9.0)) effect: specifier: catalog:effect - version: 3.21.0 + version: 4.0.0 vitest: specifier: catalog:vitest - version: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + version: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) devDependencies: '@effect/language-service': specifier: catalog:effect - version: 0.35.2 + version: 0.87.3 '@effect/vitest': specifier: catalog:effect - version: 0.27.0(effect@3.21.0)(vitest@4.1.11) + version: 4.0.0(effect@4.0.0)(vitest@5.0.3) typescript: specifier: 'catalog:' version: 5.8.3 @@ -898,10 +904,6 @@ packages: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} @@ -1451,8 +1453,8 @@ packages: '@borewit/text-codec@0.1.1': resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} - '@changesets/apply-release-plan@8.1.0': - resolution: {integrity: sha512-M93HOGyX3ssg6He3b5NotaHtQVu6uajHS6UIQ28xKt2RzskCy73ayX4I914qBKjTJmrE4YFlELQjfcqxbmGLJw==} + '@changesets/apply-release-plan@8.1.1': + resolution: {integrity: sha512-nk2Hbq3M9NeHMdaIRBDvawKrQJzXB9sGyBUE5yWnIKtvdcNCPj75zBekJYr0gTT2ecJH3eFeTrc8eisPImcv0Q==} engines: {node: ^22.11 || ^24 || >=26} '@changesets/assemble-release-plan@7.0.0': @@ -1467,13 +1469,13 @@ packages: resolution: {integrity: sha512-QUcrV7878yHlWPXXPA6gqSxNKwtVHCd1K22L7ZAoJw2yGy8K4QvjwOStD75+1Q9KD9ZSUgGS94HuYdd7HOVtpA==} engines: {node: ^22.11 || ^24 || >=26} - '@changesets/cli@3.0.2': - resolution: {integrity: sha512-t/omGJj/I+Jv0kmJAkj5cstYEdUQiJnpip2F+2m3F4lQ3kAZ3o8Exep4/Fm1qq4rvw6ovlhJvZNrKdwLJ4lkuQ==} + '@changesets/cli@3.0.3': + resolution: {integrity: sha512-L1i67bMfkK6iC/kDejuNO4pFgTRcWIObsD6Qof2woP1I4M8tj17DGlcpRaTzTv1DYSP5EMwWdEtR8X0Pj5Jg3Q==} engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'} hasBin: true - '@changesets/config@4.0.0': - resolution: {integrity: sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==} + '@changesets/config@4.0.1': + resolution: {integrity: sha512-PxpxSQLQSLDjceAgRq+4FWlU+HflDIw03mmPVipxoQx9xrXFUjmqTy3SE+n/2t+DqPdpPiLWVr5NRiLZvjyLwg==} engines: {node: ^22.11 || ^24 || >=26} '@changesets/errors@1.0.0': @@ -1524,16 +1526,16 @@ packages: resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} engines: {node: '>= 20.12.0'} - '@clack/core@1.5.0': - resolution: {integrity: sha512-zNikCcd8BbcEvzzG1sbXFrRHFk5kHPrpwZwksPvf9qyQO1Teb7JaXaOAxXZei9nZLDW0gaZawiuTCji88bTBhw==} + '@clack/core@1.5.1': + resolution: {integrity: sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==} engines: {node: '>= 20.12.0'} '@clack/prompts@1.7.0': resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} engines: {node: '>= 20.12.0'} - '@clack/prompts@1.8.0': - resolution: {integrity: sha512-PXzLZ8N34rxmuo4dJg3xtOXhcBse94qGjDqsteoEYrFrrZ5FSjIGwMAuOcv64ln8rHVBBD06XeVGr+/JX+plcA==} + '@clack/prompts@1.8.1': + resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} engines: {node: '>= 20.12.0'} '@commitlint/cli@20.1.0': @@ -1657,56 +1659,29 @@ packages: resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} engines: {node: '>=18'} - '@effect/cli@0.69.2': - resolution: {integrity: sha512-1xYfEzW5f6jGWDb6V6DWTsWbtdp8DgQcchbewnCwKOXnJzF5VsTcfo4lYM4TXk/RAHA1owyq7OaEmeZ+qIt1/w==} - peerDependencies: - '@effect/platform': ^0.90.5 - '@effect/printer': ^0.45.0 - '@effect/printer-ansi': ^0.45.0 - effect: ^3.17.8 - - '@effect/cluster@0.46.4': - resolution: {integrity: sha512-81nWw5ABtRZZFmQTrWvfsUnqTg9LybIFYvmsiIL7xQ2t+g6746IZe9Tcv9bSmMdioJLgeuO4CiRg0FfDP2qCWA==} - peerDependencies: - '@effect/platform': ^0.90.0 - '@effect/rpc': ^0.68.3 - '@effect/sql': ^0.44.1 - '@effect/workflow': ^0.8.3 - effect: ^3.17.6 - - '@effect/experimental@0.54.6': - resolution: {integrity: sha512-UqHMvCQmrZT6kUVoUC0lqyno4Yad+j9hBGCdUjW84zkLwAq08tPqySiZUKRwY+Ae5B2Ab8rISYJH7nQvct9DMQ==} - peerDependencies: - '@effect/platform': ^0.90.2 - effect: ^3.17.7 - ioredis: ^5 - lmdb: ^3 - peerDependenciesMeta: - ioredis: - optional: true - lmdb: - optional: true - - '@effect/language-service@0.35.2': - resolution: {integrity: sha512-J7GbtthuYeruD4kYUHn3QEZtbl9v7OX9+ElD20mDBGBMA+Q6W4KnVMxZc+yDvKQBBYvfXImVUSzBbXzbrZJpyg==} + '@effect/language-service@0.87.3': + resolution: {integrity: sha512-g1OmRBZF5chbW9QMNoirPo5Bb4zzU2HfP88tR7/VSZEUxHJ1/qVb8AQ0kUh2ggctLH1I715yCwP4gkw56PTjpQ==} hasBin: true - '@effect/opentelemetry@0.56.6': - resolution: {integrity: sha512-cBi9frXujTIEGXChkl4VdQfvDe7QvzC18SM8wK0CKYSgH9ZL7v/F5f5/3fTSTfEdO9ZyBk73s5Jbbogab0Q01g==} + '@effect/opentelemetry@4.0.0': + resolution: {integrity: sha512-vXVhqlcADHtmKlw2gIqRRlXFve4ms4JJ5ykAqzNe37QQ/5N5A5gJ9VOXkMBORHZC5O4gdHZwxhAzGZb0zvFf/Q==} + engines: {node: '>=18.0.0'} peerDependencies: - '@effect/platform': ^0.90.8 - '@opentelemetry/api': ^1.9 - '@opentelemetry/resources': ^2.0.0 - '@opentelemetry/sdk-logs': ^0.203.0 - '@opentelemetry/sdk-metrics': ^2.0.0 - '@opentelemetry/sdk-trace-base': ^2.0.0 - '@opentelemetry/sdk-trace-node': ^2.0.0 - '@opentelemetry/sdk-trace-web': ^2.0.0 - '@opentelemetry/semantic-conventions': ^1.33.0 - effect: ^3.17.13 + '@opentelemetry/api': '>=1.9.0 <2.0.0' + '@opentelemetry/api-logs': '>=0.203.0 <0.300.0' + '@opentelemetry/resources': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-logs': '>=0.203.0 <0.300.0' + '@opentelemetry/sdk-metrics': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-trace-base': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-trace-node': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-trace-web': '>=2.0.0 <3.0.0' + '@opentelemetry/semantic-conventions': '>=1.33.0 <2.0.0' + effect: ^4.0.0 peerDependenciesMeta: '@opentelemetry/api': optional: true + '@opentelemetry/api-logs': + optional: true '@opentelemetry/resources': optional: true '@opentelemetry/sdk-logs': @@ -1720,71 +1695,24 @@ packages: '@opentelemetry/sdk-trace-web': optional: true - '@effect/platform-node-shared@0.47.2': - resolution: {integrity: sha512-mtXNAx7Rzbfmp8hsMnyYebIkdCoKKOMa61uRLfOgbOV0p/ksO99YHYZSE/UTE2fFeoF9f2oi0mwOj/G7EMqzng==} - peerDependencies: - '@effect/cluster': ^0.46.4 - '@effect/platform': ^0.90.0 - '@effect/rpc': ^0.68.3 - '@effect/sql': ^0.44.1 - effect: ^3.17.6 - - '@effect/platform-node@0.94.2': - resolution: {integrity: sha512-iI7vUjNqd1DOFCa/9Tyf6Cu00Y4oLKMrpa2lx8+bUIHxtYbk696Yd9VFIDLMXVWrKFUru4Fw7WgWaA/YDor/sw==} - peerDependencies: - '@effect/cluster': ^0.46.4 - '@effect/platform': ^0.90.0 - '@effect/rpc': ^0.68.3 - '@effect/sql': ^0.44.1 - effect: ^3.17.6 - - '@effect/platform@0.90.10': - resolution: {integrity: sha512-QhDPgCaLfIMQKOCoCPQvRUS+Y34iYJ07jdZ/CBAvYFvg/iUBebsmFuHL63RCD/YZH9BuK/kqqLYAA3M0fmUEgg==} - peerDependencies: - effect: ^3.17.13 - - '@effect/printer-ansi@0.45.0': - resolution: {integrity: sha512-3MS02RP83eZaBJX98PRI4f5kyoEVyNfg2Qu/XUWQMFRp4wvmgNwEy18RjO9G6s7uB8NaYXTpQVDmtUoKARx7fA==} - peerDependencies: - '@effect/typeclass': ^0.36.0 - effect: ^3.17.0 - - '@effect/printer@0.45.0': - resolution: {integrity: sha512-UpFBH2JKAgakSWpue6yKkIAXMq+3md/CPb9s/NGl28vDu1P33cvDeeDL/1EOzFk8WqhIs3oKwPMDnd3jUhjzdg==} - peerDependencies: - '@effect/typeclass': ^0.36.0 - effect: ^3.17.0 - - '@effect/rpc@0.68.4': - resolution: {integrity: sha512-iFGqBtZjjatNWwgDCCajYZvQSHc55XyZEdmHGqrKS6UfdRsV7qUSPgnplMf++tIIyGme7IbAjD/3VJdbHI5Gzg==} - peerDependencies: - '@effect/platform': ^0.90.2 - effect: ^3.17.7 - - '@effect/sql@0.44.2': - resolution: {integrity: sha512-DEcvriHvj88zu7keruH9NcHQzam7yQzLNLJO6ucDXMCAwWzYZSJOsmkxBznRFv8ylFtccSclKH2fuj+wRKPjCQ==} - peerDependencies: - '@effect/experimental': ^0.54.6 - '@effect/platform': ^0.90.4 - effect: ^3.17.7 - - '@effect/typeclass@0.36.0': - resolution: {integrity: sha512-+8xYvX4tjD7gKwGYzOyFh90I+ptdXzoNHLQTSa8kGh/xOVZMIGYb0VgLoNHE02UsuVrB+JJJuBmKLdd5TeDTPg==} + '@effect/platform-node-shared@4.0.0': + resolution: {integrity: sha512-VBXHJU9UXVZPdQGGDRjGXpo+TpOzRwZuMrdKAtIxi1qwcRftmacZ1zTgIrzBa0Z2RA2KVkoOecQUsTlt/nJZhw==} + engines: {node: '>=18.0.0'} peerDependencies: - effect: ^3.17.0 + effect: ^4.0.0 - '@effect/vitest@0.27.0': - resolution: {integrity: sha512-8bM7n9xlMUYw9GqPIVgXFwFm2jf27m/R7psI64PGpwU5+26iwyxp9eAXEsfT5S6lqztYfpQQ1Ubp5o6HfNYzJQ==} + '@effect/platform-node@4.0.0': + resolution: {integrity: sha512-/L+4MUbl8FejPKLHLROYSOebvHnfixkP8KiblSD/DE5uH5xENZBHaux4nH6XMnRP+lr8ajpEJFS8sUrmmxFJeQ==} + engines: {node: '>=18.0.0'} peerDependencies: - effect: ^3.19.0 - vitest: ^3.2.0 + effect: ^4.0.0 + redis: '>=5.0.0 <7.0.0' - '@effect/workflow@0.8.3': - resolution: {integrity: sha512-8X5IOemCb6I66GMd84w6NSmaQ+Ya3oXwItCUMelQAEuRtGzwqsw8PNNunQgK/poSRkmpszlsKOb6kEVNjSdFiQ==} + '@effect/vitest@4.0.0': + resolution: {integrity: sha512-kGElCPFGtP+CgMCwV/HjJWqtE3zYo6I1+8MSA54l+EI24lPU9p2Efa+TBp1jfkg9j711KKzEqgSAy3VzTsb76Q==} peerDependencies: - '@effect/platform': ^0.90.0 - '@effect/rpc': ^0.68.3 - effect: ^3.17.6 + effect: ^4.0.0 + vitest: '>=5.0.0 <6.0.0' '@emnapi/core@1.4.5': resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} @@ -2193,6 +2121,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -2237,36 +2168,6 @@ packages: '@microsoft/tsdoc@0.16.0': resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': - resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} - cpu: [arm64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': - resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==} - cpu: [x64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': - resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==} - cpu: [arm64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': - resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==} - cpu: [arm] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': - resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==} - cpu: [x64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': - resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==} - cpu: [x64] - os: [win32] - '@mswjs/interceptors@0.40.0': resolution: {integrity: sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==} engines: {node: '>=18'} @@ -2819,88 +2720,6 @@ packages: '@paralleldrive/cuid2@2.2.2': resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} - '@parcel/watcher-android-arm64@2.5.1': - resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [android] - - '@parcel/watcher-darwin-arm64@2.5.1': - resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [darwin] - - '@parcel/watcher-darwin-x64@2.5.1': - resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [darwin] - - '@parcel/watcher-freebsd-x64@2.5.1': - resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [freebsd] - - '@parcel/watcher-linux-arm-glibc@2.5.1': - resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - - '@parcel/watcher-linux-arm-musl@2.5.1': - resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} - engines: {node: '>= 10.0.0'} - cpu: [arm] - os: [linux] - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - - '@parcel/watcher-linux-arm64-musl@2.5.1': - resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [linux] - - '@parcel/watcher-linux-x64-glibc@2.5.1': - resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - - '@parcel/watcher-linux-x64-musl@2.5.1': - resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [linux] - - '@parcel/watcher-win32-arm64@2.5.1': - resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} - engines: {node: '>= 10.0.0'} - cpu: [arm64] - os: [win32] - - '@parcel/watcher-win32-ia32@2.5.1': - resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} - engines: {node: '>= 10.0.0'} - cpu: [ia32] - os: [win32] - - '@parcel/watcher-win32-x64@2.5.1': - resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} - engines: {node: '>= 10.0.0'} - cpu: [x64] - os: [win32] - - '@parcel/watcher@2.5.1': - resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} - engines: {node: '>= 10.0.0'} - '@phenomnomnominal/tsquery@6.2.0': resolution: {integrity: sha512-Vo9nkhfZxDB/sBiqIY3pjDC4mOSyure+AFlEW5hcy/tRE82MqCXjRN4InnVNMldinRt0dLYqg4HAU2XPq5e1LA==} peerDependencies: @@ -2929,6 +2748,42 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@redis/bloom@6.3.0': + resolution: {integrity: sha512-NQ5poYpZr0jv6zazN1cy6JY5kIipKFZ3R9GTL4kOUTX3a9YAfY29U8bsE4lWhVQEM+G4V0BXVC57mubIdDijeA==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.3.0 + + '@redis/client@6.3.0': + resolution: {integrity: sha512-fHrjwGCBvAANGi+TuRuwKi83sIOzgHr8eh+Uf48w3fSX7Hhrz174NrWqfJhAC2vnN0d/tfaZpdr6+o6JC3QHwg==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@node-rs/xxhash': ^1.1.0 + '@opentelemetry/api': '>=1 <2' + peerDependenciesMeta: + '@node-rs/xxhash': + optional: true + '@opentelemetry/api': + optional: true + + '@redis/json@6.3.0': + resolution: {integrity: sha512-yt6vRfPBXtW/3qm53cF81TSQpLMjWdW4/2E9WQ2GgbvsKkuCKCFQIcMiKlil1ZMnezK+IQuS795xKU5psbaegw==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.3.0 + + '@redis/search@6.3.0': + resolution: {integrity: sha512-RPXAZmKjZZG7Tm7m1w9keFdXzbL91PiSHQBfQRe9xwW40jNsTRbG0FwhIz4QlHPU4gKDAsCy8IQHj4yZl4H9rw==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.3.0 + + '@redis/time-series@6.3.0': + resolution: {integrity: sha512-+fJOB8mN1z5WRakCJNh5lVdz1KqvHGSOistsKeitD24QsCtPwyRQXWC0iq6T/i/ubLE/YcguZqPm8F598MKk4A==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.3.0 + '@reduxjs/toolkit@2.10.1': resolution: {integrity: sha512-/U17EXQ9Do9Yx4DlNGU6eVNfZvFJfYpUtRRdLf19PbPjdWBxNlxGZXywQZ1p1Nz8nMkWplTI7iD/23m07nolDA==} peerDependencies: @@ -3410,6 +3265,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -3671,20 +3529,25 @@ packages: resolution: {integrity: sha512-wfwn3z5M+w2KOV+xJFVv8tM8aOB4Ok5emfBDrDHrHMPDJ/fn3dEo6HoOra654PJ+zNwbTiMDvE5oAg/PLtnsUw==} engines: {node: '>=18'} - '@vitest/coverage-v8@4.1.11': - resolution: {integrity: sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==} + '@vitest/coverage-v8@5.0.3': + resolution: {integrity: sha512-+klsyz7BvT1vCU28Zkfzms1Ia78XD0V41U3FUtRaa3S+vOr/EXvK1O6BvVD7l1RzEjm6SONR2aybOvDDf9u0mQ==} peerDependencies: - '@vitest/browser': 4.1.11 - vitest: 4.1.11 + '@vitest/browser': 5.0.3 + vitest: 5.0.3 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.11': - resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} + '@vitest/istanbul-lib-coverage@1.0.2': + resolution: {integrity: sha512-9J/JMwOf9AoJhAywhrn7ScKTL38hsWQP/qPG60OtaAFcQ5OXPwKsxZFlbnuCKmZ61m8/lGgHYnFpdyQZUvG/iA==} + engines: {node: '>=22'} + + '@vitest/istanbul-lib-report@1.0.2': + resolution: {integrity: sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==} + engines: {node: '>=22'} - '@vitest/mocker@4.1.11': - resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} + '@vitest/mocker@5.0.3': + resolution: {integrity: sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3694,25 +3557,19 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.11': - resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} + '@vitest/pretty-format@5.0.3': + resolution: {integrity: sha512-3hr5eV5z2ff0l2Q1vaKQbB4j3M3tElw8stDokEOTqXJB3Es5VrT8gBRIMY59gGuFp8Y61sWlWFK1aNUH5dHDYw==} - '@vitest/runner@4.1.11': - resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} + '@vitest/spy@5.0.3': + resolution: {integrity: sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==} - '@vitest/snapshot@4.1.11': - resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} - - '@vitest/spy@4.1.11': - resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} - - '@vitest/ui@4.1.11': - resolution: {integrity: sha512-r/rwyKoev21mWdRGSEkZOqkQ2BYy68mwjihg9M90nNRbf4NGrgzZ4cj6JNCEwlOGJkbKeMgsjlykvwKUbRr7gw==} + '@vitest/ui@5.0.3': + resolution: {integrity: sha512-9dfvqDBvSbHM6y9YVXxAypkl2z7mrWozK/JFo237qI0cj/3M/kzDKiVZqzi3TE54Ler7Jditud7OMBZCyUvRHA==} peerDependencies: - vitest: 4.1.11 + vitest: 5.0.3 - '@vitest/utils@4.1.11': - resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} + '@vitest/utils@5.0.3': + resolution: {integrity: sha512-77fDTZv8eu1CzlIfgPU2yrl5MXSUaUAOvgdZEeVm3X3WIxUubIX2SforqS6176lT32HCF6uBVMYVqfHxw7o6eg==} '@vue/compiler-core@3.5.24': resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==} @@ -4023,8 +3880,8 @@ packages: resolution: {integrity: sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==} engines: {node: '>=18'} - ast-v8-to-istanbul@1.0.6: - resolution: {integrity: sha512-fvpl29helSO2w/z7utIbrkNXILdrLwDwAMH2I/zPKlGf5244+gf+B4cyS1sANcrPY2h+hWCGSgC8N61s/+AF9A==} + ast-v8-to-istanbul@1.0.5: + resolution: {integrity: sha512-UPAgKJFSEGMWSDr3LX4tqnAb4f7KGT8O40Tyx8wbYmmZ/yn58lNCm8h3svs3eXgiGd5AXxz8NDOvXWvicq+rJA==} async-function@1.0.0: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} @@ -4766,15 +4623,6 @@ packages: resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} engines: {node: '>=12.20'} - detect-libc@1.0.3: - resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} - engines: {node: '>=0.10'} - hasBin: true - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -4887,8 +4735,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@3.21.0: - resolution: {integrity: sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==} + effect@4.0.0: + resolution: {integrity: sha512-ooc1TG5t+FfzgYnFz2ff6BBKyZ7EwBRVXC7c4RhQUAD6/TZ2gTXXMeb4WX7a19ozQo4J73/QW+S00YAIresoMQ==} ejs@5.0.1: resolution: {integrity: sha512-COqBPFMxuPTPspXl2DkVYaDS3HtrD1GpzOGkNTJ1IYkifq/r9h8SVEFrjA3D9/VJGOEoMQcrlhpntcSUrM8k6A==} @@ -5111,6 +4959,7 @@ packages: eslint@9.39.4: resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -5233,10 +5082,6 @@ packages: resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} engines: {'0': node >=0.6.0} - fast-check@3.23.2: - resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} - engines: {node: '>=8.0.0'} - fast-check@4.7.0: resolution: {integrity: sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ==} engines: {node: '>=12.17.0'} @@ -5293,8 +5138,8 @@ packages: picomatch: optional: true - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fflate@0.8.3: + resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} @@ -5341,9 +5186,6 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} - find-my-way-ts@0.1.6: - resolution: {integrity: sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA==} - find-node-modules@2.1.3: resolution: {integrity: sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==} @@ -5381,6 +5223,9 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + focus-trap@8.2.2: resolution: {integrity: sha512-qV0g8hRYBqgACcFOH3f9wXc4zPKhr/0z9RI2a6ZijZ72EeBi4g8oBy8zAWuUR1TsMpOzwpUMFvjdasrC41Joug==} @@ -6270,6 +6115,9 @@ packages: resolution: {integrity: sha512-uuPNLJkKN8NXAlZlQ6kmUF9qO+T6Kyd7oV4+/7yy8Jz6+MZNyhPq8EdLpdfnPVzUC8qSf1b4j1azKaGnFsjmsw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -6468,6 +6316,9 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@1.4.2: + resolution: {integrity: sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==} + magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} @@ -6654,13 +6505,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msgpackr-extract@3.0.3: - resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==} - hasBin: true - - msgpackr@1.11.5: - resolution: {integrity: sha512-UjkUHN0yqp9RWKy0Lplhh+wlpdt9oQBYgULZOiFhV3VclSF1JnSQWZ5r9gORQlNYaUKQoR8itv7g7z1xDDuACA==} - msw@2.12.1: resolution: {integrity: sha512-arzsi9IZjjByiEw21gSUP82qHM8zkV69nNpWV6W4z72KiLvsDWoOp678ORV6cNfU/JGhlX0SsnD4oXo9gI6I2A==} engines: {node: '>=18'} @@ -6671,9 +6515,6 @@ packages: typescript: optional: true - multipasta@0.2.7: - resolution: {integrity: sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA==} - mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -6716,9 +6557,6 @@ packages: nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} - node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -6728,10 +6566,6 @@ packages: encoding: optional: true - node-gyp-build-optional-packages@5.2.2: - resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} - hasBin: true - node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -6814,8 +6648,8 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obug@2.2.1: - resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} on-exit-leak-free@2.1.2: @@ -7168,9 +7002,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - pure-rand@7.0.1: resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} @@ -7249,6 +7080,10 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} + redis@6.3.0: + resolution: {integrity: sha512-XFQbPie1lGpKeUZ8ySYY43yLnQy/iIQtHNvIr/1XdaABpb96rUSdm3Mfl+98FEVbv9ZJIzINMno5s0Nh8E5LEw==} + engines: {node: '>= 20.0.0'} + redux-thunk@3.1.0: resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} peerDependencies: @@ -7557,9 +7392,6 @@ packages: resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -7660,9 +7492,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -7951,8 +7780,9 @@ packages: resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} engines: {node: '>=12'} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinybench@6.2.0: + resolution: {integrity: sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==} + engines: {node: '>=20.0.0'} tinyexec@1.0.2: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} @@ -7966,6 +7796,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinyrainbow@3.1.1: resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} engines: {node: '>=14.0.0'} @@ -8007,9 +7841,6 @@ packages: resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} engines: {node: '>=14.16'} - toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} @@ -8276,10 +8107,6 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} - uuid@11.1.1: - resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} - hasBin: true - uuid@14.0.0: resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true @@ -8372,28 +8199,28 @@ packages: yaml: optional: true - vitest-canvas-mock@1.1.3: - resolution: {integrity: sha512-zlKJR776Qgd+bcACPh0Pq5MG3xWq+CdkACKY/wX4Jyija0BSz8LH3aCCgwFKYFwtm565+050YFEGG9Ki0gE/Hw==} + vitest-canvas-mock@1.1.4: + resolution: {integrity: sha512-4boWHY+STwAxGl1+uwakNNoQky5EjPLC8HuponXNoAscYyT1h/F7RUvTkl4IyF/MiWr3V8Q626je3Iel3eArqA==} peerDependencies: vitest: ^3.0.0 || ^4.0.0 - vitest@4.1.11: - resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + vitest@5.0.3: + resolution: {integrity: sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.11 - '@vitest/browser-preview': 4.1.11 - '@vitest/browser-webdriverio': 4.1.11 - '@vitest/coverage-istanbul': 4.1.11 - '@vitest/coverage-v8': 4.1.11 - '@vitest/ui': 4.1.11 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.3 + '@vitest/browser-preview': 5.0.3 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.3 + '@vitest/coverage-v8': 5.0.3 + '@vitest/ui': 5.0.3 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -8514,9 +8341,9 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + why-is-node-running@3.2.1: + resolution: {integrity: sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==} + engines: {node: '>=20.11'} hasBin: true word-wrap@1.2.5: @@ -8700,7 +8527,7 @@ snapshots: '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 @@ -8906,8 +8733,6 @@ snapshots: '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-identifier@7.29.7': {} '@babel/helper-validator-option@7.27.1': {} @@ -9599,9 +9424,9 @@ snapshots: '@borewit/text-codec@0.1.1': {} - '@changesets/apply-release-plan@8.1.0': + '@changesets/apply-release-plan@8.1.1': dependencies: - '@changesets/config': 4.0.0 + '@changesets/config': 4.0.1 '@changesets/format': 0.1.2 '@changesets/git': 4.0.1 '@changesets/should-skip-package': 1.0.0 @@ -9627,12 +9452,12 @@ snapshots: '@changesets/get-github-info': 1.0.1 '@changesets/types': 7.0.0 - '@changesets/cli@3.0.2': + '@changesets/cli@3.0.3': dependencies: - '@changesets/apply-release-plan': 8.1.0 + '@changesets/apply-release-plan': 8.1.1 '@changesets/assemble-release-plan': 7.0.0 '@changesets/changelog-git': 1.0.0 - '@changesets/config': 4.0.0 + '@changesets/config': 4.0.1 '@changesets/errors': 1.0.0 '@changesets/get-dependents-graph': 3.0.0 '@changesets/git': 4.0.1 @@ -9641,7 +9466,7 @@ snapshots: '@changesets/should-skip-package': 1.0.0 '@changesets/types': 7.0.0 '@changesets/write': 1.0.1 - '@clack/prompts': 1.8.0 + '@clack/prompts': 1.8.1 '@manypkg/get-packages': 3.1.0 '@pnpm/deps.graph-sequencer': 1100.0.1 cac: 7.0.0 @@ -9651,7 +9476,7 @@ snapshots: semver: 7.8.5 tinyexec: 1.3.1 - '@changesets/config@4.0.0': + '@changesets/config@4.0.1': dependencies: '@changesets/get-dependents-graph': 3.0.0 '@changesets/should-skip-package': 1.0.0 @@ -9714,10 +9539,10 @@ snapshots: '@clack/core@1.4.3': dependencies: - fast-wrap-ansi: 0.2.2 + fast-wrap-ansi: 0.2.0 sisteransi: 1.0.5 - '@clack/core@1.5.0': + '@clack/core@1.5.1': dependencies: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 @@ -9726,12 +9551,12 @@ snapshots: dependencies: '@clack/core': 1.4.3 fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.2 + fast-wrap-ansi: 0.2.0 sisteransi: 1.0.5 - '@clack/prompts@1.8.0': + '@clack/prompts@1.8.1': dependencies: - '@clack/core': 1.5.0 + '@clack/core': 1.5.1 fast-string-width: 3.0.2 fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 @@ -9828,7 +9653,7 @@ snapshots: '@commitlint/types': 20.0.0 git-raw-commits: 4.0.0 minimist: 1.2.8 - tinyexec: 1.0.2 + tinyexec: 1.3.1 '@commitlint/resolve-extends@20.1.0': dependencies: @@ -9911,39 +9736,15 @@ snapshots: gonzales-pe: 4.3.0 node-source-walk: 7.0.1 - '@effect/cli@0.69.2(@effect/platform@0.90.10(effect@3.21.0))(@effect/printer-ansi@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0))(@effect/printer@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) - '@effect/printer': 0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0) - '@effect/printer-ansi': 0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0) - effect: 3.21.0 - ini: 4.1.3 - toml: 3.0.0 - yaml: 2.9.0 + '@effect/language-service@0.87.3': {} - '@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)': + '@effect/opentelemetry@4.0.0(@opentelemetry/api-logs@0.207.0)(@opentelemetry/api@1.9.0)(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.207.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-web@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)(effect@4.0.0)': dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) - '@effect/rpc': 0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@effect/sql': 0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@effect/workflow': 0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) - effect: 3.21.0 - - '@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) - effect: 3.21.0 - uuid: 11.1.1 - - '@effect/language-service@0.35.2': {} - - '@effect/opentelemetry@0.56.6(@effect/platform@0.90.10(effect@3.21.0))(@opentelemetry/api@1.9.0)(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.207.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-web@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)(effect@3.21.0)': - dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) '@opentelemetry/semantic-conventions': 1.38.0 - effect: 3.21.0 + effect: 4.0.0 optionalDependencies: '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.207.0 '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-logs': 0.207.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) @@ -9951,79 +9752,29 @@ snapshots: '@opentelemetry/sdk-trace-node': 2.2.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-web': 2.2.0(@opentelemetry/api@1.9.0) - '@effect/platform-node-shared@0.47.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)': + '@effect/platform-node-shared@4.0.0(effect@4.0.0)': dependencies: - '@effect/cluster': 0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) - '@effect/platform': 0.90.10(effect@3.21.0) - '@effect/rpc': 0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@effect/sql': 0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@parcel/watcher': 2.5.1 - effect: 3.21.0 - multipasta: 0.2.7 + '@types/ws': 8.18.1 + effect: 4.0.0 ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform-node@0.94.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)': + '@effect/platform-node@4.0.0(effect@4.0.0)(redis@6.3.0(@opentelemetry/api@1.9.0))': dependencies: - '@effect/cluster': 0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) - '@effect/platform': 0.90.10(effect@3.21.0) - '@effect/platform-node-shared': 0.47.2(@effect/cluster@0.46.4(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0) - '@effect/rpc': 0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@effect/sql': 0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - effect: 3.21.0 - mime: 3.0.0 + '@effect/platform-node-shared': 4.0.0(effect@4.0.0) + effect: 4.0.0 + redis: 6.3.0(@opentelemetry/api@1.9.0) undici: 7.29.1 - ws: 8.21.1 transitivePeerDependencies: - bufferutil - utf-8-validate - '@effect/platform@0.90.10(effect@3.21.0)': + '@effect/vitest@4.0.0(effect@4.0.0)(vitest@5.0.3)': dependencies: - effect: 3.21.0 - find-my-way-ts: 0.1.6 - msgpackr: 1.11.5 - multipasta: 0.2.7 - - '@effect/printer-ansi@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/printer': 0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0) - '@effect/typeclass': 0.36.0(effect@3.21.0) - effect: 3.21.0 - - '@effect/printer@0.45.0(@effect/typeclass@0.36.0(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/typeclass': 0.36.0(effect@3.21.0) - effect: 3.21.0 - - '@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) - effect: 3.21.0 - - '@effect/sql@0.44.2(@effect/experimental@0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/experimental': 0.54.6(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - '@effect/platform': 0.90.10(effect@3.21.0) - effect: 3.21.0 - uuid: 11.1.1 - - '@effect/typeclass@0.36.0(effect@3.21.0)': - dependencies: - effect: 3.21.0 - - '@effect/vitest@0.27.0(effect@3.21.0)(vitest@4.1.11)': - dependencies: - effect: 3.21.0 - vitest: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) - - '@effect/workflow@0.8.3(@effect/platform@0.90.10(effect@3.21.0))(@effect/rpc@0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0))(effect@3.21.0)': - dependencies: - '@effect/platform': 0.90.10(effect@3.21.0) - '@effect/rpc': 0.68.4(@effect/platform@0.90.10(effect@3.21.0))(effect@3.21.0) - effect: 3.21.0 + effect: 4.0.0 + vitest: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) '@emnapi/core@1.4.5': dependencies: @@ -10438,6 +10189,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -10514,24 +10267,6 @@ snapshots: '@microsoft/tsdoc@0.16.0': {} - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': - optional: true - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3': - optional: true - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': - optional: true - '@mswjs/interceptors@0.40.0': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -10652,7 +10387,7 @@ snapshots: ejs: 5.0.1 minimatch: 10.2.5 nx: 23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)) - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 @@ -10674,7 +10409,7 @@ snapshots: globals: 17.5.0 jsonc-eslint-parser: 2.4.1 picocolors: 1.1.1 - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 optionalDependencies: '@typescript-eslint/parser': 8.46.3(eslint@9.39.4(jiti@2.6.1))(typescript@5.8.3) @@ -10695,7 +10430,7 @@ snapshots: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) eslint: 9.39.4(jiti@2.6.1) - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 typescript: 6.0.3 optionalDependencies: @@ -10715,7 +10450,7 @@ snapshots: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) '@nx/node': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(@zkochan/js-yaml@0.0.7)(babel-plugin-macros@3.1.0)(eslint@9.39.4(jiti@2.6.1))(express@5.2.1)(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(ts-node@10.9.2(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(typescript@5.8.3))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0)) - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 optionalDependencies: express: 5.2.1 @@ -10751,11 +10486,11 @@ snapshots: jest-config: 30.2.0(@types/node@24.9.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(typescript@5.8.3)) jest-resolve: 30.2.0 jest-util: 30.2.0 - jsonc-parser: 3.3.1 + jsonc-parser: 3.2.0 minimatch: 10.2.5 picocolors: 1.1.1 resolve.exports: 2.0.3 - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -10796,11 +10531,11 @@ snapshots: detect-port: 2.1.0 ignore: 7.0.5 js-tokens: 4.0.0 - jsonc-parser: 3.3.1 + jsonc-parser: 3.2.0 npm-run-path: 4.0.1 picocolors: 1.1.1 picomatch: 4.0.4 - semver: 7.8.5 + semver: 7.7.4 source-map-support: 0.5.19 tinyglobby: 0.2.15 tslib: 2.8.1 @@ -10822,7 +10557,7 @@ snapshots: '@nx/jest': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(babel-plugin-macros@3.1.0)(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(ts-node@10.9.2(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(typescript@5.8.3))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0)) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) kill-port: 1.6.1 - semver: 7.8.5 + semver: 7.7.4 tcp-port-used: 1.0.2 tslib: 2.8.1 optionalDependencies: @@ -10883,7 +10618,7 @@ snapshots: '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) https-proxy-agent: 7.0.6 minimatch: 10.2.5 - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 optionalDependencies: '@playwright/test': 1.59.1 @@ -10899,7 +10634,7 @@ snapshots: - supports-color - verdaccio - '@nx/plugin@23.2.0(d9a0568ef46d9c1d8bfd3f0eb85080ca)': + '@nx/plugin@23.2.0(b931ba6a884f9e3aa0720ec0e703a2e0)': dependencies: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/eslint': 23.2.0(8ceffe3b0760973552360a43d5c0a78c) @@ -10907,7 +10642,7 @@ snapshots: '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) tslib: 2.8.1 optionalDependencies: - '@nx/vitest': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11) + '@nx/vitest': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -10927,15 +10662,15 @@ snapshots: - typescript - verdaccio - '@nx/vite@23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11)': + '@nx/vite@23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3)': dependencies: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) - '@nx/vitest': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11) + '@nx/vitest': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3) '@phenomnomnominal/tsquery': 6.2.0(typescript@5.8.3) ajv: 8.20.0 picomatch: 4.0.4 - semver: 7.8.5 + semver: 7.7.4 tsconfig-paths: 4.2.0 tslib: 2.8.1 vite: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) @@ -10951,17 +10686,17 @@ snapshots: - verdaccio - vitest - '@nx/vitest@23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11)': + '@nx/vitest@23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3)': dependencies: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) '@phenomnomnominal/tsquery': 6.2.0(typescript@5.8.3) - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 optionalDependencies: '@nx/eslint': 23.2.0(8ceffe3b0760973552360a43d5c0a78c) vite: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) - vitest: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + vitest: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -10972,7 +10707,7 @@ snapshots: - typescript - verdaccio - '@nx/web@23.2.0(4dc6bb3f7e748b9b328196f1867a756c)': + '@nx/web@23.2.0(de233ffe8519ec6995a15390fd0ae989)': dependencies: '@nx/devkit': 23.2.0(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21))) '@nx/js': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(verdaccio@6.5.2(typanion@3.14.0)) @@ -10984,7 +10719,7 @@ snapshots: '@nx/eslint': 23.2.0(8ceffe3b0760973552360a43d5c0a78c) '@nx/jest': 23.2.0(@babel/traverse@7.29.8)(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(babel-plugin-macros@3.1.0)(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(ts-node@10.9.2(@swc/core@1.15.30(@swc/helpers@0.5.21))(@types/node@24.9.2)(typescript@5.8.3))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0)) '@nx/playwright': 23.2.0(2553f22623d1e3e88580369ec940991e) - '@nx/vite': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@4.1.11) + '@nx/vite': 23.2.0(@babel/traverse@7.29.8)(@nx/eslint@23.2.0(8ceffe3b0760973552360a43d5c0a78c))(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/cli@0.8.1(@swc/core@1.15.30(@swc/helpers@0.5.21)))(@swc/core@1.15.30(@swc/helpers@0.5.21))(nx@23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)))(typescript@5.8.3)(verdaccio@6.5.2(typanion@3.14.0))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))(vitest@5.0.3) transitivePeerDependencies: - '@babel/traverse' - '@swc-node/register' @@ -11002,7 +10737,7 @@ snapshots: chalk: 4.1.2 nx: 23.2.0(@swc-node/register@1.11.1(@emnapi/core@1.7.0)(@emnapi/runtime@1.7.0)(@swc/core@1.15.30(@swc/helpers@0.5.21))(@swc/types@0.1.26)(typescript@5.8.3))(@swc/core@1.15.30(@swc/helpers@0.5.21)) picomatch: 4.0.4 - semver: 7.8.5 + semver: 7.7.4 tslib: 2.8.1 yargs-parser: 21.1.1 transitivePeerDependencies: @@ -11215,66 +10950,6 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 - '@parcel/watcher-android-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-arm64@2.5.1': - optional: true - - '@parcel/watcher-darwin-x64@2.5.1': - optional: true - - '@parcel/watcher-freebsd-x64@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-arm64-musl@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-glibc@2.5.1': - optional: true - - '@parcel/watcher-linux-x64-musl@2.5.1': - optional: true - - '@parcel/watcher-win32-arm64@2.5.1': - optional: true - - '@parcel/watcher-win32-ia32@2.5.1': - optional: true - - '@parcel/watcher-win32-x64@2.5.1': - optional: true - - '@parcel/watcher@2.5.1': - dependencies: - detect-libc: 1.0.3 - is-glob: 4.0.3 - micromatch: 4.0.8 - node-addon-api: 7.1.1 - optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.1 - '@parcel/watcher-darwin-arm64': 2.5.1 - '@parcel/watcher-darwin-x64': 2.5.1 - '@parcel/watcher-freebsd-x64': 2.5.1 - '@parcel/watcher-linux-arm-glibc': 2.5.1 - '@parcel/watcher-linux-arm-musl': 2.5.1 - '@parcel/watcher-linux-arm64-glibc': 2.5.1 - '@parcel/watcher-linux-arm64-musl': 2.5.1 - '@parcel/watcher-linux-x64-glibc': 2.5.1 - '@parcel/watcher-linux-x64-musl': 2.5.1 - '@parcel/watcher-win32-arm64': 2.5.1 - '@parcel/watcher-win32-ia32': 2.5.1 - '@parcel/watcher-win32-x64': 2.5.1 - '@phenomnomnominal/tsquery@6.2.0(typescript@5.8.3)': dependencies: '@types/esquery': 1.5.4 @@ -11296,6 +10971,26 @@ snapshots: '@polka/url@1.0.0-next.29': {} + '@redis/bloom@6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0))': + dependencies: + '@redis/client': 6.3.0(@opentelemetry/api@1.9.0) + + '@redis/client@6.3.0(@opentelemetry/api@1.9.0)': + optionalDependencies: + '@opentelemetry/api': 1.9.0 + + '@redis/json@6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0))': + dependencies: + '@redis/client': 6.3.0(@opentelemetry/api@1.9.0) + + '@redis/search@6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0))': + dependencies: + '@redis/client': 6.3.0(@opentelemetry/api@1.9.0) + + '@redis/time-series@6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0))': + dependencies: + '@redis/client': 6.3.0(@opentelemetry/api@1.9.0) + '@reduxjs/toolkit@2.10.1': dependencies: '@standard-schema/spec': 1.1.0 @@ -11742,6 +11437,10 @@ snapshots: '@types/unist@3.0.3': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.9.2 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.34': @@ -12106,70 +11805,53 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': + '@vitest/coverage-v8@5.0.3(vitest@5.0.3)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.11 - ast-v8-to-istanbul: 1.0.6 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 + '@vitest/istanbul-lib-coverage': 1.0.2 + '@vitest/istanbul-lib-report': 1.0.2 + ast-v8-to-istanbul: 1.0.5 magicast: 0.5.4 - obug: 2.2.1 + obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + vitest: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + + '@vitest/istanbul-lib-coverage@1.0.2': {} - '@vitest/expect@4.1.11': + '@vitest/istanbul-lib-report@1.0.2': dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.11 - '@vitest/utils': 4.1.11 - chai: 6.2.2 - tinyrainbow: 3.1.1 + '@vitest/istanbul-lib-coverage': 1.0.2 - '@vitest/mocker@4.1.11(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))': + '@vitest/mocker@5.0.3(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.11 + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.3 estree-walker: 3.0.3 - magic-string: 0.30.21 + magic-string: 1.4.2 optionalDependencies: msw: 2.12.1(@types/node@24.9.2)(typescript@5.8.3) vite: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) - '@vitest/pretty-format@4.1.11': + '@vitest/pretty-format@5.0.3': dependencies: tinyrainbow: 3.1.1 - '@vitest/runner@4.1.11': - dependencies: - '@vitest/utils': 4.1.11 - pathe: 2.0.3 + '@vitest/spy@5.0.3': {} - '@vitest/snapshot@4.1.11': + '@vitest/ui@5.0.3(vitest@5.0.3)': dependencies: - '@vitest/pretty-format': 4.1.11 - '@vitest/utils': 4.1.11 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.1.11': {} - - '@vitest/ui@4.1.11(vitest@4.1.11)': - dependencies: - '@vitest/utils': 4.1.11 - fflate: 0.8.2 - flatted: 3.4.2 + '@vitest/utils': 5.0.3 + fflate: 0.8.3 + flatted: 3.4.4 pathe: 2.0.3 sirv: 3.0.2 - tinyglobby: 0.2.15 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + vitest: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) - '@vitest/utils@4.1.11': + '@vitest/utils@5.0.3': dependencies: - '@vitest/pretty-format': 4.1.11 + '@vitest/pretty-format': 5.0.3 convert-source-map: 2.0.0 tinyrainbow: 3.1.1 @@ -12582,7 +12264,7 @@ snapshots: ast-module-types@6.0.1: {} - ast-v8-to-istanbul@1.0.6: + ast-v8-to-istanbul@1.0.5: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -13327,11 +13009,6 @@ snapshots: detect-indent@7.0.2: {} - detect-libc@1.0.3: {} - - detect-libc@2.1.2: - optional: true - detect-newline@3.1.0: {} detect-newline@4.0.1: {} @@ -13453,10 +13130,7 @@ snapshots: ee-first@1.1.1: {} - effect@3.21.0: - dependencies: - '@standard-schema/spec': 1.1.0 - fast-check: 3.23.2 + effect@4.0.0: {} ejs@5.0.1: {} @@ -13971,10 +13645,6 @@ snapshots: extsprintf@1.3.0: {} - fast-check@3.23.2: - dependencies: - pure-rand: 6.1.0 - fast-check@4.7.0: dependencies: pure-rand: 8.4.0 @@ -14027,7 +13697,7 @@ snapshots: optionalDependencies: picomatch: 4.0.4 - fflate@0.8.2: {} + fflate@0.8.3: {} figures@3.2.0: dependencies: @@ -14099,8 +13769,6 @@ snapshots: transitivePeerDependencies: - supports-color - find-my-way-ts@0.1.6: {} - find-node-modules@2.1.3: dependencies: findup-sync: 4.0.0 @@ -14145,6 +13813,8 @@ snapshots: flatted@3.4.2: {} + flatted@3.4.4: {} + focus-trap@8.2.2: dependencies: tabbable: 6.5.0 @@ -14855,7 +14525,7 @@ snapshots: '@babel/parser': 7.29.8 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.8.5 + semver: 7.7.4 transitivePeerDependencies: - supports-color @@ -15109,7 +14779,7 @@ snapshots: jest-message-util: 30.2.0 jest-util: 30.2.0 pretty-format: 30.2.0 - semver: 7.8.5 + semver: 7.7.4 synckit: 0.11.11 transitivePeerDependencies: - supports-color @@ -15235,6 +14905,8 @@ snapshots: espree: 9.6.1 semver: 7.7.4 + jsonc-parser@3.2.0: {} + jsonc-parser@3.3.1: {} jsonfile@6.2.1: @@ -15441,6 +15113,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@1.4.2: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + magicast@0.5.4: dependencies: '@babel/parser': 7.29.8 @@ -15592,22 +15268,6 @@ snapshots: ms@2.1.3: {} - msgpackr-extract@3.0.3: - dependencies: - node-gyp-build-optional-packages: 5.2.2 - optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3 - optional: true - - msgpackr@1.11.5: - optionalDependencies: - msgpackr-extract: 3.0.3 - msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3): dependencies: '@inquirer/confirm': 5.1.20(@types/node@24.9.2) @@ -15633,8 +15293,6 @@ snapshots: transitivePeerDependencies: - '@types/node' - multipasta@0.2.7: {} - mute-stream@0.0.8: {} mute-stream@1.0.0: {} @@ -15657,17 +15315,10 @@ snapshots: nice-try@1.0.5: {} - node-addon-api@7.1.1: {} - node-fetch@2.6.7: dependencies: whatwg-url: 5.0.0 - node-gyp-build-optional-packages@5.2.2: - dependencies: - detect-libc: 2.1.2 - optional: true - node-int64@0.4.0: {} node-releases@2.0.27: {} @@ -15881,7 +15532,7 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - obug@2.2.1: {} + obug@2.1.4: {} on-exit-leak-free@2.1.2: {} @@ -16253,8 +15904,6 @@ snapshots: punycode@2.3.1: {} - pure-rand@6.1.0: {} - pure-rand@7.0.1: {} pure-rand@8.4.0: {} @@ -16350,6 +15999,17 @@ snapshots: dependencies: resolve: 1.22.11 + redis@6.3.0(@opentelemetry/api@1.9.0): + dependencies: + '@redis/bloom': 6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0)) + '@redis/client': 6.3.0(@opentelemetry/api@1.9.0) + '@redis/json': 6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0)) + '@redis/search': 6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0)) + '@redis/time-series': 6.3.0(@redis/client@6.3.0(@opentelemetry/api@1.9.0)) + transitivePeerDependencies: + - '@node-rs/xxhash' + - '@opentelemetry/api' + redux-thunk@3.1.0(redux@5.0.1): dependencies: redux: 5.0.1 @@ -16716,8 +16376,6 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 - siginfo@2.0.0: {} - signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -16821,8 +16479,6 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - stackback@0.0.2: {} - statuses@2.0.1: {} statuses@2.0.2: {} @@ -17102,7 +16758,7 @@ snapshots: dependencies: convert-hrtime: 5.0.0 - tinybench@2.9.0: {} + tinybench@6.2.0: {} tinyexec@1.0.2: {} @@ -17113,6 +16769,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinyrainbow@3.1.1: {} tldts-core@6.1.86: {} @@ -17147,8 +16808,6 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - toml@3.0.0: {} - totalist@3.0.1: {} tough-cookie@5.1.2: @@ -17439,8 +17098,6 @@ snapshots: utils-merge@1.0.1: {} - uuid@11.1.1: {} - uuid@14.0.0: {} uuid@8.3.2: {} @@ -17551,39 +17208,33 @@ snapshots: tsx: 4.21.0 yaml: 2.9.0 - vitest-canvas-mock@1.1.3(vitest@4.1.11): + vitest-canvas-mock@1.1.4(vitest@5.0.3): dependencies: cssfontparser: 1.2.1 moo-color: 1.0.3 - vitest: 4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + vitest: 5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) - vitest@4.1.11(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@4.1.11)(@vitest/ui@4.1.11)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)): + vitest@5.0.3(@opentelemetry/api@1.9.0)(@types/node@24.9.2)(@vitest/coverage-v8@5.0.3)(@vitest/ui@5.0.3)(jsdom@27.4.0(@noble/hashes@1.8.0))(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.11 - '@vitest/runner': 4.1.11 - '@vitest/snapshot': 4.1.11 - '@vitest/spy': 4.1.11 - '@vitest/utils': 4.1.11 + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.3(msw@2.12.1(@types/node@24.9.2)(typescript@5.8.3))(vite@7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0)) + chai: 6.2.2 es-module-lexer: 2.3.2 expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.2.1 - pathe: 2.0.3 + magic-string: 1.4.2 + obug: 2.1.4 picomatch: 4.0.4 std-env: 4.2.0 - tinybench: 2.9.0 + tinybench: 6.2.0 tinyexec: 1.3.1 - tinyglobby: 0.2.15 - tinyrainbow: 3.1.1 + tinyglobby: 0.2.17 vite: 7.3.6(@types/node@24.9.2)(jiti@2.6.1)(terser@5.48.0)(tsx@4.21.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 + why-is-node-running: 3.2.1 optionalDependencies: '@opentelemetry/api': 1.9.0 '@types/node': 24.9.2 - '@vitest/coverage-v8': 4.1.11(vitest@4.1.11) - '@vitest/ui': 4.1.11(vitest@4.1.11) + '@vitest/coverage-v8': 5.0.3(vitest@5.0.3) + '@vitest/ui': 5.0.3(vitest@5.0.3) jsdom: 27.4.0(@noble/hashes@1.8.0) transitivePeerDependencies: - msw @@ -17730,10 +17381,7 @@ snapshots: dependencies: isexe: 3.1.1 - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 + why-is-node-running@3.2.1: {} word-wrap@1.2.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3e81db6c006..a0478f5dfe6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,17 +18,16 @@ catalog: typescript: '5.8.3' catalogs: effect: - effect: '^3.20.0' - '@effect/cli': '^0.69.0' - '@effect/language-service': '^0.35.2' - '@effect/platform': '^0.90.0' - '@effect/platform-node': '0.94.2' - '@effect/vitest': '^0.27.0' - '@effect/opentelemetry': '^0.56.1' + effect: '4.0.0' + '@effect/language-service': '0.87.3' + '@effect/platform-node': '4.0.0' + '@effect/vitest': '4.0.0' + '@effect/opentelemetry': '4.0.0' vitest: - vitest: '^4.1.11' - '@vitest/coverage-v8': '^4.1.11' - 'vitest-canvas-mock': '^1.1.3' + vitest: '^5.0.0' + '@vitest/coverage-v8': '^5.0.0' + '@vitest/ui': '^5.0.0' + 'vitest-canvas-mock': '^1.1.4' vite: vite: '^7.3.6' diff --git a/tools/release/commands/commands.ts b/tools/release/commands/commands.ts index 7b598675629..4d64965ffb3 100644 --- a/tools/release/commands/commands.ts +++ b/tools/release/commands/commands.ts @@ -1,6 +1,7 @@ import { Effect } from 'effect'; -import { Command } from '@effect/platform'; -import { FileSystem, Path } from '@effect/platform'; +import * as Command from 'effect/cli/Command'; +import * as FileSystem from 'effect/FileSystem'; +import * as Path from 'effect/Path'; import { CommandExitError, GitStatusError, diff --git a/tools/release/package.json b/tools/release/package.json index 5925c21ecb8..7cebf9aef23 100644 --- a/tools/release/package.json +++ b/tools/release/package.json @@ -9,7 +9,6 @@ "main": "index.js", "scripts": {}, "dependencies": { - "@effect/platform": "catalog:effect", "@effect/platform-node": "catalog:effect", "effect": "catalog:effect" } diff --git a/tools/user-scripts/package.json b/tools/user-scripts/package.json index 1ccceadab5c..d8049468312 100644 --- a/tools/user-scripts/package.json +++ b/tools/user-scripts/package.json @@ -16,7 +16,6 @@ "test:watch": "pnpm nx nxTest --watch" }, "dependencies": { - "@effect/platform": "catalog:effect", "@effect/platform-node": "catalog:effect", "effect": "catalog:effect", "vitest": "catalog:vitest" diff --git a/tools/user-scripts/src/lib/user-scripts.test.ts b/tools/user-scripts/src/lib/user-scripts.test.ts index 56339a3e6f8..b5cb40ac060 100644 --- a/tools/user-scripts/src/lib/user-scripts.test.ts +++ b/tools/user-scripts/src/lib/user-scripts.test.ts @@ -1,7 +1,7 @@ // import { describe, expect, it } from '@effect/vitest'; // import { GetUsersError, UnexpectedStatus, UserService } from './user-scripts.js'; // import { ConfigProvider, Effect, Layer } from 'effect'; -// import { HttpClient, HttpClientResponse } from '@effect/platform'; +// import { HttpClient, HttpClientResponse } from 'effect/http'; // // const Config = ConfigProvider.fromMap( // new Map([ diff --git a/tools/user-scripts/src/lib/user-scripts.ts b/tools/user-scripts/src/lib/user-scripts.ts index 504218cb7e9..424745d69bd 100644 --- a/tools/user-scripts/src/lib/user-scripts.ts +++ b/tools/user-scripts/src/lib/user-scripts.ts @@ -1,9 +1,12 @@ -import { HttpClient, HttpClientRequest, HttpClientResponse } from '@effect/platform'; import { NodeHttpClient } from '@effect/platform-node'; -import { Config, Data, Effect, ManagedRuntime } from 'effect'; +import { Config, Context, Data, Effect, Layer, ManagedRuntime } from 'effect'; +import { HttpClient, HttpClientRequest, HttpClientResponse } from 'effect/http'; import { getUsersResponse, TokenResponse } from './schemas.js'; +import type { Schema } from 'effect'; +import type { HttpClientError } from 'effect/http'; + export class UnexpectedStatus extends Data.TaggedError('UnExpectedStatus')<{ message: string; cause: string; @@ -29,78 +32,76 @@ export class FailureToAcquireToken extends Data.TaggedError('FailureToAcquireTok cause: string; }> {} -export class UserService extends Effect.Service()('@users/service', { - dependencies: [NodeHttpClient.layerUndici], - effect: Effect.gen(function* () { - const client = yield* HttpClient.HttpClient; - const clientId = yield* Config.string('CLIENT_ID'); - const clientSecret = yield* Config.string('CLIENT_SECRET'); - const envId = yield* Config.string('ENV_ID'); - const AUTH_URL = yield* Config.string('AUTH_URL'); - const API_URL = yield* Config.string('API_URL'); - - const tokenResponse = yield* HttpClientRequest.post(AUTH_URL).pipe( - HttpClientRequest.setHeader('Content-Type', 'application/x-www-form-urlencoded'), - HttpClientRequest.appendUrl(`/${envId}/as/token`), - HttpClientRequest.setUrlParam('grant_type', 'client_credentials'), - HttpClientRequest.setHeader('Authorization', `Basic ${btoa(`${clientId}:${clientSecret}`)}`), - client.execute, - Effect.flatMap(HttpClientResponse.filterStatusOk), - Effect.flatMap(HttpClientResponse.schemaBodyJson(TokenResponse)), - ); - - return { - deleteUser: (userId: string) => - Effect.gen(function* () { - const response = yield* HttpClientRequest.del(API_URL).pipe( - HttpClientRequest.appendUrl(`/v1/environments/${envId}/users/${userId}`), - HttpClientRequest.bearerToken(tokenResponse.access_token), - client.execute, - Effect.flatMap(HttpClientResponse.filterStatusOk), - Effect.catchTag('ResponseError', (e) => - Effect.fail( - new DeleteUserError({ - message: `Failed to delete user, error in response: ${e}`, - cause: e.message, - }), - ), - ), - Effect.catchTag('RequestError', (e) => - Effect.fail( - new DeleteUserError({ - message: `Failed to delete user, error in request: ${e}`, - cause: e.message, - }), - ), - ), - ); +type UsersResponse = typeof getUsersResponse.Type; +type UserServiceErrors = UnexpectedStatus | DeleteUserError | HttpClientError.HttpClientError; + +export class UserService extends Context.Service< + UserService, + { + readonly deleteUser: ( + userId: string, + ) => Effect.Effect; + readonly getUsers: ( + filterTerm: string, + query: string, + ) => Effect.Effect; + } +>()('@users/service') {} + +const makeUserService = Effect.gen(function* () { + const client = yield* HttpClient.HttpClient; + const clientId = yield* Config.String('CLIENT_ID'); + const clientSecret = yield* Config.String('CLIENT_SECRET'); + const envId = yield* Config.String('ENV_ID'); + const AUTH_URL = yield* Config.String('AUTH_URL'); + const API_URL = yield* Config.String('API_URL'); + + const tokenResponse = yield* HttpClientRequest.post(AUTH_URL).pipe( + HttpClientRequest.setHeader('Content-Type', 'application/x-www-form-urlencoded'), + HttpClientRequest.appendUrl(`/${envId}/as/token`), + HttpClientRequest.setUrlParam('grant_type', 'client_credentials'), + HttpClientRequest.setHeader('Authorization', `Basic ${btoa(`${clientId}:${clientSecret}`)}`), + client.execute, + Effect.flatMap(HttpClientResponse.filterStatusOk), + Effect.flatMap(HttpClientResponse.schemaBodyJson(TokenResponse)), + ); - /** - * Docs says we should expect a 204 response for success - */ - if (response.status !== 204) { - return yield* Effect.fail( - new UnexpectedStatus({ - message: 'Unexpected status code', - cause: response.status.toString(), - }), - ); - } - - return response; - }), - getUsers: (filterTerm: string, query: string) => - HttpClientRequest.get(API_URL).pipe( - HttpClientRequest.setHeader('Content-Type', 'application/json'), - HttpClientRequest.appendUrl(`/v1/environments/${envId}/users`), - HttpClientRequest.appendUrlParam('filter', `${filterTerm} eq "${query}"`), + return { + deleteUser: (userId: string) => + Effect.gen(function* () { + const response = yield* HttpClientRequest.delete(API_URL).pipe( + HttpClientRequest.appendUrl(`/v1/environments/${envId}/users/${userId}`), HttpClientRequest.bearerToken(tokenResponse.access_token), client.execute, Effect.flatMap(HttpClientResponse.filterStatusOk), - Effect.flatMap(HttpClientResponse.schemaBodyJson(getUsersResponse)), - ), - }; - }), -}) {} + ); + + if (response.status !== 204) { + return yield* Effect.fail( + new UnexpectedStatus({ + message: 'Unexpected status code', + cause: response.status.toString(), + }), + ); + } + + return response; + }), + getUsers: (filterTerm: string, query: string) => + HttpClientRequest.get(API_URL).pipe( + HttpClientRequest.setHeader('Content-Type', 'application/json'), + HttpClientRequest.appendUrl(`/v1/environments/${envId}/users`), + HttpClientRequest.appendUrlParam('filter', `${filterTerm} eq "${query}"`), + HttpClientRequest.bearerToken(tokenResponse.access_token), + client.execute, + Effect.flatMap(HttpClientResponse.filterStatusOk), + Effect.flatMap(HttpClientResponse.schemaBodyJson(getUsersResponse)), + ), + }; +}); + +export const UserServiceLayer = Layer.effect(UserService, makeUserService).pipe( + Layer.provide(NodeHttpClient.layerUndici), +); -export const UserRuntime = ManagedRuntime.make(UserService.Default); +export const UserRuntime = ManagedRuntime.make(UserServiceLayer); diff --git a/tsconfig.json b/tsconfig.json index 5bac2012e83..19174a55654 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -79,6 +79,9 @@ { "path": "./tools/api-report" }, + { + "path": "./packages/sdk-effects/wellknown" + }, { "path": "./packages/recognize" },