Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 12 additions & 4 deletions packages/core/src/shared/wizards/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
private assertReady() {
// Check for `false` explicity so that the base-class constructor can access `this._form`.
// We want to guard against confusion when implementing a subclass, not this base-class.
if (this._ready === false && this.init) {
if (this._ready === false) {
throw Error('run() (or init()) must be called immediately after creating the Wizard')
}
}
Expand All @@ -113,7 +113,7 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
return this._stepOffset[1] + this.stateController.totalSteps
}

public get _form() {
protected get _form() {
this.assertReady()
return this.__form
}
Expand All @@ -136,14 +136,23 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
this._estimator = estimator
}

public constructor(private readonly options: WizardOptions<TState> = {}) {
public constructor(protected readonly options: WizardOptions<TState> = {}) {
this.stateController = new StateMachineController(options.initState as TState)
this.__form = options.initForm ?? new WizardForm()
this._exitStep =
options.exitPrompterProvider !== undefined ? this.createExitStep(options.exitPrompterProvider) : undefined

// Subclass constructor logic should live in `init()`, if it exists.
this._ready = !this.init

if (typeof this.init === 'function') {
// eslint-disable-next-line @typescript-eslint/unbound-method
const _init = this.init
Copy link
Contributor

Choose a reason for hiding this comment

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

can the eslint ignore be avoided, by something like:

Suggested change
// eslint-disable-next-line @typescript-eslint/unbound-method
const _init = this.init
const _init = this.init.bind(this)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for pointing that out! I've replaced .apply(this) with .bind(this), which fixes the unbound method issue and removes the need for the ESLint comment.

this.init = () => {
this._ready = true
return _init.apply(this)
}
}
}

/**
Expand All @@ -166,7 +175,6 @@ export class Wizard<TState extends Partial<Record<keyof TState, unknown>>> {
if (!this._ready && this.init) {
this._ready = true // Let init() use `this._form`.
await this.init()
delete this.init
}

this.assignSteps()
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/test/shared/wizards/wizardTestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ function failIf(cond: boolean, message?: string): void {
export async function createWizardTester<T extends Partial<T>>(wizard: Wizard<T> | WizardForm<T>): Promise<Tester<T>> {
if (wizard instanceof Wizard && wizard.init) {
// Ensure that init() was called. Needed because createWizardTester() does not call run().
;(wizard as any)._ready = true
await wizard.init()
delete wizard.init
}

const form = wizard instanceof Wizard ? wizard.boundForm : wizard
Expand Down
Loading