docs-util: fixes to base OAS + circular-patch redocly plugin (#7382)
* docs-util: remove MultipleErrors schema from base OAS * fixes to circular patch plugin * general fixes * change nested schemas to references
This commit is contained in:
@@ -3,6 +3,7 @@ import { SchemaObject } from "../../../types/openapi"
|
||||
import path from "path"
|
||||
import { existsSync, promises as fs } from "fs"
|
||||
import { parseDocument } from "yaml"
|
||||
import dereference from "../../../utils/dereference"
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const { searchParams } = new URL(request.url)
|
||||
@@ -37,14 +38,14 @@ export async function GET(request: Request) {
|
||||
.replace("#/components/schemas/", "")
|
||||
.replaceAll("./components/schemas/", "")
|
||||
|
||||
const schemaPath = path.join(
|
||||
const baseSchemasPath = path.join(
|
||||
process.cwd(),
|
||||
"specs",
|
||||
area,
|
||||
"components",
|
||||
"schemas",
|
||||
name
|
||||
"schemas"
|
||||
)
|
||||
const schemaPath = path.join(baseSchemasPath, name)
|
||||
|
||||
if (!existsSync(schemaPath)) {
|
||||
return NextResponse.json(
|
||||
@@ -61,9 +62,17 @@ export async function GET(request: Request) {
|
||||
const schemaContent = await fs.readFile(schemaPath, "utf-8")
|
||||
const schema = parseDocument(schemaContent).toJS() as SchemaObject
|
||||
|
||||
// resolve references in schema
|
||||
const dereferencedDocument = await dereference({
|
||||
basePath: baseSchemasPath,
|
||||
schemas: [schema],
|
||||
})
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
schema,
|
||||
schema: dereferencedDocument.components?.schemas
|
||||
? Object.values(dereferencedDocument.components?.schemas)[0]
|
||||
: schema,
|
||||
},
|
||||
{
|
||||
status: 200,
|
||||
|
||||
@@ -114,7 +114,7 @@ const TagOperationParametersObject = ({
|
||||
)
|
||||
}
|
||||
|
||||
if (!schema.properties) {
|
||||
if (!schema.properties || !Object.values(schema.properties).length) {
|
||||
return getPropertyDescriptionElm()
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import SectionContainer from "../../../Section/Container"
|
||||
import useSchemaExample from "../../../../hooks/use-schema-example"
|
||||
import { InView } from "react-intersection-observer"
|
||||
import checkElementInViewport from "../../../../utils/check-element-in-viewport"
|
||||
import { singular } from "pluralize"
|
||||
|
||||
export type TagSectionSchemaProps = {
|
||||
schema: SchemaObject
|
||||
@@ -24,15 +25,10 @@ export type TagSectionSchemaProps = {
|
||||
const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
|
||||
const { addItems, setActivePath, activePath } = useSidebar()
|
||||
const tagSlugName = useMemo(() => getSectionId([tagName]), [tagName])
|
||||
const formattedName = useMemo(() => {
|
||||
if (!schema["x-schemaName"]) {
|
||||
return tagName.replaceAll(" ", "")
|
||||
}
|
||||
|
||||
return schema["x-schemaName"]
|
||||
.replaceAll(/^(Admin|Store)/g, "")
|
||||
.replaceAll(/^Create/g, "")
|
||||
}, [schema, tagName])
|
||||
const formattedName = useMemo(
|
||||
() => singular(tagName).replaceAll(" ", ""),
|
||||
[tagName]
|
||||
)
|
||||
const schemaSlug = useMemo(
|
||||
() => getSectionId([tagName, formattedName, "schema"]),
|
||||
[tagName, formattedName]
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"next-mdx-remote": "^4.4.1",
|
||||
"openapi-sampler": "^1.3.1",
|
||||
"openapi-types": "^12.1.3",
|
||||
"pluralize": "^8.0.0",
|
||||
"postcss": "8.4.27",
|
||||
"prism-react-renderer": "2.3.1",
|
||||
"react": "^18.2.0",
|
||||
@@ -54,6 +55,7 @@
|
||||
"devDependencies": {
|
||||
"@next/bundle-analyzer": "^14.2.3",
|
||||
"@types/jsdom": "^21.1.1",
|
||||
"@types/pluralize": "^0.0.33",
|
||||
"types": "*"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -118,3 +118,7 @@ export type ExpandedDocument = Document & {
|
||||
export type TagObject = OpenAPIV3.TagObject & {
|
||||
"x-associatedSchema"?: OpenAPIV3.ReferenceObject
|
||||
}
|
||||
|
||||
export type ParsedPathItemObject = OpenAPIV3.PathItemObject<Operation> & {
|
||||
operationPath?: string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Document, ParsedPathItemObject, SchemaObject } from "@/types/openapi"
|
||||
import OpenAPIParser from "@readme/openapi-parser"
|
||||
|
||||
type Options = {
|
||||
basePath: string
|
||||
paths?: ParsedPathItemObject[]
|
||||
schemas?: SchemaObject[]
|
||||
}
|
||||
|
||||
export default async function dereference({
|
||||
basePath,
|
||||
paths,
|
||||
schemas,
|
||||
}: Options): Promise<Document> {
|
||||
// dereference the references in the paths
|
||||
let document: Document = {
|
||||
paths: {},
|
||||
// These attributes are only for validation purposes
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Medusa API",
|
||||
version: "1.0.0",
|
||||
},
|
||||
components: {
|
||||
schemas: {},
|
||||
},
|
||||
}
|
||||
|
||||
if (paths) {
|
||||
paths.forEach((path) => {
|
||||
const documentPath = path.operationPath || ""
|
||||
delete path.operationPath
|
||||
document.paths[documentPath] = path
|
||||
})
|
||||
}
|
||||
|
||||
if (schemas) {
|
||||
schemas.forEach((schema) => {
|
||||
if (!schema["x-schemaName"]) {
|
||||
return
|
||||
}
|
||||
document.components!.schemas![schema["x-schemaName"]] = schema
|
||||
})
|
||||
}
|
||||
|
||||
// resolve references in paths
|
||||
document = (await OpenAPIParser.dereference(`${basePath}/`, document, {
|
||||
parse: {
|
||||
text: {
|
||||
// This ensures that all files are parsed as expected
|
||||
// resolving the error with incorrect new lines for
|
||||
// example files having `undefined` extension.
|
||||
canParse: /.*/,
|
||||
},
|
||||
},
|
||||
})) as unknown as Document
|
||||
|
||||
return document
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
import path from "path"
|
||||
import { promises as fs } from "fs"
|
||||
import type { OpenAPIV3 } from "openapi-types"
|
||||
import type { Operation, Document } from "@/types/openapi"
|
||||
import type { Operation, Document, ParsedPathItemObject } from "@/types/openapi"
|
||||
import readSpecDocument from "./read-spec-document"
|
||||
import getSectionId from "./get-section-id"
|
||||
import OpenAPIParser from "@readme/openapi-parser"
|
||||
|
||||
type ParsedPathItemObject = OpenAPIV3.PathItemObject<Operation> & {
|
||||
operationPath?: string
|
||||
}
|
||||
import dereference from "./dereference"
|
||||
|
||||
export default async function getPathsOfTag(
|
||||
tagName: string,
|
||||
@@ -46,34 +42,8 @@ export default async function getPathsOfTag(
|
||||
})
|
||||
)
|
||||
|
||||
// dereference the references in the paths
|
||||
let paths: Document = {
|
||||
paths: {},
|
||||
// These attributes are only for validation purposes
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Medusa API",
|
||||
version: "1.0.0",
|
||||
},
|
||||
}
|
||||
|
||||
documents.forEach((document) => {
|
||||
const documentPath = document.operationPath || ""
|
||||
delete document.operationPath
|
||||
paths.paths[documentPath] = document
|
||||
return dereference({
|
||||
basePath,
|
||||
paths: documents,
|
||||
})
|
||||
|
||||
// resolve references in paths
|
||||
paths = (await OpenAPIParser.dereference(`${basePath}/`, paths, {
|
||||
parse: {
|
||||
text: {
|
||||
// This ensures that all files are parsed as expected
|
||||
// resolving the error with incorrect new lines for
|
||||
// example files having `undefined` extension.
|
||||
canParse: /.*/,
|
||||
},
|
||||
},
|
||||
})) as unknown as Document
|
||||
|
||||
return paths
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user