diff --git a/packages/web/package.json b/packages/web/package.json
index 12ad3f94..ee023c4e 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -35,6 +35,7 @@
"@docusaurus/module-type-aliases": "^3.0.1",
"@docusaurus/tsconfig": "^3.0.1",
"@docusaurus/types": "^3.0.1",
+ "json-schema-typed": "^8.0.1",
"typescript": "~5.2.2"
},
"browserslist": {
diff --git a/packages/web/src/contexts/SchemaContext.tsx b/packages/web/src/contexts/SchemaContext.tsx
index abad8487..9e0996f7 100644
--- a/packages/web/src/contexts/SchemaContext.tsx
+++ b/packages/web/src/contexts/SchemaContext.tsx
@@ -1,5 +1,6 @@
import { useContext, createContext } from "react";
-import type { SchemaInfo, SchemaIndex } from "@site/src/schemas";
+import type { SchemaInfo } from "@ethdebug/format";
+import type { SchemaIndex } from "@site/src/schemas";
export interface SchemaContextValue {
rootSchemaInfo?: SchemaInfo;
diff --git a/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/DiscriminatorSchema.tsx b/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/DiscriminatorSchema.tsx
new file mode 100644
index 00000000..cc8b1277
--- /dev/null
+++ b/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/DiscriminatorSchema.tsx
@@ -0,0 +1,154 @@
+import React from 'react';
+import type { JSONSchema } from "json-schema-typed/draft-2020-12"
+import Tabs from "@theme/Tabs";
+import TabItem from "@theme/TabItem";
+
+import {
+ SchemaHierarchyContextProvider,
+ useSchemaHierarchyContext,
+} from "@theme-original/JSONSchemaViewer/contexts"
+
+import { CreateNodes } from "@theme-original/JSONSchemaViewer/components"
+
+export interface Discriminator {
+ propertyName: string;
+ schemasByConst: {
+ [value: string]: {
+ schema: JSONSchema;
+ index: number;
+ }
+ }
+}
+
+export interface DiscriminatorSchemaProps extends Discriminator {
+}
+
+export default function DiscriminatorSchema({
+ propertyName,
+ schemasByConst
+}: DiscriminatorSchemaProps): JSX.Element {
+ const { jsonPointer: currentJsonPointer, level: currentLevel } =
+ useSchemaHierarchyContext()
+
+ return (
+
+
+ polymorphic discriminator
+ The value of the {propertyName} field
+ determines which sub-schema applies:
+
+ {
+ Object.entries(schemasByConst)
+ .map(([value, { schema, index }]) => (
+
+
+
+
+
+ ))
+ }
+
+ );
+}
+
+export function detectDiscriminator(schema: {
+ allOf: JSONSchema[]
+}): Discriminator | undefined {
+ const { allOf } = schema;
+
+ const allIfThen = allOf.every(
+ (clause: JSONSchema): clause is { "if": JSONSchema; then: JSONSchema } => {
+ if (typeof clause === "boolean") {
+ return false;
+ }
+
+ const { title, description, "if": if_, then, ...others } = clause;
+
+ return !!if_ && !!then && Object.keys(others).length === 0;
+ }
+ )
+
+ if (!allIfThen) {
+ return;
+ }
+
+ const allIfsHaveSinglePropertyWithConst = allOf.every(
+ (ifThen: { "if": JSONSchema; then: JSONSchema }): ifThen is {
+ "if": {
+ properties: {
+ [propertyName: string]: {
+ "const": string
+ }
+ }
+ };
+ then: JSONSchema;
+ } => {
+ const { "if": if_ } = ifThen;
+
+ if (
+ typeof if_ === "boolean" ||
+ !("properties" in if_) ||
+ !if_.properties
+ ) {
+ return false;
+ }
+
+ const ifProperties = if_.properties;
+
+ if (Object.keys(ifProperties).length !== 1) {
+ return false;
+ }
+
+ const propertyName = Object.keys(ifProperties)[0];
+ const propertySchema = ifProperties[propertyName];
+
+ return (
+ typeof propertySchema === "object" &&
+ "const" in propertySchema &&
+ typeof propertySchema.const === "string" &&
+ !!propertySchema.const
+ ) ;
+ }
+ );
+
+ if (!allIfsHaveSinglePropertyWithConst) {
+ return;
+ }
+
+ const propertyName = Object.keys(allOf[0]["if"].properties)[0];
+
+ const schemasByConst = allOf
+ .map(({ "if": if_, then }, index) => {
+ const value = if_.properties[propertyName]["const"];
+
+ return {
+ [value]: {
+ schema: then,
+ index
+ }
+ };
+ })
+ .reduce((a, b) => ({ ...a, ...b }), {});
+
+
+ const isUniquelyDiscriminating =
+ Object.keys(schemasByConst).length === allOf.length;
+
+ if (!isUniquelyDiscriminating) {
+ return;
+ }
+
+ return {
+ propertyName,
+ schemasByConst
+ };
+}
diff --git a/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/allOfSchema.tsx b/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/allOfSchema.tsx
index 625d81f7..fdba389f 100644
--- a/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/allOfSchema.tsx
+++ b/packages/web/src/theme/JSONSchemaViewer/JSONSchemaElements/schemaComposition/allOfSchema.tsx
@@ -1,147 +1,25 @@
import React from 'react';
+import type { JSONSchema } from "json-schema-typed/draft-2020-12"
import AllOfSchema from '@theme-original/JSONSchemaViewer/JSONSchemaElements/schemaComposition/allOfSchema';
-import Tabs from "@theme/Tabs";
-import TabItem from "@theme/TabItem";
-import { CreateNodes } from "@theme-original/JSONSchemaViewer/components"
-import {
- SchemaHierarchyContextProvider,
- useSchemaHierarchyContext,
-} from "@theme-original/JSONSchemaViewer/contexts"
-import { Collapsible } from "@theme-original/JSONSchemaViewer/components";
+import DiscriminatorSchema, {
+ detectDiscriminator
+} from "./DiscriminatorSchema";
-export default function allOfSchemaWrapper(props) {
+export default function allOfSchemaWrapper(props: {
+ schema: Exclude & { allOf: JSONSchema[]; }
+}) {
const { schema } = props;
- const { jsonPointer: currentJsonPointer, level: currentLevel } =
- useSchemaHierarchyContext()
const discriminator = detectDiscriminator(schema);
- if (!discriminator) {
- return (
- <>
-
- >
- );
+ if (discriminator) {
+ return
}
- const { propertyName, schemasByConst } = discriminator;
-
return (
-
-
- polymorphic discriminator
- The value of the {propertyName} field
- determines which sub-schema applies:
-
- {
- Object.entries(schemasByConst)
- .map(([value, { schema, index }]) => (
-
-
-
-
-
- ))
- }
-
+ <>
+
+ >
);
}
-function detectDiscriminator(schema: {
- allOf: any[]
-}): {
- propertyName: string;
- schemasByConst: {
- [value: string]: {
- schema: object;
- index: number;
- }
- }
-} | undefined {
- const { allOf } = schema;
-
- const allIfThen = allOf.every(
- (clause: any): clause is { "if": any; then: any } => {
- const { title, description, "if": if_, then, ...others } = clause;
-
- return if_ && then && Object.keys(others).length === 0;
- }
- )
-
- if (!allIfThen) {
- return;
- }
-
- const allIfsHaveSinglePropertyWithConst = allOf.every(
- (ifThen: { "if": any; then: any }): ifThen is {
- "if": {
- properties: {
- [propertyName: string]: {
- "const": string
- }
- }
- };
- then: any;
- } => {
- const { "if": if_ } = ifThen;
-
- if (!("properties" in if_)) {
- return false;
- }
-
- const ifProperties = if_.properties;
-
- if (Object.keys(ifProperties).length !== 1) {
- return false;
- }
-
- const propertyName = Object.keys(ifProperties)[0];
-
- const { "const": const_ } = ifProperties[propertyName];
-
- return typeof const_ === "string" && !!const_;
- }
- );
-
- if (!allIfsHaveSinglePropertyWithConst) {
- return;
- }
-
- const propertyName = Object.keys(allOf[0]["if"].properties)[0];
-
- const schemasByConst = allOf
- .map(({ "if": if_, then }, index) => {
- const value = if_.properties[propertyName]["const"];
-
- return {
- [value]: {
- schema: then,
- index
- }
- };
- })
- .reduce((a, b) => ({ ...a, ...b }), {});
-
-
- const isUniquelyDiscriminating =
- Object.keys(schemasByConst).length === allOf.length;
-
- if (!isUniquelyDiscriminating) {
- return;
- }
-
- return {
- propertyName,
- schemasByConst
- };
-}
-
diff --git a/packages/web/src/theme/JSONSchemaViewer/components/CreateNodes.tsx b/packages/web/src/theme/JSONSchemaViewer/components/CreateNodes.tsx
index 37e19777..9bb9cc16 100644
--- a/packages/web/src/theme/JSONSchemaViewer/components/CreateNodes.tsx
+++ b/packages/web/src/theme/JSONSchemaViewer/components/CreateNodes.tsx
@@ -1,11 +1,16 @@
import React from 'react';
import CreateTypes from "@theme-original/JSONSchemaViewer/components/CreateTypes";
import CreateNodes from '@theme-original/JSONSchemaViewer/components/CreateNodes';
-import { useJSVOptionsContext, useSchemaHierarchyContext } from "@theme-original/JSONSchemaViewer/contexts";
+import type { JSONSchema } from "json-schema-typed/draft-2020-12";
+import { useSchemaHierarchyContext } from "@theme-original/JSONSchemaViewer/contexts";
import { useSchemaContext, internalIdKey } from "@site/src/contexts/SchemaContext";
import Link from "@docusaurus/Link";
-export default function CreateNodesWrapper(props) {
+export default function CreateNodesWrapper(props: {
+ schema: Exclude & {
+ [internalIdKey]: string
+ }
+}) {
const { level } = useSchemaHierarchyContext();
const { schemaIndex } = useSchemaContext();
@@ -25,7 +30,7 @@ export default function CreateNodesWrapper(props) {
? id.slice("schema:".length)
: id
} schema`
- } = schemaIndex[id];
+ } = schemaIndex[id as keyof typeof schemaIndex];
return (
<>
@@ -36,7 +41,7 @@ export default function CreateNodesWrapper(props) {
return (
<>
-
+
>
);
}
diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json
index 6f9aaca5..1710cb7d 100644
--- a/packages/web/tsconfig.json
+++ b/packages/web/tsconfig.json
@@ -3,6 +3,7 @@
"extends": "@docusaurus/tsconfig",
"compilerOptions": {
"baseUrl": ".",
+ "strict": true,
"resolveJsonModule": true,
// Extending "@tsconfig/docusaurus/tsconfig.json".types with "docusaurus-json-schema-plugin"
"types": ["node", "@docusaurus/module-type-aliases", "@docusaurus/theme-classic", "docusaurus-json-schema-plugin"]