docusaurus-theme-openapi-docs 0.0.0-1333 → 0.0.0-1337
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.
|
@@ -267,6 +267,9 @@ const AnyOneOf = ({ schema, schemaType, schemaPath }) => {
|
|
|
267
267
|
}),
|
|
268
268
|
(anyOneSchema.type === "object" || !anyOneSchema.type) &&
|
|
269
269
|
anyOneSchema.properties &&
|
|
270
|
+
!anyOneSchema.oneOf &&
|
|
271
|
+
!anyOneSchema.anyOf &&
|
|
272
|
+
!anyOneSchema.allOf &&
|
|
270
273
|
react_1.default.createElement(Properties, {
|
|
271
274
|
schema: anyOneSchema,
|
|
272
275
|
schemaType: schemaType,
|
|
@@ -140,6 +140,74 @@ describe("foldSiblingsIntoBranches", () => {
|
|
|
140
140
|
expect(result.items).toBeUndefined();
|
|
141
141
|
expect(result.oneOf).toHaveLength(1);
|
|
142
142
|
});
|
|
143
|
+
// Regression for #1548 (property duplication in nested anyOf-of-oneOf):
|
|
144
|
+
// when the outer schema is `{ properties, anyOf: [{oneOf:[...]}, ...] }`,
|
|
145
|
+
// fold merges the outer properties into each anyOf branch, giving each
|
|
146
|
+
// branch its own inner `oneOf` alongside merged properties. The AnyOneOf
|
|
147
|
+
// render layer then delegates the branch to SchemaNode, which folds again
|
|
148
|
+
// into each inner variant. If AnyOneOf were to *also* render the branch's
|
|
149
|
+
// properties directly at that outer level, the same fields would appear
|
|
150
|
+
// twice per selected inner variant tab — hence the check in Schema/index.tsx
|
|
151
|
+
// that skips <Properties> when the branch has a nested oneOf/anyOf/allOf.
|
|
152
|
+
it("folds outer properties into each anyOf branch when branches contain nested oneOf", () => {
|
|
153
|
+
const schema = {
|
|
154
|
+
type: "object",
|
|
155
|
+
properties: {
|
|
156
|
+
name: { type: "string" },
|
|
157
|
+
default_value: { type: "string" },
|
|
158
|
+
},
|
|
159
|
+
anyOf: [
|
|
160
|
+
{
|
|
161
|
+
oneOf: [
|
|
162
|
+
{
|
|
163
|
+
title: "aggregate_group",
|
|
164
|
+
properties: {
|
|
165
|
+
aggregate_group: { type: "string" },
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
title: "tap",
|
|
170
|
+
properties: {
|
|
171
|
+
tap: { type: "object" },
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
oneOf: [
|
|
178
|
+
{
|
|
179
|
+
title: "folder",
|
|
180
|
+
properties: { folder: { type: "string" } },
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
title: "snippet",
|
|
184
|
+
properties: { snippet: { type: "string" } },
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
};
|
|
190
|
+
const outer = (0, normalize_1.foldSiblingsIntoBranches)(schema);
|
|
191
|
+
expect(outer.properties).toBeUndefined();
|
|
192
|
+
expect(outer.anyOf).toHaveLength(2);
|
|
193
|
+
for (const branch of outer.anyOf) {
|
|
194
|
+
// Each anyOf branch retains its own inner oneOf and picks up the
|
|
195
|
+
// merged outer properties as siblings — this is the shape that
|
|
196
|
+
// AnyOneOf must NOT render <Properties> for directly, because
|
|
197
|
+
// SchemaNode will fold them into the inner variants below.
|
|
198
|
+
expect(branch.oneOf).toBeDefined();
|
|
199
|
+
expect(branch.properties.name).toBeDefined();
|
|
200
|
+
expect(branch.properties.default_value).toBeDefined();
|
|
201
|
+
const inner = (0, normalize_1.foldSiblingsIntoBranches)(branch);
|
|
202
|
+
expect(inner.properties).toBeUndefined();
|
|
203
|
+
expect(inner.oneOf).toBeDefined();
|
|
204
|
+
for (const variant of inner.oneOf) {
|
|
205
|
+
// Merged outer properties appear exactly once — inside each variant.
|
|
206
|
+
expect(variant.properties.name).toBeDefined();
|
|
207
|
+
expect(variant.properties.default_value).toBeDefined();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
143
211
|
});
|
|
144
212
|
describe("getDiscriminator", () => {
|
|
145
213
|
it("returns direct discriminator", () => {
|
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-1337",
|
|
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": "^10.0.3",
|
|
41
|
-
"docusaurus-plugin-openapi-docs": "0.0.0-
|
|
41
|
+
"docusaurus-plugin-openapi-docs": "0.0.0-1337",
|
|
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": "eb25a87f1b874a78582eadb3dc389d967dc221f4"
|
|
86
86
|
}
|
|
@@ -251,8 +251,16 @@ const AnyOneOf: React.FC<SchemaProps> = ({
|
|
|
251
251
|
|
|
252
252
|
{/* Handle actual object types with properties or nested schemas */}
|
|
253
253
|
{/* Note: In OpenAPI, properties implies type: object even if not explicitly set */}
|
|
254
|
+
{/* When the branch also has a nested oneOf/anyOf/allOf, skip
|
|
255
|
+
Properties here and delegate to SchemaNode below —
|
|
256
|
+
foldSiblingsIntoBranches will merge these properties into
|
|
257
|
+
each inner variant, so rendering them inline as well would
|
|
258
|
+
duplicate them per variant tab. See #1548. */}
|
|
254
259
|
{(anyOneSchema.type === "object" || !anyOneSchema.type) &&
|
|
255
|
-
anyOneSchema.properties &&
|
|
260
|
+
anyOneSchema.properties &&
|
|
261
|
+
!anyOneSchema.oneOf &&
|
|
262
|
+
!anyOneSchema.anyOf &&
|
|
263
|
+
!anyOneSchema.allOf && (
|
|
256
264
|
<Properties
|
|
257
265
|
schema={anyOneSchema}
|
|
258
266
|
schemaType={schemaType}
|
|
@@ -158,6 +158,78 @@ describe("foldSiblingsIntoBranches", () => {
|
|
|
158
158
|
expect(result.items).toBeUndefined();
|
|
159
159
|
expect(result.oneOf).toHaveLength(1);
|
|
160
160
|
});
|
|
161
|
+
|
|
162
|
+
// Regression for #1548 (property duplication in nested anyOf-of-oneOf):
|
|
163
|
+
// when the outer schema is `{ properties, anyOf: [{oneOf:[...]}, ...] }`,
|
|
164
|
+
// fold merges the outer properties into each anyOf branch, giving each
|
|
165
|
+
// branch its own inner `oneOf` alongside merged properties. The AnyOneOf
|
|
166
|
+
// render layer then delegates the branch to SchemaNode, which folds again
|
|
167
|
+
// into each inner variant. If AnyOneOf were to *also* render the branch's
|
|
168
|
+
// properties directly at that outer level, the same fields would appear
|
|
169
|
+
// twice per selected inner variant tab — hence the check in Schema/index.tsx
|
|
170
|
+
// that skips <Properties> when the branch has a nested oneOf/anyOf/allOf.
|
|
171
|
+
it("folds outer properties into each anyOf branch when branches contain nested oneOf", () => {
|
|
172
|
+
const schema = {
|
|
173
|
+
type: "object",
|
|
174
|
+
properties: {
|
|
175
|
+
name: { type: "string" },
|
|
176
|
+
default_value: { type: "string" },
|
|
177
|
+
},
|
|
178
|
+
anyOf: [
|
|
179
|
+
{
|
|
180
|
+
oneOf: [
|
|
181
|
+
{
|
|
182
|
+
title: "aggregate_group",
|
|
183
|
+
properties: {
|
|
184
|
+
aggregate_group: { type: "string" },
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
title: "tap",
|
|
189
|
+
properties: {
|
|
190
|
+
tap: { type: "object" },
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
oneOf: [
|
|
197
|
+
{
|
|
198
|
+
title: "folder",
|
|
199
|
+
properties: { folder: { type: "string" } },
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
title: "snippet",
|
|
203
|
+
properties: { snippet: { type: "string" } },
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const outer = foldSiblingsIntoBranches(schema);
|
|
211
|
+
expect(outer.properties).toBeUndefined();
|
|
212
|
+
expect(outer.anyOf).toHaveLength(2);
|
|
213
|
+
|
|
214
|
+
for (const branch of outer.anyOf) {
|
|
215
|
+
// Each anyOf branch retains its own inner oneOf and picks up the
|
|
216
|
+
// merged outer properties as siblings — this is the shape that
|
|
217
|
+
// AnyOneOf must NOT render <Properties> for directly, because
|
|
218
|
+
// SchemaNode will fold them into the inner variants below.
|
|
219
|
+
expect(branch.oneOf).toBeDefined();
|
|
220
|
+
expect(branch.properties.name).toBeDefined();
|
|
221
|
+
expect(branch.properties.default_value).toBeDefined();
|
|
222
|
+
|
|
223
|
+
const inner = foldSiblingsIntoBranches(branch);
|
|
224
|
+
expect(inner.properties).toBeUndefined();
|
|
225
|
+
expect(inner.oneOf).toBeDefined();
|
|
226
|
+
for (const variant of inner.oneOf) {
|
|
227
|
+
// Merged outer properties appear exactly once — inside each variant.
|
|
228
|
+
expect(variant.properties.name).toBeDefined();
|
|
229
|
+
expect(variant.properties.default_value).toBeDefined();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
161
233
|
});
|
|
162
234
|
|
|
163
235
|
describe("getDiscriminator", () => {
|