Skip to content

Commit 08042da

Browse files
committed
fix(app): satisfy current lint rules
1 parent 9140d58 commit 08042da

41 files changed

Lines changed: 4218 additions & 4119 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import { Either } from "effect"
2+
3+
import type { ParseError } from "./frontend-lib/core/domain.js"
4+
import {
5+
type AdvanceCreateFlowHandlers,
6+
type AdvanceCreateFlowOptions,
7+
type AdvanceCreateFlowResult,
8+
type CreateFlowContext,
9+
type CreateFlowView,
10+
type CreateModeFlowView,
11+
type DisplayModeFlowView,
12+
firstCreateSettingsStepIndex,
13+
isDisplayModeFlowView,
14+
type Mutable
15+
} from "./menu-create-flow-types.js"
16+
import { normalizeCreateFlowContext, resolveCreateInputs } from "./menu-create-inputs.js"
17+
import { clampCreateSettingsStep, moveCreateDisplaySettingsStep } from "./menu-create-navigation.js"
18+
import { applyCreateBufferToValues } from "./menu-create-step-apply.js"
19+
import { resolveCreateDisplaySteps, resolveCreateFlowSteps } from "./menu-create-steps.js"
20+
import type { CreateInputs, CreateStep } from "./menu-types.js"
21+
22+
export const createInitialFlowView = (buffer = ""): CreateModeFlowView => ({
23+
mode: "create",
24+
step: 0,
25+
buffer,
26+
inputError: null,
27+
values: {}
28+
})
29+
30+
const resolveDisplayFlowStep = (view: CreateFlowView): number => {
31+
const displaySteps = resolveCreateDisplaySteps()
32+
if (isDisplayModeFlowView(view)) {
33+
return clampCreateSettingsStep(view.step, displaySteps.length - 1)
34+
}
35+
const flowStep = resolveCreateFlowSteps(view.values)[view.step]
36+
const displayStep = flowStep === undefined ? -1 : displaySteps.indexOf(flowStep)
37+
return clampCreateSettingsStep(displayStep === -1 ? view.step : displayStep, displaySteps.length - 1)
38+
}
39+
40+
export const createDisplayFlowView = (view: CreateFlowView): DisplayModeFlowView => ({
41+
mode: "display",
42+
step: resolveDisplayFlowStep(view),
43+
buffer: view.buffer,
44+
inputError: null,
45+
values: view.values
46+
})
47+
48+
const shouldQuickCreate = (
49+
step: CreateStep,
50+
options: AdvanceCreateFlowOptions
51+
): boolean =>
52+
step === "repoUrl" &&
53+
options.quickCreate === true
54+
55+
const continueCreateFlow = (
56+
nextStep: number,
57+
nextValues: Partial<Mutable<CreateInputs>>
58+
): AdvanceCreateFlowResult => ({
59+
_tag: "Continue",
60+
view: {
61+
mode: "create",
62+
step: nextStep,
63+
buffer: "",
64+
inputError: null,
65+
values: nextValues
66+
}
67+
})
68+
69+
const continueCreateDisplayFlow = (
70+
view: DisplayModeFlowView,
71+
nextValues: Partial<Mutable<CreateInputs>>
72+
): AdvanceCreateFlowResult => ({
73+
_tag: "Continue",
74+
view: {
75+
...view,
76+
buffer: "",
77+
inputError: null,
78+
values: nextValues
79+
}
80+
})
81+
82+
type ActiveCreateDisplayContext = {
83+
readonly context: CreateFlowContext
84+
readonly step: CreateStep
85+
}
86+
87+
const resolveActiveCreateDisplayStep = (view: DisplayModeFlowView): CreateStep | null => {
88+
const step = resolveCreateDisplaySteps()[view.step]
89+
return view.step < firstCreateSettingsStepIndex || step === undefined ? null : step
90+
}
91+
92+
const resolveActiveCreateDisplayContext = (
93+
contextOrCwd: string | CreateFlowContext,
94+
view: DisplayModeFlowView
95+
): ActiveCreateDisplayContext | null => {
96+
const step = resolveActiveCreateDisplayStep(view)
97+
return step === null
98+
? null
99+
: {
100+
context: normalizeCreateFlowContext(contextOrCwd),
101+
step
102+
}
103+
}
104+
105+
const completeCreateFlow = (
106+
context: CreateFlowContext,
107+
values: Partial<CreateInputs>
108+
): AdvanceCreateFlowResult => ({
109+
_tag: "Complete",
110+
inputs: resolveCreateInputs(context, values)
111+
})
112+
113+
const foldAppliedCreateValues = (
114+
appliedValues: Either.Either<Partial<Mutable<CreateInputs>>, ParseError>,
115+
onSuccess: (nextValues: Partial<Mutable<CreateInputs>>) => AdvanceCreateFlowResult
116+
): AdvanceCreateFlowResult =>
117+
Either.isLeft(appliedValues)
118+
? {
119+
_tag: "Error",
120+
error: appliedValues.left
121+
}
122+
: onSuccess(appliedValues.right)
123+
124+
const withActiveCreateDisplayContext = (
125+
contextOrCwd: string | CreateFlowContext,
126+
view: DisplayModeFlowView,
127+
onActive: (active: ActiveCreateDisplayContext) => AdvanceCreateFlowResult | null
128+
): AdvanceCreateFlowResult | null => {
129+
const active = resolveActiveCreateDisplayContext(contextOrCwd, view)
130+
return active === null ? null : onActive(active)
131+
}
132+
133+
export const applyCreateDisplaySettingsStep = (
134+
contextOrCwd: string | CreateFlowContext,
135+
view: DisplayModeFlowView
136+
): AdvanceCreateFlowResult | null =>
137+
withActiveCreateDisplayContext(contextOrCwd, view, (active) =>
138+
foldAppliedCreateValues(
139+
applyCreateBufferToValues(active.context, view, active.step),
140+
(nextValues) => continueCreateDisplayFlow(view, nextValues)
141+
))
142+
143+
export const advanceCreateDisplaySettingsStep = (
144+
contextOrCwd: string | CreateFlowContext,
145+
view: DisplayModeFlowView
146+
): AdvanceCreateFlowResult | null => {
147+
const applied = applyCreateDisplaySettingsStep(contextOrCwd, view)
148+
if (applied === null || applied._tag !== "Continue" || !isDisplayModeFlowView(applied.view)) {
149+
return applied
150+
}
151+
152+
const movedView = moveCreateDisplaySettingsStep(applied.view, "down")
153+
return movedView === null ? applied : { ...applied, view: movedView }
154+
}
155+
156+
export const completeCreateDisplaySettingsFlow = (
157+
contextOrCwd: string | CreateFlowContext,
158+
view: DisplayModeFlowView
159+
): AdvanceCreateFlowResult | null =>
160+
withActiveCreateDisplayContext(contextOrCwd, view, (active) => {
161+
if (view.buffer.trim().length === 0) {
162+
return completeCreateFlow(active.context, view.values)
163+
}
164+
165+
const applied = applyCreateDisplaySettingsStep(active.context, view)
166+
if (applied === null || applied._tag === "Error") {
167+
return applied
168+
}
169+
if (applied._tag === "Continue") {
170+
return completeCreateFlow(active.context, applied.view.values)
171+
}
172+
return applied
173+
})
174+
175+
const resolveNextCreateFlowStep = (
176+
currentStep: CreateStep,
177+
currentStepIndex: number,
178+
nextSteps: ReadonlyArray<CreateStep>
179+
): number =>
180+
currentStep === "repoUrl"
181+
? firstCreateSettingsStepIndex
182+
: clampCreateSettingsStep(currentStepIndex, nextSteps.length - 1)
183+
184+
export const advanceCreateFlow = (
185+
contextOrCwd: string | CreateFlowContext,
186+
view: CreateModeFlowView,
187+
options: AdvanceCreateFlowOptions = {}
188+
): AdvanceCreateFlowResult | null => {
189+
const context = normalizeCreateFlowContext(contextOrCwd)
190+
const currentSteps = resolveCreateFlowSteps(view.values)
191+
const step = currentSteps[view.step]
192+
if (step === undefined) {
193+
return null
194+
}
195+
196+
return foldAppliedCreateValues(
197+
applyCreateBufferToValues(context, view, step),
198+
(nextValues) => {
199+
if (shouldQuickCreate(step, options)) {
200+
return completeCreateFlow(context, nextValues)
201+
}
202+
203+
const nextSteps = resolveCreateFlowSteps(nextValues)
204+
const nextStep = resolveNextCreateFlowStep(step, view.step, nextSteps)
205+
return nextSteps.length > firstCreateSettingsStepIndex && nextStep < nextSteps.length
206+
? continueCreateFlow(nextStep, nextValues)
207+
: completeCreateFlow(context, nextValues)
208+
}
209+
)
210+
}
211+
212+
export const handleAdvanceCreateFlowResult = (
213+
next: AdvanceCreateFlowResult | null,
214+
handlers: AdvanceCreateFlowHandlers
215+
): void => {
216+
if (next === null) {
217+
return
218+
}
219+
if (next._tag === "Error") {
220+
handlers.onError(next.error)
221+
return
222+
}
223+
if (next._tag === "Continue") {
224+
handlers.onContinue(next.view)
225+
return
226+
}
227+
handlers.onComplete(next.inputs)
228+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { Either } from "effect"
2+
3+
import { type GpuMode, isGpuMode, type ParseError } from "./frontend-lib/core/domain.js"
4+
import { createParseError } from "./menu-create-errors.js"
5+
6+
export const renderExplicitBooleanChoice = (value: boolean): string => value ? "Y" : "N"
7+
8+
export const parseBooleanChoice = (input: string): boolean | null => {
9+
const normalized = input.trim().toLowerCase()
10+
if (normalized === "y" || normalized === "yes") {
11+
return true
12+
}
13+
if (normalized === "n" || normalized === "no") {
14+
return false
15+
}
16+
return null
17+
}
18+
19+
export const parseExplicitBooleanChoice = parseBooleanChoice
20+
21+
export const parseExplicitGpuChoice = (
22+
input: string
23+
): GpuMode | null => {
24+
const normalized = input.trim().toLowerCase()
25+
if (normalized === "y" || normalized === "yes") {
26+
return "all"
27+
}
28+
if (normalized === "n" || normalized === "no") {
29+
return "none"
30+
}
31+
if (isGpuMode(normalized)) {
32+
return normalized
33+
}
34+
return null
35+
}
36+
37+
export const parseGpuInput = (
38+
input: string,
39+
fallback: GpuMode
40+
): Either.Either<GpuMode, ParseError> => {
41+
const normalized = input.trim().toLowerCase()
42+
if (normalized.length === 0) {
43+
return Either.right(fallback)
44+
}
45+
if (normalized === "y" || normalized === "yes") {
46+
return Either.right("all")
47+
}
48+
if (normalized === "n" || normalized === "no") {
49+
return Either.right("none")
50+
}
51+
if (isGpuMode(normalized)) {
52+
return Either.right(normalized)
53+
}
54+
return Either.left(createParseError("gpu must be one of: none, all, yes, no"))
55+
}
56+
57+
export const parseYesDefault = (input: string, fallback: boolean): boolean => parseBooleanChoice(input) ?? fallback

0 commit comments

Comments
 (0)