From e523e09d68f4d25eab5b2429b7c067aa3f9c013d Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 7 Feb 2025 20:03:46 -0500 Subject: [PATCH 1/2] Add { schema: string; } polymorphism to describeSchema ... in addition to the existing: - { schema: { id: string } } - { schema: { yaml: string } - { schema: JSONSchema } --- packages/format/src/describe.ts | 44 ++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/format/src/describe.ts b/packages/format/src/describe.ts index 94e743b2c..72893cf67 100644 --- a/packages/format/src/describe.ts +++ b/packages/format/src/describe.ts @@ -34,11 +34,30 @@ export function describeSchema({ throw new Error("`pointer` option must start with '#'"); } - return referencesId(schema) - ? describeSchemaById({ schema, ...(pointer ? { pointer } : {}) }) - : referencesYaml(schema) - ? describeSchemaByYaml({ schema, ...(pointer ? { pointer } : {}) }) - : describeSchemaByObject({ schema, ...(pointer ? { pointer } : {}) }); + const pointerOptions = pointer + ? { pointer } + : {}; + + if (referencesId(schema)) { + return describeSchemaById({ + schema: typeof schema === "object" + ? schema + : { id: schema }, + ...pointerOptions + }); + } + + if (referencesYaml(schema)) { + return describeSchemaByYaml({ + schema, + ...pointerOptions + }); + } + + return describeSchemaByObject({ + schema, + ...pointerOptions + }); } function describeSchemaById({ @@ -180,12 +199,15 @@ type NoExtraProperties = export type SchemaPointer = `#${string}`; export type SchemaReference = + | SchemaId | SchemaById | SchemaByYaml | object /* JSONSchema object itself */; +export type SchemaId = string; + export type SchemaById = NoExtraProperties<{ - id: string; + id: SchemaId; }>; export type SchemaByYaml = NoExtraProperties<{ @@ -194,12 +216,16 @@ export type SchemaByYaml = NoExtraProperties<{ export function referencesId( schema: SchemaReference -): schema is SchemaById { - return Object.keys(schema).length === 1 && "id" in schema; +): schema is SchemaId | SchemaById { + return ( + typeof schema === "string" || + (Object.keys(schema).length === 1 && "id" in schema) + ); } export function referencesYaml( schema: SchemaReference ): schema is SchemaByYaml { - return Object.keys(schema).length === 1 && "yaml" in schema; + return typeof schema === "object" && + Object.keys(schema).length === 1 && "yaml" in schema; } From f87f6782eaa37313f5a307e923cef996f00096dd Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 7 Feb 2025 20:04:59 -0500 Subject: [PATCH 2/2] Switch some things to new describeSchema polymorphism --- packages/format/src/types/data/index.test.ts | 12 +-- .../format/src/types/materials/index.test.ts | 22 ++---- .../format/src/types/pointer/pointer.test.ts | 52 ++++--------- .../format/src/types/program/context.test.ts | 18 ++--- .../src/types/program/instruction.test.ts | 6 +- .../format/src/types/program/program.test.ts | 6 +- packages/format/src/types/type/base.test.ts | 14 +--- packages/format/src/types/type/index.test.ts | 74 +++++-------------- packages/web/spec/type/overview.mdx | 2 +- 9 files changed, 55 insertions(+), 151 deletions(-) diff --git a/packages/format/src/types/data/index.test.ts b/packages/format/src/types/data/index.test.ts index f849476e8..bf1e3d1a1 100644 --- a/packages/format/src/types/data/index.test.ts +++ b/packages/format/src/types/data/index.test.ts @@ -7,21 +7,15 @@ import { Data } from "./index.js"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/data/value" - }, + schema: "schema:ethdebug/format/data/value", guard: Data.isValue }, { - schema: { - id: "schema:ethdebug/format/data/unsigned" - }, + schema: "schema:ethdebug/format/data/unsigned", guard: Data.isUnsigned }, { - schema: { - id: "schema:ethdebug/format/data/hex" - }, + schema: "schema:ethdebug/format/data/hex", guard: Data.isHex }, ] as const; diff --git a/packages/format/src/types/materials/index.test.ts b/packages/format/src/types/materials/index.test.ts index 42cd19fde..caa777264 100644 --- a/packages/format/src/types/materials/index.test.ts +++ b/packages/format/src/types/materials/index.test.ts @@ -7,40 +7,30 @@ import { Materials } from "./index"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/materials/id" - }, + schema: "schema:ethdebug/format/materials/id", guard: Materials.isId }, { - schema: { - id: "schema:ethdebug/format/materials/reference" - }, + schema: "schema:ethdebug/format/materials/reference", guard: Materials.isReference }, { - schema: { - id: "schema:ethdebug/format/materials/compilation" - }, + schema: "schema:ethdebug/format/materials/compilation", guard: Materials.isCompilation }, { - schema: { - id: "schema:ethdebug/format/materials/source" - }, + schema: "schema:ethdebug/format/materials/source", guard: Materials.isSource }, { - schema: { - id: "schema:ethdebug/format/materials/source-range" - }, + schema: "schema:ethdebug/format/materials/source-range", guard: Materials.isSourceRange }, ] as const; for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema } = describeSchemaOptions; - describe(schema.id.slice("schema:".length), () => { + describe(schema.slice("schema:".length), () => { it("matches its examples", () => { const { schema: { diff --git a/packages/format/src/types/pointer/pointer.test.ts b/packages/format/src/types/pointer/pointer.test.ts index 6f5e435fa..703602c95 100644 --- a/packages/format/src/types/pointer/pointer.test.ts +++ b/packages/format/src/types/pointer/pointer.test.ts @@ -5,9 +5,7 @@ import { describeSchema } from "../../describe"; import { Pointer, isPointer } from "./pointer"; describe("type guards", () => { - const expressionSchema = { - id: "schema:ethdebug/format/pointer/expression" - }; + const expressionSchema = "schema:ethdebug/format/pointer/expression"; const schemaGuards = [ { @@ -60,75 +58,51 @@ describe("type guards", () => { guard: Pointer.Expression.isResize }, { - schema: { - id: "schema:ethdebug/format/pointer/region" - }, + schema: "schema:ethdebug/format/pointer/region", guard: Pointer.isRegion }, { - schema: { - id: "schema:ethdebug/format/pointer/region/stack" - }, + schema: "schema:ethdebug/format/pointer/region/stack", guard: Pointer.Region.isStack }, { - schema: { - id: "schema:ethdebug/format/pointer/region/memory" - }, + schema: "schema:ethdebug/format/pointer/region/memory", guard: Pointer.Region.isMemory }, { - schema: { - id: "schema:ethdebug/format/pointer/region/storage" - }, + schema: "schema:ethdebug/format/pointer/region/storage", guard: Pointer.Region.isStorage }, { - schema: { - id: "schema:ethdebug/format/pointer/region/calldata" - }, + schema: "schema:ethdebug/format/pointer/region/calldata", guard: Pointer.Region.isCalldata }, { - schema: { - id: "schema:ethdebug/format/pointer/region/returndata" - }, + schema: "schema:ethdebug/format/pointer/region/returndata", guard: Pointer.Region.isReturndata }, { - schema: { - id: "schema:ethdebug/format/pointer/region/transient" - }, + schema: "schema:ethdebug/format/pointer/region/transient", guard: Pointer.Region.isTransient }, { - schema: { - id: "schema:ethdebug/format/pointer/region/code" - }, + schema: "schema:ethdebug/format/pointer/region/code", guard: Pointer.Region.isCode }, { - schema: { - id: "schema:ethdebug/format/pointer/collection/group" - }, + schema: "schema:ethdebug/format/pointer/collection/group", guard: Pointer.Collection.isGroup }, { - schema: { - id: "schema:ethdebug/format/pointer/collection/list" - }, + schema: "schema:ethdebug/format/pointer/collection/list", guard: Pointer.Collection.isList }, { - schema: { - id: "schema:ethdebug/format/pointer" - }, + schema: "schema:ethdebug/format/pointer", guard: isPointer }, { - schema: { - id: "schema:ethdebug/format/pointer/template" - }, + schema: "schema:ethdebug/format/pointer/template", guard: Pointer.isTemplate }, ] as const; diff --git a/packages/format/src/types/program/context.test.ts b/packages/format/src/types/program/context.test.ts index 9b4a1f39f..1606cdfbc 100644 --- a/packages/format/src/types/program/context.test.ts +++ b/packages/format/src/types/program/context.test.ts @@ -7,34 +7,26 @@ import { Context, isContext } from "./context"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/program/context" - }, + schema: "schema:ethdebug/format/program/context", guard: isContext }, { - schema: { - id: "schema:ethdebug/format/program/context/code" - }, + schema: "schema:ethdebug/format/program/context/code", guard: Context.isCode }, { - schema: { - id: "schema:ethdebug/format/program/context/variables" - }, + schema: "schema:ethdebug/format/program/context/variables", guard: Context.isVariables }, { - schema: { - id: "schema:ethdebug/format/program/context/remark" - }, + schema: "schema:ethdebug/format/program/context/remark", guard: Context.isRemark }, ] as const; for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema } = describeSchemaOptions; - describe(schema.id.slice("schema:".length), () => { + describe(schema.slice("schema:".length), () => { it("matches its examples", () => { const { schema: { diff --git a/packages/format/src/types/program/instruction.test.ts b/packages/format/src/types/program/instruction.test.ts index 1be5f3480..a522da859 100644 --- a/packages/format/src/types/program/instruction.test.ts +++ b/packages/format/src/types/program/instruction.test.ts @@ -7,16 +7,14 @@ import { Instruction, isInstruction } from "./instruction"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/program/instruction" - }, + schema: "schema:ethdebug/format/program/instruction", guard: isInstruction }, ] as const; for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema } = describeSchemaOptions; - describe(schema.id.slice("schema:".length), () => { + describe(schema.slice("schema:".length), () => { it("matches its examples", () => { const { schema: { diff --git a/packages/format/src/types/program/program.test.ts b/packages/format/src/types/program/program.test.ts index dcd46e318..a3065848c 100644 --- a/packages/format/src/types/program/program.test.ts +++ b/packages/format/src/types/program/program.test.ts @@ -7,16 +7,14 @@ import { Program, isProgram } from "./program"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/program" - }, + schema: "schema:ethdebug/format/program", guard: isProgram }, ] as const; for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema } = describeSchemaOptions; - describe(schema.id.slice("schema:".length), () => { + describe(schema.slice("schema:".length), () => { it("matches its examples", () => { const { schema: { diff --git a/packages/format/src/types/type/base.test.ts b/packages/format/src/types/type/base.test.ts index 4da133579..ed42bda0d 100644 --- a/packages/format/src/types/type/base.test.ts +++ b/packages/format/src/types/type/base.test.ts @@ -7,23 +7,17 @@ import * as Base from "./base"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/type/base" - }, + schema: "schema:ethdebug/format/type/base", pointer: "#/$defs/ElementaryType", guard: Base.isElementary }, { - schema: { - id: "schema:ethdebug/format/type/base" - }, + schema: "schema:ethdebug/format/type/base", pointer: "#/$defs/ComplexType", guard: Base.isComplex }, { - schema: { - id: "schema:ethdebug/format/type/base" - }, + schema: "schema:ethdebug/format/type/base", pointer: "#/$defs/TypeWrapper", guard: Base.isWrapper }, @@ -32,7 +26,7 @@ describe("type guards", () => { for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema, pointer } = describeSchemaOptions; describe( - `${schema.id.slice("schema:".length)}${pointer}`, + `${schema.slice("schema:".length)}${pointer}`, () => { it("matches its examples", () => { const { diff --git a/packages/format/src/types/type/index.test.ts b/packages/format/src/types/type/index.test.ts index 73c7e8a58..f7875304a 100644 --- a/packages/format/src/types/type/index.test.ts +++ b/packages/format/src/types/type/index.test.ts @@ -7,124 +7,88 @@ import { Type, isType } from "./index"; describe("type guards", () => { const schemaGuards = [ { - schema: { - id: "schema:ethdebug/format/type" - }, + schema: "schema:ethdebug/format/type", guard: isType }, // elementary types { - schema: { - id: "schema:ethdebug/format/type/elementary" - }, + schema: "schema:ethdebug/format/type/elementary", guard: Type.isElementary }, { - schema: { - id: "schema:ethdebug/format/type/elementary/uint" - }, + schema: "schema:ethdebug/format/type/elementary/uint", guard: Type.Elementary.isUint }, { - schema: { - id: "schema:ethdebug/format/type/elementary/int" - }, + schema: "schema:ethdebug/format/type/elementary/int", guard: Type.Elementary.isInt }, { - schema: { - id: "schema:ethdebug/format/type/elementary/ufixed" - }, + schema: "schema:ethdebug/format/type/elementary/ufixed", guard: Type.Elementary.isUfixed }, { - schema: { - id: "schema:ethdebug/format/type/elementary/fixed" - }, + schema: "schema:ethdebug/format/type/elementary/fixed", guard: Type.Elementary.isFixed }, { - schema: { - id: "schema:ethdebug/format/type/elementary/bool" - }, + schema: "schema:ethdebug/format/type/elementary/bool", guard: Type.Elementary.isBool }, { - schema: { - id: "schema:ethdebug/format/type/elementary/bytes" - }, + schema: "schema:ethdebug/format/type/elementary/bytes", guard: Type.Elementary.isBytes }, { - schema: { - id: "schema:ethdebug/format/type/elementary/string" - }, + schema: "schema:ethdebug/format/type/elementary/string", guard: Type.Elementary.isString }, { - schema: { - id: "schema:ethdebug/format/type/elementary/address" - }, + schema: "schema:ethdebug/format/type/elementary/address", guard: Type.Elementary.isAddress }, { - schema: { - id: "schema:ethdebug/format/type/elementary/contract" - }, + schema: "schema:ethdebug/format/type/elementary/contract", guard: Type.Elementary.isContract }, { - schema: { - id: "schema:ethdebug/format/type/elementary/enum" - }, + schema: "schema:ethdebug/format/type/elementary/enum", guard: Type.Elementary.isEnum }, // complex types { - schema: { - id: "schema:ethdebug/format/type/complex" - }, + schema: "schema:ethdebug/format/type/complex", guard: Type.isComplex }, { - schema: { - id: "schema:ethdebug/format/type/complex/alias" - }, + schema: "schema:ethdebug/format/type/complex/alias", guard: Type.Complex.isAlias }, { - schema: { - id: "schema:ethdebug/format/type/complex/tuple" - }, + schema: "schema:ethdebug/format/type/complex/tuple", guard: Type.Complex.isTuple }, { - schema: { - id: "schema:ethdebug/format/type/complex/array" - }, + schema: "schema:ethdebug/format/type/complex/array", guard: Type.Complex.isArray }, { - schema: { - id: "schema:ethdebug/format/type/complex/mapping" - }, + schema: "schema:ethdebug/format/type/complex/mapping", guard: Type.Complex.isMapping }, { - schema: { - id: "schema:ethdebug/format/type/complex/struct" - }, + schema: "schema:ethdebug/format/type/complex/struct", guard: Type.Complex.isStruct }, ] as const; for (const { guard, ...describeSchemaOptions } of schemaGuards) { const { schema } = describeSchemaOptions; - describe(schema.id.slice("schema:".length), () => { + describe(schema.slice("schema:".length), () => { it("matches its examples", () => { const { schema: { diff --git a/packages/web/spec/type/overview.mdx b/packages/web/spec/type/overview.mdx index d5a769031..ccaf39573 100644 --- a/packages/web/spec/type/overview.mdx +++ b/packages/web/spec/type/overview.mdx @@ -88,7 +88,7 @@ Here are some example **ethdebug/format/type** type representations. "ethdebug/format/type/complex/mapping", "ethdebug/format/type/complex/struct" ].map((id, index) => { - const { schema } = describeSchema({ schema: { id: `schema:${id}` } }); + const { schema } = describeSchema({ schema: `schema:${id}` }); return