Hyperlinkv0.8.0-beta.28

JsonSchema

JsonSchema.toMultiDocumentOpenApi3_1functioneffect/JsonSchema.ts:670
(
  multiDocument: MultiDocument<"draft-2020-12">
): MultiDocument<"openapi-3.1">

Converts a MultiDocument<"draft-2020-12"> to a MultiDocument<"openapi-3.1">.

When to use

Use when you need to emit an OpenAPI 3.1 multi-document from canonical JSON Schema documents.

Details

This rewrites #/$defs/... refs to #/components/schemas/..., sanitizes definition keys to match the OpenAPI component key pattern (^[a-zA-Z0-9.\-_]+$) by replacing invalid characters with _, updates all $ref pointers to use the sanitized keys, and converts all schemas and definitions in the multi-document.

Example (Converting to OpenAPI 3.1)

import { JsonSchema } from "effect"

const multi: JsonSchema.MultiDocument<"draft-2020-12"> = {
  dialect: "draft-2020-12",
  schemas: [{ $ref: "#/$defs/User" }],
  definitions: {
    User: { type: "object", properties: { name: { type: "string" } } }
  }
}

const openapi = JsonSchema.toMultiDocumentOpenApi3_1(multi)
console.log(openapi.dialect) // "openapi-3.1"
console.log(openapi.schemas[0]) // { $ref: "#/components/schemas/User" }
export function toMultiDocumentOpenApi3_1(multiDocument: MultiDocument<"draft-2020-12">): MultiDocument<"openapi-3.1"> {
  const keyMap = new Map<string, string>()
  for (const key of Object.keys(multiDocument.definitions)) {
    const sanitized = sanitizeOpenApiComponentsSchemasKey(key)
    if (sanitized !== key) {
      keyMap.set(key, sanitized)
    }
  }

  function rewrite(schema: JsonSchema): JsonSchema {
    return rewrite_refs(schema, ($ref) => {
      const tokens = $ref.split("/")
      if (tokens.length > 0) {
        const identifier = unescapeToken(tokens[tokens.length - 1])
        const sanitized = keyMap.get(identifier)
        if (sanitized !== undefined) {
          $ref = tokens.slice(0, -1).join("/") + "/" + sanitized
        }
      }
      return $ref.replace(RE_DEFS, "#/components/schemas")
    }) as JsonSchema
  }

  return {
    dialect: "openapi-3.1",
    schemas: Arr.map(multiDocument.schemas, rewrite),
    definitions: Rec.mapEntries(
      multiDocument.definitions,
      (definition, key) => [keyMap.get(key) ?? key, rewrite(definition)]
    )
  }
}