Skip to content

Commit dc26d75

Browse files
committed
fix(ci): reduce auth codec lint complexity
1 parent 024ecea commit dc26d75

File tree

1 file changed

+102
-46
lines changed

1 file changed

+102
-46
lines changed
Lines changed: 102 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,55 @@
11
import { asObject, asString, type JsonValue } from "./api-json.js"
22
import type { AuthSnapshot, ProjectAuthSnapshot } from "./menu-types.js"
33

4-
const readNumber = (value: JsonValue | undefined): number | null =>
5-
typeof value === "number" ? value : null
4+
type RawAuthSnapshot = {
5+
readonly globalEnvPath: string | null
6+
readonly claudeAuthPath: string | null
7+
readonly geminiAuthPath: string | null
8+
readonly totalEntries: number | null
9+
readonly githubTokenEntries: number | null
10+
readonly gitTokenEntries: number | null
11+
readonly gitUserEntries: number | null
12+
readonly claudeAuthEntries: number | null
13+
readonly geminiAuthEntries: number | null
14+
}
15+
16+
type RawProjectAuthSnapshot = {
17+
readonly projectDir: string | null
18+
readonly projectName: string | null
19+
readonly envGlobalPath: string | null
20+
readonly envProjectPath: string | null
21+
readonly claudeAuthPath: string | null
22+
readonly geminiAuthPath: string | null
23+
readonly githubTokenEntries: number | null
24+
readonly gitTokenEntries: number | null
25+
readonly claudeAuthEntries: number | null
26+
readonly geminiAuthEntries: number | null
27+
readonly activeGithubLabel: string | null
28+
readonly activeGitLabel: string | null
29+
readonly activeClaudeLabel: string | null
30+
readonly activeGeminiLabel: string | null
31+
}
32+
33+
const readNumber = (value: JsonValue | undefined): number | null => typeof value === "number" ? value : null
34+
const stringOrEmpty = (value: string | null): string => value ?? ""
35+
const numberOrZero = (value: number | null): number => value ?? 0
36+
const hasNullValue = (
37+
values: ReadonlyArray<string | number | null>
38+
): boolean => values.includes(null)
639

740
const resolveSnapshotObject = (payload: JsonValue) => {
841
const object = asObject(payload)
942
return asObject(object?.["snapshot"] ?? payload)
1043
}
1144

