Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cool-kings-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@forgerock/journey-client': patch
---

patch @forgerock/journey-client: export PolicyParams from journey-client/types
83 changes: 83 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,37 @@ if ('error' in result) {

---

## StepOptions → StartParam / NextOptions / ResumeOptions

For the full type-level mapping see [`interface_mapping.md` § Authentication Flow](./interface_mapping.md#3-authentication-flow). The three implementation pain points that aren't obvious from the type table:

**1. `tree` is no longer threaded through `next()`.**

The legacy pattern merged `initOptions` and `nextOptions` and passed the combined object to both `start()` and `next()`, carrying `tree` through every call. In the new SDK, `next()` does not accept a journey name — it only takes `{ query? }`. Remove any options merging/forwarding from your `next()` wrapper.

```typescript
// Legacy — options object merged and threaded through every call
const options = { ...initOptions, ...nextOptions };
await FRAuth.next(prevStep, options); // tree still in options

// New — next() has no journey param; don't merge options through
await journeyClient.next(prevStep, { query: nextOptions?.query });
```

**2. A journey stack stored `StepOptions[]`; it now stores `StartParam[]`.**

If you maintain a stack for switching between trees, the stored type changes from `StepOptions` to `StartParam` and the deduplication key changes from `tree` to `journey`:

```typescript
// Legacy
if (options?.tree !== current[current.length - 1]?.tree) { ... }

// New
if (options?.journey !== current[current.length - 1]?.journey) { ... }
```

---

## Step Types

| Legacy | New | Notes |
Expand All @@ -160,6 +191,58 @@ if ('error' in result) {

All step methods (`getCallbackOfType`, `getDescription`, `getHeader`, `getStage`, `getSessionToken`, etc.) remain identical.

### Creating a JourneyStep for Tests and Stories

The legacy SDK created step objects by instantiating `new FRStep(payload)`, `new FRLoginSuccess(payload)`, or `new FRLoginFailure(payload)`. The new SDK creates these internally — there are no classes to instantiate. Because all three types are plain objects, replace every `new FR*` call with an object literal typed against the corresponding interface:

```typescript
// Before
import { FRStep, FRLoginSuccess, FRLoginFailure } from '@forgerock/javascript-sdk';
const step = new FRStep(payload);
const success = new FRLoginSuccess(payload);
const failure = new FRLoginFailure(payload);

// After
import type {
JourneyStep,
JourneyLoginSuccess,
JourneyLoginFailure,
} from '@forgerock/journey-client/types';
import { StepType, createCallback } from '@forgerock/journey-client/types';

const mockStep: JourneyStep = {
type: StepType.Step,
payload: rawPayload,
callbacks: rawPayload.callbacks?.map(createCallback) ?? [],
getCallbackOfType: (type) => {
throw new Error('not implemented');
},
getCallbacksOfType: (type) => [],
setCallbackValue: () => {},
getDescription: () => undefined,
getHeader: () => undefined,
getStage: () => undefined,
};

const mockSuccess: JourneyLoginSuccess = {
type: StepType.LoginSuccess,
payload: rawPayload,
getRealm: () => 'alpha',
getSessionToken: () => 'abc123',
getSuccessUrl: () => undefined,
};

const mockFailure: JourneyLoginFailure = {
type: StepType.LoginFailure,
payload: rawPayload,
getCode: () => 401,
getDetail: () => undefined,
getMessage: () => 'Login failure',
getReason: () => undefined,
getProcessedMessage: () => [],
};
```

---

## HTTP Client
Expand Down
12 changes: 6 additions & 6 deletions interface_mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Flat lookup table for AI context injection. Every legacy symbol → new import i
| `ErrorCode` | Removed — use `GenericError.type` instead |
| `FRAuth` | `import { journey } from '@forgerock/journey-client'` — factory returns `JourneyClient` |
| `FRCallback` | `import { BaseCallback } from '@forgerock/journey-client/types'` |
| `FRDevice` | `import { deviceClient } from '@forgerock/device-client'` |
| `FRDevice` | `import { Device } from '@forgerock/journey-client/device'` |
| `FRLoginFailure` | `import type { JourneyLoginFailure } from '@forgerock/journey-client/types'` |
| `FRLoginSuccess` | `import type { JourneyLoginSuccess } from '@forgerock/journey-client/types'` |
| `FRPolicy` | `import { Policy } from '@forgerock/journey-client/policy'` |
Expand Down Expand Up @@ -178,7 +178,7 @@ The legacy SDK is a single package. The new SDK splits concerns across multiple
| `import { deviceClient } from '@forgerock/javascript-sdk'` | `import { deviceClient } from '@forgerock/device-client'` | deviceClient |
| `import { FRAuth } from '@forgerock/javascript-sdk'` | `import { journey } from '@forgerock/journey-client'` | FRAuth |
| `import { FRCallback } from '@forgerock/javascript-sdk'` | `import { BaseCallback } from '@forgerock/journey-client/types'` | FRCallback |
| `import { FRDevice } from '@forgerock/javascript-sdk'` | `import { deviceClient } from '@forgerock/device-client'` | FRDevice |
| `import { FRDevice } from '@forgerock/javascript-sdk'` | `import { Device } from '@forgerock/journey-client/device'` | FRDevice |
| `import type { FRLoginFailure } from '@forgerock/javascript-sdk'` | `import type { JourneyLoginFailure } from '@forgerock/journey-client/types'` | FRLoginFailure |
| `import type { FRLoginSuccess } from '@forgerock/javascript-sdk'` | `import type { JourneyLoginSuccess } from '@forgerock/journey-client/types'` | FRLoginSuccess |
| `import { FRPolicy } from '@forgerock/javascript-sdk'` | `import { Policy } from '@forgerock/journey-client/policy'` | FRPolicy |
Expand Down Expand Up @@ -955,10 +955,10 @@ if (type === WebAuthnStepType.Authentication) {

### FRDevice (Device Profile Collection)

| Legacy API | New API | Return Type Change | Behavioral Notes |
| ---------------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------- |
| `import { FRDevice } from '@forgerock/javascript-sdk'` | Device profile functionality via `@forgerock/device-client` | — | Class-based → factory function |
| `new FRDevice(config?).getProfile({ location, metadata })` | `deviceClient(config).profile.get(query)` | `DeviceProfileData` → `ProfileDevice[] \| { error }` | Returns error object instead of throwing |
| Legacy API | New API | Return Type Change | Behavioral Notes |
| ---------------------------------------------------------- | ----------------------------------------------------------- | ------------------ | ---------------------------------------------------------------- |
| `import { FRDevice } from '@forgerock/javascript-sdk'` | `import { Device } from '@forgerock/journey-client/device'` | — | Class renamed `FRDevice` → `Device`. **Subpath import required** |
| `new FRDevice(config?).getProfile({ location, metadata })` | `new Device(config?).getProfile({ location, metadata })` | Same | Same signature and return type (`DeviceProfileData`) |

### deviceClient (Device CRUD Operations)

Expand Down
3 changes: 3 additions & 0 deletions packages/journey-client/api-report/journey-client.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { isValidWellknownUrl } from '@forgerock/sdk-utilities';
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';
Expand Down Expand Up @@ -338,6 +339,8 @@ export class PingOneProtectInitializeCallback extends BaseCallback {

export { PolicyKey }

export { PolicyParams }

export { PolicyRequirement }

// @public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { AsyncLegacyConfigOptions } from '@forgerock/sdk-types';
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';
Expand All @@ -18,6 +19,7 @@ import { isValidWellknownUrl } from '@forgerock/sdk-utilities';
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';
Expand Down Expand Up @@ -61,6 +63,8 @@ export type CallbackFactory = (callback: Callback) => BaseCallback;

export { CallbackType }

export { callbackType }

// @public
export class ChoiceCallback extends BaseCallback {
constructor(payload: Callback);
Expand Down Expand Up @@ -325,6 +329,8 @@ export class PingOneProtectInitializeCallback extends BaseCallback {

export { PolicyKey }

export { PolicyParams }

export { PolicyRequirement }

// @public
Expand Down
3 changes: 0 additions & 3 deletions packages/journey-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,3 @@

export * from './lib/client.store.js';
export * from './types.js';

// Re-export types from internal packages that consumers need
export { callbackType } from '@forgerock/sdk-types';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is tricky since its both a type and a value. we may want to keep this here, doing otherwise breaks the api.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh okay. Moving it to types looked cleaner. Why does it break the API? Can we

export type { callbackType } from '@forgerock/sdk-types';

along with

export { callbackType, PolicyKey, StepType } from '@forgerock/sdk-types';

in types.ts file? Just a thought to keep index.ts cleaner.

4 changes: 2 additions & 2 deletions packages/journey-client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ export type {
Step,
Callback,
CallbackType,
StepType,
GenericError,
PolicyRequirement,
FailedPolicyRequirement,
NameValue,
PolicyParams,
StepDetail,
AuthResponse,
FailureDetail,
} from '@forgerock/sdk-types';

export { PolicyKey } from '@forgerock/sdk-types';
export { callbackType, PolicyKey, StepType } from '@forgerock/sdk-types';

// Re-export local types
export * from './lib/client.types.js';
Expand Down
Loading