docusaurus-theme-openapi-docs 0.0.0-1247 → 0.0.0-1250

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.
@@ -96,6 +96,32 @@ const mergeAllOf = (allOf) => {
96
96
  const mergedSchemas = (0, allof_merge_1.merge)(allOf, { onMergeError });
97
97
  return mergedSchemas ?? {};
98
98
  };
99
+ /**
100
+ * Fold sibling fields into each `oneOf`/`anyOf` branch via allOf-merge, so each
101
+ * branch is self-contained. Mirrors Redoc's `SchemaModel.initOneOf` behavior.
102
+ * Without this, when an `allOf` override redefines a nested property with
103
+ * `oneOf`, the merged schema ends up with both `properties` and `oneOf` as
104
+ * siblings — and the renderer prints the shared properties twice.
105
+ *
106
+ * See https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issues/1218
107
+ */
108
+ const foldSiblingsIntoBranches = (schema) => {
109
+ const branchKey = schema?.oneOf
110
+ ? "oneOf"
111
+ : schema?.anyOf
112
+ ? "anyOf"
113
+ : undefined;
114
+ if (!branchKey) return schema;
115
+ const branches = schema[branchKey];
116
+ if (!Array.isArray(branches) || branches.length === 0) return schema;
117
+ const siblings = { ...schema };
118
+ delete siblings[branchKey];
119
+ if (Object.keys(siblings).length === 0) return schema;
120
+ const folded = branches.map((branch) =>
121
+ mergeAllOf({ allOf: [siblings, branch] })
122
+ );
123
+ return { [branchKey]: folded };
124
+ };
99
125
  /**
100
126
  * Recursively searches for a property in a schema, including nested
101
127
  * oneOf, anyOf, and allOf structures. This is needed for discriminators
@@ -701,17 +727,25 @@ const Items = ({ schema, schemaType, schemaPath }) => {
701
727
  // Build the items schema path
702
728
  const itemsSchemaPath = schemaPath ? `${schemaPath}.items` : undefined;
703
729
  if (hasOneOfAnyOf || hasProperties || hasAdditionalProperties) {
730
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
731
+ // property rendering. See issue #1218.
732
+ const renderSchema =
733
+ hasOneOfAnyOf && hasProperties
734
+ ? foldSiblingsIntoBranches(itemsSchema)
735
+ : itemsSchema;
736
+ const renderHasProperties =
737
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
704
738
  return react_1.default.createElement(
705
739
  react_1.default.Fragment,
706
740
  null,
707
741
  react_1.default.createElement(ArrayBrackets_1.OpeningArrayBracket, null),
708
742
  hasOneOfAnyOf &&
709
743
  react_1.default.createElement(AnyOneOf, {
710
- schema: itemsSchema,
744
+ schema: renderSchema,
711
745
  schemaType: schemaType,
712
746
  schemaPath: itemsSchemaPath,
713
747
  }),
714
- hasProperties &&
748
+ renderHasProperties &&
715
749
  react_1.default.createElement(Properties, {
716
750
  schema: itemsSchema,
717
751
  schemaType: schemaType,
@@ -928,22 +962,30 @@ const SchemaEdge = ({
928
962
  });
929
963
  };
930
964
  function renderChildren(schema, schemaType, schemaPath) {
965
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
966
+ // property rendering. See issue #1218.
967
+ const hasOneOfAnyOf = !!(schema.oneOf || schema.anyOf);
968
+ const hasProperties = !!schema.properties;
969
+ const folded =
970
+ hasOneOfAnyOf && hasProperties ? foldSiblingsIntoBranches(schema) : schema;
971
+ const renderProperties =
972
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
931
973
  return react_1.default.createElement(
932
974
  react_1.default.Fragment,
933
975
  null,
934
- schema.oneOf &&
976
+ folded.oneOf &&
935
977
  react_1.default.createElement(AnyOneOf, {
936
- schema: schema,
978
+ schema: folded,
937
979
  schemaType: schemaType,
938
980
  schemaPath: schemaPath,
939
981
  }),
940
- schema.anyOf &&
982
+ folded.anyOf &&
941
983
  react_1.default.createElement(AnyOneOf, {
942
- schema: schema,
984
+ schema: folded,
943
985
  schemaType: schemaType,
944
986
  schemaPath: schemaPath,
945
987
  }),
946
- schema.properties &&
988
+ renderProperties &&
947
989
  react_1.default.createElement(Properties, {
948
990
  schema: schema,
949
991
  schemaType: schemaType,
@@ -1044,22 +1086,32 @@ const SchemaNode = ({ schema, schemaType, schemaPath }) => {
1044
1086
  ) {
1045
1087
  return null;
1046
1088
  }
1089
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
1090
+ // property rendering. See issue #1218.
1091
+ const hasOneOfAnyOf = !!(mergedSchemas.oneOf || mergedSchemas.anyOf);
1092
+ const hasProperties = !!mergedSchemas.properties;
1093
+ const folded =
1094
+ hasOneOfAnyOf && hasProperties
1095
+ ? foldSiblingsIntoBranches(mergedSchemas)
1096
+ : mergedSchemas;
1097
+ const renderProperties =
1098
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
1047
1099
  return react_1.default.createElement(
1048
1100
  "div",
1049
1101
  null,
1050
- mergedSchemas.oneOf &&
1102
+ folded.oneOf &&
1051
1103
  react_1.default.createElement(AnyOneOf, {
1052
- schema: mergedSchemas,
1104
+ schema: folded,
1053
1105
  schemaType: schemaType,
1054
1106
  schemaPath: schemaPath,
1055
1107
  }),
1056
- mergedSchemas.anyOf &&
1108
+ folded.anyOf &&
1057
1109
  react_1.default.createElement(AnyOneOf, {
1058
- schema: mergedSchemas,
1110
+ schema: folded,
1059
1111
  schemaType: schemaType,
1060
1112
  schemaPath: schemaPath,
1061
1113
  }),
1062
- mergedSchemas.properties &&
1114
+ renderProperties &&
1063
1115
  react_1.default.createElement(Properties, {
1064
1116
  schema: mergedSchemas,
1065
1117
  schemaType: schemaType,
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-1247",
4
+ "version": "0.0.0-1250",
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-1247",
41
+ "docusaurus-plugin-openapi-docs": "0.0.0-1250",
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": "2e6e04573a1c30d9b0ef899da2e75518ce7c046f"
85
+ "gitHead": "bc0f3a2a6e8e1d18abcf1684ab37716e5bde220b"
86
86
  }
@@ -44,6 +44,37 @@ const mergeAllOf = (allOf: any) => {
44
44
  return mergedSchemas ?? {};
45
45
  };
46
46
 
47
+ /**
48
+ * Fold sibling fields into each `oneOf`/`anyOf` branch via allOf-merge, so each
49
+ * branch is self-contained. Mirrors Redoc's `SchemaModel.initOneOf` behavior.
50
+ * Without this, when an `allOf` override redefines a nested property with
51
+ * `oneOf`, the merged schema ends up with both `properties` and `oneOf` as
52
+ * siblings — and the renderer prints the shared properties twice.
53
+ *
54
+ * See https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/issues/1218
55
+ */
56
+ const foldSiblingsIntoBranches = (schema: any): any => {
57
+ const branchKey = schema?.oneOf
58
+ ? "oneOf"
59
+ : schema?.anyOf
60
+ ? "anyOf"
61
+ : undefined;
62
+ if (!branchKey) return schema;
63
+
64
+ const branches = schema[branchKey];
65
+ if (!Array.isArray(branches) || branches.length === 0) return schema;
66
+
67
+ const siblings = { ...schema };
68
+ delete siblings[branchKey];
69
+ if (Object.keys(siblings).length === 0) return schema;
70
+
71
+ const folded = branches.map((branch: any) =>
72
+ mergeAllOf({ allOf: [siblings, branch] })
73
+ );
74
+
75
+ return { [branchKey]: folded };
76
+ };
77
+
47
78
  /**
48
79
  * Recursively searches for a property in a schema, including nested
49
80
  * oneOf, anyOf, and allOf structures. This is needed for discriminators
@@ -737,17 +768,25 @@ const Items: React.FC<{
737
768
  const itemsSchemaPath = schemaPath ? `${schemaPath}.items` : undefined;
738
769
 
739
770
  if (hasOneOfAnyOf || hasProperties || hasAdditionalProperties) {
771
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
772
+ // property rendering. See issue #1218.
773
+ const renderSchema =
774
+ hasOneOfAnyOf && hasProperties
775
+ ? foldSiblingsIntoBranches(itemsSchema)
776
+ : itemsSchema;
777
+ const renderHasProperties =
778
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
740
779
  return (
741
780
  <>
742
781
  <OpeningArrayBracket />
743
782
  {hasOneOfAnyOf && (
744
783
  <AnyOneOf
745
- schema={itemsSchema}
784
+ schema={renderSchema}
746
785
  schemaType={schemaType}
747
786
  schemaPath={itemsSchemaPath}
748
787
  />
749
788
  )}
750
- {hasProperties && (
789
+ {renderHasProperties && (
751
790
  <Properties
752
791
  schema={itemsSchema}
753
792
  schemaType={schemaType}
@@ -1032,23 +1071,31 @@ function renderChildren(
1032
1071
  schemaType: "request" | "response",
1033
1072
  schemaPath?: string
1034
1073
  ) {
1074
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
1075
+ // property rendering. See issue #1218.
1076
+ const hasOneOfAnyOf = !!(schema.oneOf || schema.anyOf);
1077
+ const hasProperties = !!schema.properties;
1078
+ const folded =
1079
+ hasOneOfAnyOf && hasProperties ? foldSiblingsIntoBranches(schema) : schema;
1080
+ const renderProperties =
1081
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
1035
1082
  return (
1036
1083
  <>
1037
- {schema.oneOf && (
1084
+ {folded.oneOf && (
1038
1085
  <AnyOneOf
1039
- schema={schema}
1086
+ schema={folded}
1040
1087
  schemaType={schemaType}
1041
1088
  schemaPath={schemaPath}
1042
1089
  />
1043
1090
  )}
1044
- {schema.anyOf && (
1091
+ {folded.anyOf && (
1045
1092
  <AnyOneOf
1046
- schema={schema}
1093
+ schema={folded}
1047
1094
  schemaType={schemaType}
1048
1095
  schemaPath={schemaPath}
1049
1096
  />
1050
1097
  )}
1051
- {schema.properties && (
1098
+ {renderProperties && (
1052
1099
  <Properties
1053
1100
  schema={schema}
1054
1101
  schemaType={schemaType}
@@ -1172,23 +1219,34 @@ const SchemaNode: React.FC<SchemaProps> = ({
1172
1219
  return null;
1173
1220
  }
1174
1221
 
1222
+ // Fold sibling properties into each oneOf/anyOf branch to avoid duplicate
1223
+ // property rendering. See issue #1218.
1224
+ const hasOneOfAnyOf = !!(mergedSchemas.oneOf || mergedSchemas.anyOf);
1225
+ const hasProperties = !!mergedSchemas.properties;
1226
+ const folded =
1227
+ hasOneOfAnyOf && hasProperties
1228
+ ? foldSiblingsIntoBranches(mergedSchemas)
1229
+ : mergedSchemas;
1230
+ const renderProperties =
1231
+ hasOneOfAnyOf && hasProperties ? false : hasProperties;
1232
+
1175
1233
  return (
1176
1234
  <div>
1177
- {mergedSchemas.oneOf && (
1235
+ {folded.oneOf && (
1178
1236
  <AnyOneOf
1179
- schema={mergedSchemas}
1237
+ schema={folded}
1180
1238
  schemaType={schemaType}
1181
1239
  schemaPath={schemaPath}
1182
1240
  />
1183
1241
  )}
1184
- {mergedSchemas.anyOf && (
1242
+ {folded.anyOf && (
1185
1243
  <AnyOneOf
1186
- schema={mergedSchemas}
1244
+ schema={folded}
1187
1245
  schemaType={schemaType}
1188
1246
  schemaPath={schemaPath}
1189
1247
  />
1190
1248
  )}
1191
- {mergedSchemas.properties && (
1249
+ {renderProperties && (
1192
1250
  <Properties
1193
1251
  schema={mergedSchemas}
1194
1252
  schemaType={schemaType}