Skip to content

Commit e45cff7

Browse files
refactor: extract shared types, filter internal keys, unify formatting
1 parent e402ae7 commit e45cff7

3 files changed

Lines changed: 59 additions & 54 deletions

File tree

src/components/models/SchemaDisplay.astro

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { type Dictionary } from "@stoplight/types";
2121
import { resolveInlineRef } from "@stoplight/json";
2222
import SchemaTreeView from "./SchemaTree.tsx";
2323
import SchemaVariantSelector from "./SchemaVariantSelector.tsx";
24+
import type { SchemaRowData } from "./types";
25+
export type { SchemaRowData };
2426
2527
interface Props {
2628
schema: Record<string, unknown>;
@@ -47,9 +49,7 @@ const isFlat = isFlatSchema(schema);
4749
4850
// Convert flat schema keys into rows for display
4951
// e.g. { type: "string", format: "binary" } => rows with name=type, type=string
50-
function flatSchemaToRows(
51-
schemaObj: Record<string, unknown>,
52-
): import("./SchemaDisplay.astro").SchemaRowData[] {
52+
function flatSchemaToRows(schemaObj: Record<string, unknown>): SchemaRowData[] {
5353
const keys = Object.keys(schemaObj);
5454
return keys.map((key, i) => ({
5555
id: key,
@@ -100,29 +100,6 @@ const defaultResolver: SchemaTreeRefDereferenceFn =
100100
throw new ReferenceError(`Could not resolve '${pointer}'`);
101101
};
102102
103-
// Schema row data structure
104-
export interface SchemaRowData {
105-
id: string;
106-
name: string;
107-
type: string;
108-
isArray: boolean;
109-
isObject: boolean;
110-
isOneOf: boolean;
111-
isOneOfChild: boolean; // This item is a child of a oneOf/anyOf
112-
isFirstOneOfChild: boolean; // First child (no OR divider before)
113-
isLastOneOfChild: boolean; // Last child (no OR divider after, so show border)
114-
required: boolean;
115-
defaultValue?: string;
116-
description?: string;
117-
enumValues?: string[];
118-
// Generic metadata - all other schema properties (format, min, max, minItems, maxItems, etc.)
119-
metadata?: Record<string, string | number | boolean>;
120-
depth: number;
121-
isLast: boolean;
122-
ancestorIsLast: boolean[];
123-
children?: SchemaRowData[];
124-
}
125-
126103
function collectRows(
127104
nodes: SchemaNode[] | undefined,
128105
depth: number,
@@ -219,18 +196,25 @@ function collectRows(
219196
"anyOf",
220197
"allOf",
221198
"$ref",
199+
"$id",
200+
"$schema",
201+
"$comment",
222202
"title",
223203
"additionalProperties",
224204
]);
225205
206+
// Check if a key should be skipped (includes $-prefixed and x-prefixed keys)
207+
const shouldSkipKey = (key: string) =>
208+
skipKeys.has(key) || key.startsWith("$") || key.startsWith("x-");
209+
226210
const metadata: Record<string, string | number | boolean> = {};
227211
228212
// Get metadata from fragment (format, etc.)
229213
const fragment = reg.fragment as Record<string, unknown>;
230214
if (fragment) {
231215
for (const [key, value] of Object.entries(fragment)) {
232216
if (
233-
!skipKeys.has(key) &&
217+
!shouldSkipKey(key) &&
234218
(typeof value === "string" ||
235219
typeof value === "number" ||
236220
typeof value === "boolean")
@@ -244,7 +228,7 @@ function collectRows(
244228
if (reg.validations) {
245229
for (const [key, value] of Object.entries(reg.validations)) {
246230
if (
247-
!skipKeys.has(key) &&
231+
!shouldSkipKey(key) &&
248232
key !== "enum" &&
249233
(typeof value === "string" ||
250234
typeof value === "number" ||

src/components/models/SchemaTree.tsx

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useState, useEffect, useCallback, useMemo } from "react";
2+
import type { SchemaRowData } from "./types";
23

34
/**
45
* SchemaTree - Interactive flex-based view for schema parameters
@@ -11,26 +12,11 @@ import { useState, useEffect, useCallback, useMemo } from "react";
1112
* - sessionStorage persistence for collapse state
1213
*/
1314

14-
export interface SchemaRowData {
15-
id: string;
16-
name: string;
17-
type: string;
18-
isArray: boolean;
19-
isObject: boolean;
20-
isOneOf: boolean;
21-
isOneOfChild: boolean;
22-
isFirstOneOfChild: boolean;
23-
isLastOneOfChild: boolean;
24-
required: boolean;
25-
defaultValue?: string;
26-
description?: string;
27-
enumValues?: string[];
28-
metadata?: Record<string, string | number | boolean>;
29-
depth: number;
30-
isLast: boolean;
31-
ancestorIsLast: boolean[];
32-
children?: SchemaRowData[];
33-
}
15+
export type { SchemaRowData };
16+
17+
// Type indicator symbols
18+
const ARRAY_BRACKETS = "[]";
19+
const OBJECT_BRACES = "{}";
3420

3521
interface SchemaTreeProps {
3622
rows: SchemaRowData[];
@@ -198,12 +184,12 @@ function SchemaNode({
198184
</span>
199185
{row.isArray && (
200186
<span className="font-mono text-gray-400 dark:text-gray-500">
201-
[]
187+
{ARRAY_BRACKETS}
202188
</span>
203189
)}
204190
{row.isObject && !row.isOneOf && (
205191
<span className="font-mono text-gray-400 dark:text-gray-500">
206-
{"{}"}
192+
{OBJECT_BRACES}
207193
</span>
208194
)}
209195
</div>
@@ -214,11 +200,14 @@ function SchemaNode({
214200
{row.metadata &&
215201
Object.entries(row.metadata).map(([key, value]) => (
216202
<span key={key}>
217-
{key}: {String(value)}
203+
<span className="font-medium">{key}:</span> {String(value)}
218204
</span>
219205
))}
220206
{row.enumValues && row.enumValues.length > 0 && (
221-
<span>enum: {row.enumValues.join(", ")}</span>
207+
<span>
208+
<span className="font-medium">enum:</span>{" "}
209+
{row.enumValues.join(", ")}
210+
</span>
222211
)}
223212
</div>
224213

@@ -285,10 +274,14 @@ function SchemaNode({
285274
{highlightMatch(row.name, searchTerm)}
286275
</span>
287276
{row.isArray && (
288-
<span className="text-gray-400 dark:text-gray-500">[]</span>
277+
<span className="text-gray-400 dark:text-gray-500">
278+
{ARRAY_BRACKETS}
279+
</span>
289280
)}
290281
{row.isObject && !row.isOneOf && (
291-
<span className="text-gray-400 dark:text-gray-500">{"{}"}</span>
282+
<span className="text-gray-400 dark:text-gray-500">
283+
{OBJECT_BRACES}
284+
</span>
292285
)}
293286
</div>
294287

src/components/models/types.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Shared types for schema display components
3+
*/
4+
5+
/**
6+
* Schema row data structure for rendering parameter trees
7+
*/
8+
export interface SchemaRowData {
9+
id: string;
10+
name: string;
11+
type: string;
12+
isArray: boolean;
13+
isObject: boolean;
14+
isOneOf: boolean;
15+
isOneOfChild: boolean; // This item is a child of a oneOf/anyOf
16+
isFirstOneOfChild: boolean; // First child (no OR divider before)
17+
isLastOneOfChild: boolean; // Last child (no OR divider after, so show border)
18+
required: boolean;
19+
defaultValue?: string;
20+
description?: string;
21+
enumValues?: string[];
22+
// Generic metadata - all other schema properties (format, min, max, minItems, maxItems, etc.)
23+
metadata?: Record<string, string | number | boolean>;
24+
depth: number;
25+
isLast: boolean;
26+
ancestorIsLast: boolean[];
27+
children?: SchemaRowData[];
28+
}

0 commit comments

Comments
 (0)