docusaurus-theme-openapi-docs 0.0.0-1293 → 0.0.0-1294
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/markdown/schema.js +34 -10
- package/lib/markdown/schema.test.js +35 -0
- package/package.json +3 -3
- package/src/markdown/schema.test.ts +41 -0
- package/src/markdown/schema.ts +38 -10
package/lib/markdown/schema.js
CHANGED
|
@@ -42,13 +42,36 @@ function getTypeFromSchema(schema) {
|
|
|
42
42
|
}
|
|
43
43
|
return undefined;
|
|
44
44
|
}
|
|
45
|
+
// OpenAPI 3.1 / JSON Schema 2020-12 allows `type` to be an array of type names
|
|
46
|
+
// (e.g. `["string", "null"]`). Normalize to a single name and a pretty-printed
|
|
47
|
+
// union form joined with ` | `.
|
|
48
|
+
function normalizeType(type) {
|
|
49
|
+
if (Array.isArray(type)) {
|
|
50
|
+
const filtered = type.filter((t) => typeof t === "string");
|
|
51
|
+
if (filtered.length === 0)
|
|
52
|
+
return { isUnion: false };
|
|
53
|
+
if (filtered.length === 1)
|
|
54
|
+
return { single: filtered[0], isUnion: false };
|
|
55
|
+
return { pretty: filtered.join(" | "), isUnion: true };
|
|
56
|
+
}
|
|
57
|
+
if (typeof type === "string")
|
|
58
|
+
return { single: type, isUnion: false };
|
|
59
|
+
return { isUnion: false };
|
|
60
|
+
}
|
|
45
61
|
function prettyName(schema, circular) {
|
|
46
62
|
// Handle enum-only schemas (valid in JSON Schema)
|
|
47
63
|
// When enum is present without explicit type, treat as string
|
|
48
64
|
if (schema.enum && !schema.type) {
|
|
49
65
|
return "string";
|
|
50
66
|
}
|
|
67
|
+
const t = normalizeType(schema.type);
|
|
51
68
|
if (schema.format) {
|
|
69
|
+
if (t.single) {
|
|
70
|
+
return `${t.single}<${schema.format}>`;
|
|
71
|
+
}
|
|
72
|
+
if (t.isUnion) {
|
|
73
|
+
return `(${t.pretty})<${schema.format}>`;
|
|
74
|
+
}
|
|
52
75
|
return schema.format;
|
|
53
76
|
}
|
|
54
77
|
if (schema.allOf) {
|
|
@@ -72,22 +95,23 @@ function prettyName(schema, circular) {
|
|
|
72
95
|
if (schema.anyOf) {
|
|
73
96
|
return "object";
|
|
74
97
|
}
|
|
75
|
-
if (
|
|
76
|
-
return schema.xml?.name ??
|
|
77
|
-
// return schema.type;
|
|
98
|
+
if (t.single === "object") {
|
|
99
|
+
return schema.xml?.name ?? t.single;
|
|
78
100
|
}
|
|
79
|
-
if (
|
|
80
|
-
return schema.xml?.name ??
|
|
81
|
-
// return schema.type;
|
|
101
|
+
if (t.single === "array") {
|
|
102
|
+
return schema.xml?.name ?? t.single;
|
|
82
103
|
}
|
|
83
|
-
if (
|
|
84
|
-
return
|
|
104
|
+
if (t.isUnion) {
|
|
105
|
+
return t.pretty;
|
|
85
106
|
}
|
|
86
|
-
return schema.title ??
|
|
107
|
+
return schema.title ?? t.single;
|
|
87
108
|
}
|
|
88
109
|
function getSchemaName(schema, circular) {
|
|
89
110
|
if (schema.items) {
|
|
90
|
-
|
|
111
|
+
const items = schema.items;
|
|
112
|
+
const inner = getSchemaName(items, circular);
|
|
113
|
+
const needsParens = Array.isArray(items.type) && items.type.length > 1;
|
|
114
|
+
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
91
115
|
}
|
|
92
116
|
return prettyName(schema, circular) ?? "";
|
|
93
117
|
}
|
|
@@ -48,4 +48,39 @@ describe("getSchemaName", () => {
|
|
|
48
48
|
};
|
|
49
49
|
expect((0, schema_1.getSchemaName)(schema)).toBe("integer[][][]");
|
|
50
50
|
});
|
|
51
|
+
it("joins OpenAPI 3.1 type arrays with ` | ` (issue #950)", () => {
|
|
52
|
+
const schema = { type: ["string", "null"] };
|
|
53
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("string | null");
|
|
54
|
+
});
|
|
55
|
+
it("unwraps a single-element type array", () => {
|
|
56
|
+
const schema = { type: ["integer"] };
|
|
57
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("integer");
|
|
58
|
+
});
|
|
59
|
+
it("renders single type with format as `type<format>`", () => {
|
|
60
|
+
const schema = {
|
|
61
|
+
type: "string",
|
|
62
|
+
format: "uuid",
|
|
63
|
+
};
|
|
64
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("string<uuid>");
|
|
65
|
+
});
|
|
66
|
+
it("renders type union with format", () => {
|
|
67
|
+
const schema = {
|
|
68
|
+
type: ["string", "null"],
|
|
69
|
+
format: "uuid",
|
|
70
|
+
};
|
|
71
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("(string | null)<uuid>");
|
|
72
|
+
});
|
|
73
|
+
it("resolves type from an allOf wrapper that contains an enum", () => {
|
|
74
|
+
const schema = {
|
|
75
|
+
allOf: [{ type: "string", enum: ["a", "b"] }],
|
|
76
|
+
};
|
|
77
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("string");
|
|
78
|
+
});
|
|
79
|
+
it("renders array of items whose type is a union", () => {
|
|
80
|
+
const schema = {
|
|
81
|
+
type: "array",
|
|
82
|
+
items: { type: ["string", "null"] },
|
|
83
|
+
};
|
|
84
|
+
expect((0, schema_1.getSchemaName)(schema)).toBe("(string | null)[]");
|
|
85
|
+
});
|
|
51
86
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-theme-openapi-docs",
|
|
3
3
|
"description": "OpenAPI theme for Docusaurus.",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-1294",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@types/postman-collection": "^3.5.11",
|
|
39
39
|
"@types/react-modal": "^3.16.3",
|
|
40
40
|
"concurrently": "^9.2.0",
|
|
41
|
-
"docusaurus-plugin-openapi-docs": "0.0.0-
|
|
41
|
+
"docusaurus-plugin-openapi-docs": "0.0.0-1294",
|
|
42
42
|
"docusaurus-plugin-sass": "^0.2.6",
|
|
43
43
|
"eslint-plugin-prettier": "^5.5.1"
|
|
44
44
|
},
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"engines": {
|
|
83
83
|
"node": ">=14"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "dcce97d6a3cae4f76af8f02e81571e8ce5a394ac"
|
|
86
86
|
}
|
|
@@ -58,4 +58,45 @@ describe("getSchemaName", () => {
|
|
|
58
58
|
} as SchemaObject;
|
|
59
59
|
expect(getSchemaName(schema)).toBe("integer[][][]");
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
it("joins OpenAPI 3.1 type arrays with ` | ` (issue #950)", () => {
|
|
63
|
+
const schema = { type: ["string", "null"] } as unknown as SchemaObject;
|
|
64
|
+
expect(getSchemaName(schema)).toBe("string | null");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("unwraps a single-element type array", () => {
|
|
68
|
+
const schema = { type: ["integer"] } as unknown as SchemaObject;
|
|
69
|
+
expect(getSchemaName(schema)).toBe("integer");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("renders single type with format as `type<format>`", () => {
|
|
73
|
+
const schema = {
|
|
74
|
+
type: "string",
|
|
75
|
+
format: "uuid",
|
|
76
|
+
} as SchemaObject;
|
|
77
|
+
expect(getSchemaName(schema)).toBe("string<uuid>");
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("renders type union with format", () => {
|
|
81
|
+
const schema = {
|
|
82
|
+
type: ["string", "null"],
|
|
83
|
+
format: "uuid",
|
|
84
|
+
} as unknown as SchemaObject;
|
|
85
|
+
expect(getSchemaName(schema)).toBe("(string | null)<uuid>");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("resolves type from an allOf wrapper that contains an enum", () => {
|
|
89
|
+
const schema = {
|
|
90
|
+
allOf: [{ type: "string", enum: ["a", "b"] }],
|
|
91
|
+
} as unknown as SchemaObject;
|
|
92
|
+
expect(getSchemaName(schema)).toBe("string");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("renders array of items whose type is a union", () => {
|
|
96
|
+
const schema: SchemaObject = {
|
|
97
|
+
type: "array",
|
|
98
|
+
items: { type: ["string", "null"] } as any,
|
|
99
|
+
} as SchemaObject;
|
|
100
|
+
expect(getSchemaName(schema)).toBe("(string | null)[]");
|
|
101
|
+
});
|
|
61
102
|
});
|
package/src/markdown/schema.ts
CHANGED
|
@@ -48,6 +48,24 @@ function getTypeFromSchema(schema: SchemaObject): string | undefined {
|
|
|
48
48
|
return undefined;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// OpenAPI 3.1 / JSON Schema 2020-12 allows `type` to be an array of type names
|
|
52
|
+
// (e.g. `["string", "null"]`). Normalize to a single name and a pretty-printed
|
|
53
|
+
// union form joined with ` | `.
|
|
54
|
+
function normalizeType(type: unknown): {
|
|
55
|
+
single?: string;
|
|
56
|
+
pretty?: string;
|
|
57
|
+
isUnion: boolean;
|
|
58
|
+
} {
|
|
59
|
+
if (Array.isArray(type)) {
|
|
60
|
+
const filtered = type.filter((t): t is string => typeof t === "string");
|
|
61
|
+
if (filtered.length === 0) return { isUnion: false };
|
|
62
|
+
if (filtered.length === 1) return { single: filtered[0], isUnion: false };
|
|
63
|
+
return { pretty: filtered.join(" | "), isUnion: true };
|
|
64
|
+
}
|
|
65
|
+
if (typeof type === "string") return { single: type, isUnion: false };
|
|
66
|
+
return { isUnion: false };
|
|
67
|
+
}
|
|
68
|
+
|
|
51
69
|
function prettyName(schema: SchemaObject, circular?: boolean) {
|
|
52
70
|
// Handle enum-only schemas (valid in JSON Schema)
|
|
53
71
|
// When enum is present without explicit type, treat as string
|
|
@@ -55,7 +73,15 @@ function prettyName(schema: SchemaObject, circular?: boolean) {
|
|
|
55
73
|
return "string";
|
|
56
74
|
}
|
|
57
75
|
|
|
76
|
+
const t = normalizeType(schema.type);
|
|
77
|
+
|
|
58
78
|
if (schema.format) {
|
|
79
|
+
if (t.single) {
|
|
80
|
+
return `${t.single}<${schema.format}>`;
|
|
81
|
+
}
|
|
82
|
+
if (t.isUnion) {
|
|
83
|
+
return `(${t.pretty})<${schema.format}>`;
|
|
84
|
+
}
|
|
59
85
|
return schema.format;
|
|
60
86
|
}
|
|
61
87
|
|
|
@@ -83,21 +109,19 @@ function prettyName(schema: SchemaObject, circular?: boolean) {
|
|
|
83
109
|
return "object";
|
|
84
110
|
}
|
|
85
111
|
|
|
86
|
-
if (
|
|
87
|
-
return schema.xml?.name ??
|
|
88
|
-
// return schema.type;
|
|
112
|
+
if (t.single === "object") {
|
|
113
|
+
return schema.xml?.name ?? t.single;
|
|
89
114
|
}
|
|
90
115
|
|
|
91
|
-
if (
|
|
92
|
-
return schema.xml?.name ??
|
|
93
|
-
// return schema.type;
|
|
116
|
+
if (t.single === "array") {
|
|
117
|
+
return schema.xml?.name ?? t.single;
|
|
94
118
|
}
|
|
95
119
|
|
|
96
|
-
if (
|
|
97
|
-
return
|
|
120
|
+
if (t.isUnion) {
|
|
121
|
+
return t.pretty;
|
|
98
122
|
}
|
|
99
123
|
|
|
100
|
-
return schema.title ??
|
|
124
|
+
return schema.title ?? t.single;
|
|
101
125
|
}
|
|
102
126
|
|
|
103
127
|
export function getSchemaName(
|
|
@@ -105,7 +129,11 @@ export function getSchemaName(
|
|
|
105
129
|
circular?: boolean
|
|
106
130
|
): string {
|
|
107
131
|
if (schema.items) {
|
|
108
|
-
|
|
132
|
+
const items = schema.items as SchemaObject;
|
|
133
|
+
const inner = getSchemaName(items, circular);
|
|
134
|
+
const needsParens =
|
|
135
|
+
Array.isArray((items as any).type) && (items as any).type.length > 1;
|
|
136
|
+
return needsParens ? `(${inner})[]` : `${inner}[]`;
|
|
109
137
|
}
|
|
110
138
|
|
|
111
139
|
return prettyName(schema, circular) ?? "";
|