docusaurus-theme-openapi-docs 5.1.0 → 5.1.2

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.
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /* ============================================================================
3
+ * Copyright (c) Palo Alto Networks
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ * ========================================================================== */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const normalize_1 = require("./normalize");
10
+ describe("normalizeSchema", () => {
11
+ it("returns the input as-is (identity-stable pass-through)", () => {
12
+ const schema = { type: "object", properties: { a: { type: "string" } } };
13
+ expect((0, normalize_1.normalizeSchema)(schema)).toBe(schema);
14
+ });
15
+ it("handles null, undefined, and primitives", () => {
16
+ expect((0, normalize_1.normalizeSchema)(null)).toBeNull();
17
+ expect((0, normalize_1.normalizeSchema)(undefined)).toBeUndefined();
18
+ expect((0, normalize_1.normalizeSchema)("string")).toBe("string");
19
+ expect((0, normalize_1.normalizeSchema)(42)).toBe(42);
20
+ });
21
+ });
22
+ describe("mergeAllOf", () => {
23
+ it("merges allOf members into a flat schema", () => {
24
+ const schema = {
25
+ allOf: [
26
+ { type: "object", properties: { a: { type: "string" } } },
27
+ { type: "object", properties: { b: { type: "number" } } },
28
+ ],
29
+ };
30
+ const result = (0, normalize_1.mergeAllOf)(schema);
31
+ expect(result.allOf).toBeUndefined();
32
+ expect(result.properties.a).toEqual({ type: "string" });
33
+ expect(result.properties.b).toEqual({ type: "number" });
34
+ });
35
+ it("strips conflicting additionalProperties: false from allOf members", () => {
36
+ const schema = {
37
+ allOf: [
38
+ {
39
+ type: "object",
40
+ properties: { a: { type: "string" } },
41
+ additionalProperties: false,
42
+ },
43
+ {
44
+ type: "object",
45
+ properties: { b: { type: "number" } },
46
+ additionalProperties: false,
47
+ },
48
+ ],
49
+ };
50
+ const result = (0, normalize_1.mergeAllOf)(schema);
51
+ expect(result.properties.a).toBeDefined();
52
+ expect(result.properties.b).toBeDefined();
53
+ });
54
+ it("preserves both properties and oneOf when merging incompatible-shape members", () => {
55
+ const result = (0, normalize_1.mergeAllOf)({
56
+ allOf: [
57
+ { type: "object", properties: { id: { type: "string" } } },
58
+ { oneOf: [{ title: "a" }, { title: "b" }] },
59
+ ],
60
+ });
61
+ expect(result.properties.id).toBeDefined();
62
+ expect(result.oneOf).toHaveLength(2);
63
+ });
64
+ });
65
+ describe("foldSiblingsIntoBranches", () => {
66
+ it("returns schema unchanged when no oneOf/anyOf is present", () => {
67
+ const schema = { type: "object", properties: { a: { type: "string" } } };
68
+ expect((0, normalize_1.foldSiblingsIntoBranches)(schema)).toBe(schema);
69
+ });
70
+ it("returns schema unchanged when branches have no siblings", () => {
71
+ const schema = {
72
+ oneOf: [{ properties: { a: { type: "string" } } }],
73
+ };
74
+ expect((0, normalize_1.foldSiblingsIntoBranches)(schema)).toBe(schema);
75
+ });
76
+ it("returns schema unchanged when a discriminator is present", () => {
77
+ const schema = {
78
+ discriminator: { propertyName: "type" },
79
+ properties: { shared: { type: "string" } },
80
+ oneOf: [{ properties: { a: { type: "number" } } }],
81
+ };
82
+ expect((0, normalize_1.foldSiblingsIntoBranches)(schema)).toBe(schema);
83
+ });
84
+ it("folds sibling properties into oneOf branches", () => {
85
+ const schema = {
86
+ properties: { shared: { type: "string" } },
87
+ oneOf: [
88
+ { properties: { a: { type: "number" } } },
89
+ { properties: { b: { type: "boolean" } } },
90
+ ],
91
+ };
92
+ const result = (0, normalize_1.foldSiblingsIntoBranches)(schema);
93
+ expect(result.properties).toBeUndefined();
94
+ expect(result.oneOf).toHaveLength(2);
95
+ expect(result.oneOf[0].properties.shared).toBeDefined();
96
+ expect(result.oneOf[0].properties.a).toBeDefined();
97
+ });
98
+ it("folds sibling properties into anyOf branches", () => {
99
+ const schema = {
100
+ properties: { shared: { type: "string" } },
101
+ anyOf: [
102
+ { properties: { a: { type: "number" } } },
103
+ { properties: { b: { type: "boolean" } } },
104
+ ],
105
+ };
106
+ const result = (0, normalize_1.foldSiblingsIntoBranches)(schema);
107
+ expect(result.properties).toBeUndefined();
108
+ expect(result.anyOf).toHaveLength(2);
109
+ expect(result.anyOf[1].properties.shared).toBeDefined();
110
+ expect(result.anyOf[1].properties.b).toBeDefined();
111
+ });
112
+ it("preserves metadata and x-extension keys when folding", () => {
113
+ const schema = {
114
+ title: "Test",
115
+ description: "desc",
116
+ deprecated: true,
117
+ "x-vendor": true,
118
+ properties: { shared: { type: "string" } },
119
+ anyOf: [{ properties: { a: { type: "number" } } }],
120
+ };
121
+ const result = (0, normalize_1.foldSiblingsIntoBranches)(schema);
122
+ expect(result.title).toBe("Test");
123
+ expect(result.description).toBe("desc");
124
+ expect(result.deprecated).toBe(true);
125
+ expect(result["x-vendor"]).toBe(true);
126
+ expect(result.properties).toBeUndefined();
127
+ });
128
+ it("strips non-metadata keys from result", () => {
129
+ const schema = {
130
+ type: "object",
131
+ required: ["shared"],
132
+ properties: { shared: { type: "string" } },
133
+ items: { type: "string" },
134
+ oneOf: [{ properties: { a: { type: "number" } } }],
135
+ };
136
+ const result = (0, normalize_1.foldSiblingsIntoBranches)(schema);
137
+ expect(result.type).toBeUndefined();
138
+ expect(result.required).toBeUndefined();
139
+ expect(result.properties).toBeUndefined();
140
+ expect(result.items).toBeUndefined();
141
+ expect(result.oneOf).toHaveLength(1);
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
+ });
211
+ });
212
+ describe("getDiscriminator", () => {
213
+ it("returns direct discriminator", () => {
214
+ const schema = { discriminator: { propertyName: "type" } };
215
+ expect((0, normalize_1.getDiscriminator)(schema)).toEqual({
216
+ propertyName: "type",
217
+ });
218
+ });
219
+ it("finds discriminator in oneOf branches", () => {
220
+ const schema = {
221
+ oneOf: [{ discriminator: { propertyName: "kind" } }, { type: "string" }],
222
+ };
223
+ expect((0, normalize_1.getDiscriminator)(schema)).toEqual({
224
+ propertyName: "kind",
225
+ });
226
+ });
227
+ it("finds discriminator in anyOf branches", () => {
228
+ const schema = {
229
+ anyOf: [
230
+ { type: "string" },
231
+ { discriminator: { propertyName: "variant" } },
232
+ ],
233
+ };
234
+ expect((0, normalize_1.getDiscriminator)(schema)).toEqual({
235
+ propertyName: "variant",
236
+ });
237
+ });
238
+ it("finds discriminator in allOf branches", () => {
239
+ const schema = {
240
+ allOf: [
241
+ { properties: { id: { type: "string" } } },
242
+ { discriminator: { propertyName: "type" } },
243
+ ],
244
+ };
245
+ expect((0, normalize_1.getDiscriminator)(schema)).toEqual({
246
+ propertyName: "type",
247
+ });
248
+ });
249
+ it("returns undefined when no discriminator exists", () => {
250
+ const schema = {
251
+ type: "object",
252
+ properties: { name: { type: "string" } },
253
+ };
254
+ expect((0, normalize_1.getDiscriminator)(schema)).toBeUndefined();
255
+ });
256
+ it("returns undefined for null/primitive input", () => {
257
+ expect((0, normalize_1.getDiscriminator)(null)).toBeUndefined();
258
+ expect((0, normalize_1.getDiscriminator)("string")).toBeUndefined();
259
+ });
260
+ it("caches results for same object reference", () => {
261
+ const inner = { discriminator: { propertyName: "type" } };
262
+ const schema = { oneOf: [inner] };
263
+ const first = (0, normalize_1.getDiscriminator)(schema);
264
+ const second = (0, normalize_1.getDiscriminator)(schema);
265
+ expect(first).toBe(second);
266
+ });
267
+ it("handles cycles without infinite recursion", () => {
268
+ const a = { properties: {} };
269
+ const b = { properties: { a } };
270
+ a.properties.b = b;
271
+ expect(() => (0, normalize_1.getDiscriminator)(a)).not.toThrow();
272
+ expect((0, normalize_1.getDiscriminator)(a)).toBeUndefined();
273
+ });
274
+ });
275
+ describe("findPropertyDeep", () => {
276
+ it("returns property at top level", () => {
277
+ const schema = { properties: { foo: { type: "string" } } };
278
+ expect((0, normalize_1.findPropertyDeep)(schema, "foo")).toEqual({
279
+ type: "string",
280
+ });
281
+ });
282
+ it("finds property in oneOf branches", () => {
283
+ const schema = {
284
+ oneOf: [
285
+ { properties: { a: { type: "string" } } },
286
+ { properties: { b: { type: "number" } } },
287
+ ],
288
+ };
289
+ expect((0, normalize_1.findPropertyDeep)(schema, "a")).toEqual({
290
+ type: "string",
291
+ });
292
+ expect((0, normalize_1.findPropertyDeep)(schema, "b")).toEqual({
293
+ type: "number",
294
+ });
295
+ });
296
+ it("finds property in anyOf branches", () => {
297
+ const schema = {
298
+ anyOf: [{ properties: { x: { type: "integer" } } }],
299
+ };
300
+ expect((0, normalize_1.findPropertyDeep)(schema, "x")).toEqual({
301
+ type: "integer",
302
+ });
303
+ });
304
+ it("finds property in allOf branches", () => {
305
+ const schema = {
306
+ allOf: [{ properties: { y: { type: "boolean" } } }],
307
+ };
308
+ expect((0, normalize_1.findPropertyDeep)(schema, "y")).toEqual({
309
+ type: "boolean",
310
+ });
311
+ });
312
+ it("returns undefined when property not found", () => {
313
+ const schema = { properties: { foo: { type: "string" } } };
314
+ expect((0, normalize_1.findPropertyDeep)(schema, "bar")).toBeUndefined();
315
+ });
316
+ it("returns undefined for null/primitive input", () => {
317
+ expect((0, normalize_1.findPropertyDeep)(null, "foo")).toBeUndefined();
318
+ expect((0, normalize_1.findPropertyDeep)("string", "foo")).toBeUndefined();
319
+ });
320
+ it("handles cycles without infinite recursion", () => {
321
+ const a = { properties: {} };
322
+ a.oneOf = [a];
323
+ expect(() => (0, normalize_1.findPropertyDeep)(a, "foo")).not.toThrow();
324
+ expect((0, normalize_1.findPropertyDeep)(a, "foo")).toBeUndefined();
325
+ });
326
+ });
327
+ describe("isCircularMarker", () => {
328
+ it("returns true for circular marker strings", () => {
329
+ expect((0, normalize_1.isCircularMarker)("circular(Title)")).toBe(true);
330
+ expect((0, normalize_1.isCircularMarker)("circular()")).toBe(true);
331
+ });
332
+ it("returns false for other values", () => {
333
+ expect((0, normalize_1.isCircularMarker)("normal string")).toBe(false);
334
+ expect((0, normalize_1.isCircularMarker)(null)).toBe(false);
335
+ expect((0, normalize_1.isCircularMarker)(undefined)).toBe(false);
336
+ expect((0, normalize_1.isCircularMarker)({})).toBe(false);
337
+ expect((0, normalize_1.isCircularMarker)(42)).toBe(false);
338
+ });
339
+ });
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": "5.1.0",
4
+ "version": "5.1.2",
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": "^5.1.0",
41
+ "docusaurus-plugin-openapi-docs": "^5.1.2",
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": "977ec415b37207142f71f6e3d3780df834301d31"
85
+ "gitHead": "c5e36feabeb4ee6758a7bf5a24a7bfe96cb88500"
86
86
  }