Skip to content

Commit 39e1aac

Browse files
committed
fix ts types
1 parent 882a248 commit 39e1aac

File tree

5 files changed

+74
-10
lines changed

5 files changed

+74
-10
lines changed

scripts/apitypings/main.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/coder/guts"
88
"github.com/coder/guts/bindings"
9+
"github.com/coder/guts/bindings/walk"
910
"github.com/coder/guts/config"
1011
)
1112

@@ -33,7 +34,8 @@ func main() {
3334
"github.com/coder/serpent": "Serpent",
3435
"tailscale.com/derp": "",
3536
// Conflicting name "DERPRegion"
36-
"tailscale.com/tailcfg": "Tail",
37+
"tailscale.com/tailcfg": "Tail",
38+
"tailscale.com/net/netcheck": "Netcheck",
3739
}
3840
for pkg, prefix := range referencePackages {
3941
err = gen.IncludeReference(pkg, prefix)
@@ -75,6 +77,7 @@ func TsMutations(ts *guts.Typescript) {
7577
// Omitempty + null is just '?' in golang json marshal
7678
// number?: number | null --> number?: number
7779
config.SimplifyOmitEmpty,
80+
SimplifyUndefinedUnionFields,
7881
)
7982
}
8083

@@ -84,6 +87,8 @@ func TypeMappings(gen *guts.GoParser) error {
8487

8588
gen.IncludeCustomDeclaration(map[string]guts.TypeOverride{
8689
"github.com/coder/coder/v2/codersdk.NullTime": config.OverrideNullable(config.OverrideLiteral(bindings.KeywordString)),
90+
// opt.Bool can return 'null' if unset
91+
"tailscale.com/types/opt.Bool": config.OverrideNullable(config.OverrideLiteral(bindings.KeywordBoolean)),
8792
})
8893

8994
err := gen.IncludeCustom(map[string]string{
@@ -144,3 +149,32 @@ func FixSerpentStruct(gen *guts.Typescript) {
144149
}
145150
})
146151
}
152+
153+
// SimplifyUndefinedUnionFields converts 'foo: string | undefined' to 'foo?: string'
154+
func SimplifyUndefinedUnionFields(gen *guts.Typescript) {
155+
gen.ForEach(func(key string, originalNode bindings.Node) {
156+
walk.Walk(questionTokenWalker{}, originalNode)
157+
})
158+
}
159+
160+
type questionTokenWalker struct {
161+
}
162+
163+
func (q questionTokenWalker) Visit(node bindings.Node) (w walk.Visitor) {
164+
switch n := node.(type) {
165+
case *bindings.PropertySignature:
166+
isUnion, ok := n.Type.(*bindings.UnionType)
167+
if !ok {
168+
return q
169+
}
170+
for i, t := range isUnion.Types {
171+
if keyword, ok := t.(*bindings.LiteralKeyword); ok && *keyword == bindings.KeywordUndefined {
172+
n.QuestionToken = true
173+
// Remove undefined
174+
isUnion.Types = append(isUnion.Types[:i], isUnion.Types[i+1:]...)
175+
break
176+
}
177+
}
178+
}
179+
return q
180+
}

site/src/api/typesGenerated.ts

Lines changed: 24 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/pages/HealthPage/Content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export const Pill = forwardRef<HTMLDivElement, PillProps>((props, ref) => {
186186
});
187187

188188
type BooleanPillProps = Omit<ComponentProps<typeof Pill>, "icon" | "value"> & {
189-
value: boolean;
189+
value: boolean | null;
190190
};
191191

192192
export const BooleanPill: FC<BooleanPillProps> = ({

site/src/pages/HealthPage/DERPPage.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
HealthMessage,
66
HealthSeverity,
77
HealthcheckReport,
8+
NetcheckReport,
89
} from "api/typesGenerated";
910
import { Alert } from "components/Alert/Alert";
1011
import type { FC } from "react";
@@ -24,7 +25,7 @@ import {
2425
import { DismissWarningButton } from "./DismissWarningButton";
2526
import { healthyColor } from "./healthyColor";
2627

27-
const flags = [
28+
const flags: BooleanKeys<NetcheckReport>[] = [
2829
"UDP",
2930
"IPv6",
3031
"IPv4",
@@ -39,9 +40,15 @@ const flags = [
3940
"PCP",
4041
];
4142

43+
type BooleanKeys<T> = {
44+
[K in keyof T]: T[K] extends boolean | null ? K : never;
45+
}[keyof T];
46+
47+
4248
export const DERPPage: FC = () => {
4349
const { derp } = useOutletContext<HealthcheckReport>();
4450
const { netcheck, regions, netcheck_logs: logs } = derp;
51+
const safeNetcheck = netcheck || {} as NetcheckReport;
4552
const theme = useTheme();
4653

4754
return (
@@ -75,7 +82,7 @@ export const DERPPage: FC = () => {
7582
<SectionLabel>Flags</SectionLabel>
7683
<div css={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
7784
{flags.map((flag) => (
78-
<BooleanPill key={flag} value={netcheck[flag]}>
85+
<BooleanPill key={flag} value={safeNetcheck[flag]}>
7986
{flag}
8087
</BooleanPill>
8188
))}
@@ -94,6 +101,7 @@ export const DERPPage: FC = () => {
94101
if (a.region && b.region) {
95102
return a.region.RegionName.localeCompare(b.region.RegionName);
96103
}
104+
return 0;
97105
})
98106
.map(({ severity, region }) => {
99107
return (
@@ -111,10 +119,10 @@ export const DERPPage: FC = () => {
111119
/>
112120
}
113121
component={Link}
114-
to={`/health/derp/regions/${region.RegionID}`}
115-
key={region.RegionID}
122+
to={`/health/derp/regions/${region!.RegionID}`}
123+
key={region!.RegionID}
116124
>
117-
{region.RegionName}
125+
{region!.RegionName}
118126
</Button>
119127
);
120128
})}

site/src/pages/HealthPage/DERPRegionPage.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const meta: Meta = {
1111
...generateMeta({
1212
path: "/health/derp/regions/:regionId",
1313
element: <DERPRegionPage />,
14-
params: { regionId: firstRegionId },
14+
params: { regionId: firstRegionId?.toString() || "" },
1515
}),
1616
};
1717

0 commit comments

Comments
 (0)