12-
export const decodeAuthSnapshot = (payload: JsonValue): AuthSnapshot | null => {
13-
const snapshot = resolveSnapshotObject(payload)
45+
const readAuthSnapshot = (
46+
snapshot: ReturnType<typeof resolveSnapshotObject>
47+
): RawAuthSnapshot | null => {
1448
if (snapshot === null) {
1549
return null
1650
}
1751

18-
const decoded = {
52+
return {
1953
globalEnvPath: asString(snapshot["globalEnvPath"]),
2054
claudeAuthPath: asString(snapshot["claudeAuthPath"]),
2155
geminiAuthPath: asString(snapshot["geminiAuthPath"]),
@@ -26,29 +60,34 @@ export const decodeAuthSnapshot = (payload: JsonValue): AuthSnapshot | null => {
2660
claudeAuthEntries: readNumber(snapshot["claudeAuthEntries"]),
2761
geminiAuthEntries: readNumber(snapshot["geminiAuthEntries"])
2862
}
63+
}
64+
65+
const decodeRequiredAuthSnapshot = (snapshot: RawAuthSnapshot): AuthSnapshot | null => {
66+
if (hasNullValue(Object.values(snapshot))) {
67+
return null
68+
}
2969

30-
return Object.values(decoded).includes(null)
31-
? null
32-
: {
33-
globalEnvPath: decoded.globalEnvPath ?? "",
34-
claudeAuthPath: decoded.claudeAuthPath ?? "",
35-
geminiAuthPath: decoded.geminiAuthPath ?? "",
36-
totalEntries: decoded.totalEntries ?? 0,
37-
githubTokenEntries: decoded.githubTokenEntries ?? 0,
38-
gitTokenEntries: decoded.gitTokenEntries ?? 0,
39-
gitUserEntries: decoded.gitUserEntries ?? 0,
40-
claudeAuthEntries: decoded.claudeAuthEntries ?? 0,
41-
geminiAuthEntries: decoded.geminiAuthEntries ?? 0
42-
}
70+
return {
71+
globalEnvPath: stringOrEmpty(snapshot.globalEnvPath),
72+
claudeAuthPath: stringOrEmpty(snapshot.claudeAuthPath),
73+
geminiAuthPath: stringOrEmpty(snapshot.geminiAuthPath),
74+
totalEntries: numberOrZero(snapshot.totalEntries),
75+
githubTokenEntries: numberOrZero(snapshot.githubTokenEntries),
76+
gitTokenEntries: numberOrZero(snapshot.gitTokenEntries),
77+
gitUserEntries: numberOrZero(snapshot.gitUserEntries),
78+
claudeAuthEntries: numberOrZero(snapshot.claudeAuthEntries),
79+
geminiAuthEntries: numberOrZero(snapshot.geminiAuthEntries)
80+
}
4381
}
4482

45-
export const decodeProjectAuthSnapshot = (payload: JsonValue): ProjectAuthSnapshot | null => {
46-
const snapshot = resolveSnapshotObject(payload)
83+
const readProjectAuthSnapshot = (
84+
snapshot: ReturnType<typeof resolveSnapshotObject>
85+
): RawProjectAuthSnapshot | null => {
4786
if (snapshot === null) {
4887
return null
4988
}
5089

51-
const decoded = {
90+
return {
5291
projectDir: asString(snapshot["projectDir"]),
5392
projectName: asString(snapshot["projectName"]),
5493
envGlobalPath: asString(snapshot["envGlobalPath"]),
@@ -64,37 +103,54 @@ export const decodeProjectAuthSnapshot = (payload: JsonValue): ProjectAuthSnapsh
64103
activeClaudeLabel: asString(snapshot["activeClaudeLabel"]),
65104
activeGeminiLabel: asString(snapshot["activeGeminiLabel"])
66105
}
106+
}
67107

108+
const decodeRequiredProjectAuthSnapshot = (
109+
snapshot: RawProjectAuthSnapshot
110+
): ProjectAuthSnapshot | null => {
68111
const requiredValues = [
69-
decoded.projectDir,
70-
decoded.projectName,
71-
decoded.envGlobalPath,
72-
decoded.envProjectPath,
73-
decoded.claudeAuthPath,
74-
decoded.geminiAuthPath,
75-
decoded.githubTokenEntries,
76-
decoded.gitTokenEntries,
77-
decoded.claudeAuthEntries,
78-
decoded.geminiAuthEntries
112+
snapshot.projectDir,
113+
snapshot.projectName,
114+
snapshot.envGlobalPath,
115+
snapshot.envProjectPath,
116+
snapshot.claudeAuthPath,
117+
snapshot.geminiAuthPath,
118+
snapshot.githubTokenEntries,
119+
snapshot.gitTokenEntries,
120+
snapshot.claudeAuthEntries,
121+
snapshot.geminiAuthEntries
79122
]
80-
if (requiredValues.includes(null)) {
123+
124+
if (hasNullValue(requiredValues)) {
81125
return null
82126
}
83127

84128
return {
85-
projectDir: decoded.projectDir ?? "",
86-
projectName: decoded.projectName ?? "",
87-
envGlobalPath: decoded.envGlobalPath ?? "",
88-
envProjectPath: decoded.envProjectPath ?? "",
89-
claudeAuthPath: decoded.claudeAuthPath ?? "",
90-
geminiAuthPath: decoded.geminiAuthPath ?? "",
91-
githubTokenEntries: decoded.githubTokenEntries ?? 0,
92-
gitTokenEntries: decoded.gitTokenEntries ?? 0,
93-
claudeAuthEntries: decoded.claudeAuthEntries ?? 0,
94-
geminiAuthEntries: decoded.geminiAuthEntries ?? 0,
95-
activeGithubLabel: decoded.activeGithubLabel,
96-
activeGitLabel: decoded.activeGitLabel,
97-
activeClaudeLabel: decoded.activeClaudeLabel,
98-
activeGeminiLabel: decoded.activeGeminiLabel
129+
projectDir: stringOrEmpty(snapshot.projectDir),
130+
projectName: stringOrEmpty(snapshot.projectName),
131+
envGlobalPath: stringOrEmpty(snapshot.envGlobalPath),
132+
envProjectPath: stringOrEmpty(snapshot.envProjectPath),
133+
claudeAuthPath: stringOrEmpty(snapshot.claudeAuthPath),
134+
geminiAuthPath: stringOrEmpty(snapshot.geminiAuthPath),
135+
githubTokenEntries: numberOrZero(snapshot.githubTokenEntries),
136+
gitTokenEntries: numberOrZero(snapshot.gitTokenEntries),
137+
claudeAuthEntries: numberOrZero(snapshot.claudeAuthEntries),
138+
geminiAuthEntries: numberOrZero(snapshot.geminiAuthEntries),
139+
activeGithubLabel: snapshot.activeGithubLabel,
140+
activeGitLabel: snapshot.activeGitLabel,
141+
activeClaudeLabel: snapshot.activeClaudeLabel,
142+
activeGeminiLabel: snapshot.activeGeminiLabel
99143
}
100144
}
145+
146+
export const decodeAuthSnapshot = (payload: JsonValue): AuthSnapshot | null => {
147+
const snapshot = readAuthSnapshot(resolveSnapshotObject(payload))
148+
return snapshot === null ? null : decodeRequiredAuthSnapshot(snapshot)
149+
}
150+
151+
export const decodeProjectAuthSnapshot = (
152+
payload: JsonValue
153+
): ProjectAuthSnapshot | null => {
154+
const snapshot = readProjectAuthSnapshot(resolveSnapshotObject(payload))
155+
return snapshot === null ? null : decodeRequiredProjectAuthSnapshot(snapshot)
156+
}

0 commit comments

Comments
 (0)