Skip to content

Inconsistent behavior with prepending of #/components/schema for direct Refs #226

@recanman

Description

@recanman

This problem seems to appear when manually specifying $ids for Elysia models.

Problem is in the convoluted conditionals right here:

{
	...schema,
	$ref: `#/components/schemas/${schema.$ref}`
}

The following code shows the inconsistent behavior:

import swagger from "@elysiajs/swagger";
import type { TObject } from "@sinclair/typebox";
import Elysia, { t } from "elysia";

const $id = (name: string) => `#/components/schemas/${name}`;
const exampleObj = t.Object(
	{
		name: t.String(),
	},
	{
		$id: $id("example"),
	}
);

// For convenience
export const ObjRef = <T extends TObject>(obj: T) => {
	if (obj.$id) {
		// @ts-expect-error this is correct
		return t.Ref<T>(obj.$id) as T;
	}
	throw new Error("obj must have $id property");
};
new Elysia()
	.model({
		example: exampleObj,
	})
	.use(swagger())
	.get("/", () => ({ test: { name: "hello" } }), {
		response: ObjRef(exampleObj),
	})
	.get("/test", ({ query }) => query.test.name, {
		query: t.Object({ test: ObjRef(exampleObj) }),
	})
	.listen(4242);

For the / endpoint, the condition '$ref' in schema && Kind in schema && schema[Kind] === 'Ref' evaluates to true, and thus the $ref added to the resulting OpenAPI schema is #/components/schemas/#components/schemas/example. For the /test endpoint, this condition does not evaluate to true; the resulting $ref checks before prepending #/components/schemas:

if (!$ref.startsWith("#/components/schemas/"))
    return t.Ref(
        `#/components/schemas/${$ref}`,
        options
   );
return t.Ref($ref, options);

Using the same startsWith check above would fix this. Will submit a PR shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions