@digi-frontend/dgate-api-documentation 4.2.3 → 4.2.5

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/dist/index.cjs CHANGED
@@ -704,6 +704,99 @@ const getSidebarStyles$1 = (token, scope) => ({
704
704
  }
705
705
  });
706
706
  //#endregion
707
+ //#region src/view/helper/patch-endpoint.ts
708
+ /** Convert an editor ParameterFormValues into an OpenAPI request Parameter. */
709
+ const toOpenApiParam = (p) => ({
710
+ name: p.name,
711
+ in: p.in,
712
+ required: p.required,
713
+ ...p.description ? { description: p.description } : {},
714
+ schema: {
715
+ type: p.type,
716
+ ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
717
+ }
718
+ });
719
+ /** Convert editor response ParameterFormValues into an OpenAPI response headers map. */
720
+ const toResponseHeaders = (params) => params.reduce((acc, p) => {
721
+ acc[p.name] = {
722
+ schema: {
723
+ type: p.type,
724
+ ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
725
+ },
726
+ required: p.required,
727
+ ...p.description ? { description: p.description } : {}
728
+ };
729
+ return acc;
730
+ }, {});
731
+ /**
732
+ * Apply the local (unsaved) edits for a single endpoint onto a clone of the
733
+ * stored endpoint. Absent edits fall back to the endpoint's existing value, so
734
+ * unedited fields are never wiped.
735
+ */
736
+ const buildPatchedEndpoint = (ep, edits) => {
737
+ const localName = edits.names[ep.id];
738
+ const localDesc = edits.descs[ep.id];
739
+ const localTags = edits.tags[ep.id];
740
+ const localParams = edits.params[ep.id];
741
+ const localResponseParams = edits.responseParams[ep.id];
742
+ const localResponseBody = edits.responseBody[ep.id];
743
+ const parameters = localParams !== void 0 ? localParams.map(toOpenApiParam) : ep.parameters;
744
+ const responseHeadersMap = localResponseParams && localResponseParams.length > 0 ? toResponseHeaders(localResponseParams) : null;
745
+ const responses = Object.fromEntries(Object.entries(ep.responses ?? {}).map(([code, resp]) => {
746
+ const patchedExample = localResponseBody?.[code];
747
+ const existingJson = resp.content?.["application/json"];
748
+ const content = patchedExample !== void 0 ? {
749
+ ...resp.content,
750
+ "application/json": {
751
+ ...existingJson ?? { schema: {} },
752
+ example: patchedExample
753
+ }
754
+ } : resp.content;
755
+ return [code, {
756
+ ...resp,
757
+ headers: responseHeadersMap ?? resp.headers,
758
+ ...content ? { content } : {}
759
+ }];
760
+ }));
761
+ const tags = localTags ?? ep.tags;
762
+ return {
763
+ ...ep,
764
+ summary: localName !== void 0 ? localName : ep.summary,
765
+ description: localDesc !== void 0 ? localDesc : ep.description,
766
+ tags,
767
+ parameters,
768
+ responses
769
+ };
770
+ };
771
+ /**
772
+ * Build a fully-patched copy of `selectedApi` that reflects all unsaved local
773
+ * edits, so View-mode surfaces (API page cards, endpoint detail, Codebox,
774
+ * sidebar tree) preview changes before saving. Endpoints are re-grouped under
775
+ * their edited primary tag. Returns the same `selectedApi` reference when no
776
+ * edit changes the result, to keep memo consumers stable.
777
+ */
778
+ const buildPatchedApi = (selectedApi, edits) => {
779
+ const patchedTags = {};
780
+ Object.entries(selectedApi.tags ?? {}).forEach(([bucketKey, endpoints]) => {
781
+ endpoints.forEach((ep) => {
782
+ const patched = buildPatchedEndpoint(ep, edits);
783
+ const newKey = edits.tags[ep.id]?.[0] ?? ep.tagName ?? bucketKey;
784
+ const endpoint = newKey === patched.tagName ? patched : {
785
+ ...patched,
786
+ tagName: newKey
787
+ };
788
+ (patchedTags[newKey] ??= []).push(endpoint);
789
+ });
790
+ });
791
+ const patched = {
792
+ ...selectedApi,
793
+ title: edits.apiTitle ?? selectedApi.title,
794
+ description: edits.apiDescription ?? selectedApi.description,
795
+ tags: patchedTags
796
+ };
797
+ return JSON.stringify(patched) === JSON.stringify(selectedApi) ? selectedApi : patched;
798
+ };
799
+ //#endregion
707
800
  //#region src/utils/OverflowTooltip.tsx
708
801
  const OverflowTooltip = ({ title, children, className, style, placement }) => {
709
802
  const ref = (0, react.useRef)(null);
@@ -1697,9 +1790,10 @@ const APIPage = ({ apiOverride }) => {
1697
1790
  if (selectedApi?.servers && !selectedUrl) setSelectedUrl(selectedApi?.servers?.[0].url);
1698
1791
  }, [selectedApi?.servers]);
1699
1792
  const getEndpointsForSelectedUrl = () => {
1700
- if (!selectedApi) return {};
1701
- const tags = selectedApi.tags || {};
1702
- const curl = selectedApi.curl || [];
1793
+ const api = apiOverride ?? selectedApi;
1794
+ if (!api) return {};
1795
+ const tags = api.tags || {};
1796
+ const curl = api.curl || [];
1703
1797
  const filtered = {};
1704
1798
  Object.keys(tags).forEach((tagKey) => {
1705
1799
  filtered[tagKey] = tags[tagKey].map((endpoint) => {
@@ -3384,6 +3478,7 @@ const AddParameterDrawer = ({ open, onClose, onAdd, onEdit, mode = "add", initia
3384
3478
  //#endregion
3385
3479
  //#region src/view/components/ApiPage/components/EndpointsSection.tsx
3386
3480
  const { useBreakpoint: useBreakpoint$2 } = antd.Grid;
3481
+ const ucFirst = (s) => s.charAt(0).toUpperCase() + s.slice(1);
3387
3482
  const PAGE_SIZE = 4;
3388
3483
  const VIEW_PAGE_SIZE = 4;
3389
3484
  const getStatusCodeColor = (code, token) => {
@@ -3754,6 +3849,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
3754
3849
  alignItems: "center",
3755
3850
  justifyContent: "space-between",
3756
3851
  width: "100%",
3852
+ gap: 16,
3757
3853
  padding: `12px 0px`,
3758
3854
  borderBottom: `1px solid ${token.colorBorderSecondary}`,
3759
3855
  background: token.colorBgContainer,
@@ -4089,7 +4185,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4089
4185
  background: token.colorBgElevated,
4090
4186
  borderRadius: token.borderRadius,
4091
4187
  paddingTop: 16,
4092
- paddingBottom: 16,
4188
+ paddingBottom: 32,
4093
4189
  gap: 8,
4094
4190
  display: "flex",
4095
4191
  flexDirection: "column",
@@ -4561,7 +4657,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4561
4657
  children: "Parameter In"
4562
4658
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4563
4659
  className: cx("param-detail-value"),
4564
- children: param.in
4660
+ children: ucFirst(param.in)
4565
4661
  })]
4566
4662
  })]
4567
4663
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4640,7 +4736,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4640
4736
  children: "Parameter In"
4641
4737
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4642
4738
  className: cx("param-detail-value"),
4643
- children: param.in
4739
+ children: ucFirst(param.in)
4644
4740
  })]
4645
4741
  }),
4646
4742
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4650,7 +4746,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
4650
4746
  children: "Parameter Type"
4651
4747
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4652
4748
  className: cx("param-detail-value"),
4653
- children: param.type
4749
+ children: ucFirst(param.type)
4654
4750
  })]
4655
4751
  }),
4656
4752
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5048,7 +5144,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5048
5144
  children: "Parameter In"
5049
5145
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5050
5146
  className: cx("param-detail-value"),
5051
- children: param.in
5147
+ children: ucFirst(param.in)
5052
5148
  })]
5053
5149
  })]
5054
5150
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5127,7 +5223,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5127
5223
  children: "Parameter In"
5128
5224
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5129
5225
  className: cx("param-detail-value"),
5130
- children: param.in
5226
+ children: ucFirst(param.in)
5131
5227
  })]
5132
5228
  }),
5133
5229
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5137,7 +5233,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5137
5233
  children: "Parameter Type"
5138
5234
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5139
5235
  className: cx("param-detail-value"),
5140
- children: param.type
5236
+ children: ucFirst(param.type)
5141
5237
  })]
5142
5238
  }),
5143
5239
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5868,7 +5964,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5868
5964
  children: "Parameter In"
5869
5965
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5870
5966
  className: cx("param-detail-value"),
5871
- children: param.in
5967
+ children: ucFirst(param.in)
5872
5968
  })]
5873
5969
  })]
5874
5970
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5943,7 +6039,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5943
6039
  children: "Parameter In"
5944
6040
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5945
6041
  className: cx("param-detail-value"),
5946
- children: param.in
6042
+ children: ucFirst(param.in)
5947
6043
  })]
5948
6044
  }),
5949
6045
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -5953,7 +6049,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
5953
6049
  children: "Parameter Type"
5954
6050
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5955
6051
  className: cx("param-detail-value"),
5956
- children: param.type
6052
+ children: ucFirst(param.type)
5957
6053
  })]
5958
6054
  }),
5959
6055
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -6347,7 +6443,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
6347
6443
  children: "Parameter In"
6348
6444
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6349
6445
  className: cx("param-detail-value"),
6350
- children: param.in
6446
+ children: ucFirst(param.in)
6351
6447
  })]
6352
6448
  })]
6353
6449
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -6422,7 +6518,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
6422
6518
  children: "Parameter In"
6423
6519
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6424
6520
  className: cx("param-detail-value"),
6425
- children: param.in
6521
+ children: ucFirst(param.in)
6426
6522
  })]
6427
6523
  }),
6428
6524
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -6432,7 +6528,7 @@ const EndpointsSection = ({ endpointsByTag, collapsed = false, onToggleCollapse,
6432
6528
  children: "Parameter Type"
6433
6529
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6434
6530
  className: cx("param-detail-value"),
6435
- children: param.type
6531
+ children: ucFirst(param.type)
6436
6532
  })]
6437
6533
  }),
6438
6534
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -9281,17 +9377,27 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
9281
9377
  const viewModeApi = (0, react$1.useMemo)(() => {
9282
9378
  if (!selectedApi) return null;
9283
9379
  if (mode !== "view") return selectedApi;
9284
- if (localApiName === selectedApi.title && localDescription === selectedApi.description) return selectedApi;
9285
- return {
9286
- ...selectedApi,
9287
- title: localApiName,
9288
- description: localDescription
9289
- };
9380
+ return buildPatchedApi(selectedApi, {
9381
+ apiTitle: localApiName,
9382
+ apiDescription: localDescription,
9383
+ names: endpointNames,
9384
+ descs: endpointDescs,
9385
+ tags: endpointTags,
9386
+ params: endpointParams,
9387
+ responseParams: endpointResponseParams,
9388
+ responseBody: endpointResponseBody
9389
+ });
9290
9390
  }, [
9291
9391
  mode,
9292
9392
  selectedApi,
9293
9393
  localApiName,
9294
- localDescription
9394
+ localDescription,
9395
+ endpointNames,
9396
+ endpointDescs,
9397
+ endpointTags,
9398
+ endpointParams,
9399
+ endpointResponseParams,
9400
+ endpointResponseBody
9295
9401
  ]);
9296
9402
  (0, react$1.useEffect)(() => {
9297
9403
  return () => {
@@ -9617,58 +9723,32 @@ const ConsoleDocumentationLayout = ({ data, preSelectedApi, handleVisitLandingPa
9617
9723
  setBannerVisible(hasChanges);
9618
9724
  }, [hasChanges]);
9619
9725
  (0, react$1.useEffect)(() => {
9620
- if (mode !== "view" || !selectedEndpoint) return;
9621
- const epId = selectedEndpoint.id;
9622
- const localName = endpointNames[epId];
9623
- const localDesc = endpointDescs[epId];
9624
- const localEpTags = endpointTags[epId];
9625
- const patchedSummary = localName !== void 0 && localName !== selectedEndpoint.summary ? localName : selectedEndpoint.summary;
9626
- const patchedDesc = localDesc !== void 0 && localDesc !== selectedEndpoint.description ? localDesc : selectedEndpoint.description;
9627
- const patchedTags = localEpTags !== void 0 && JSON.stringify(localEpTags) !== JSON.stringify(selectedEndpoint.tags ?? []) ? localEpTags : selectedEndpoint.tags;
9628
- const openApiParams = (endpointParams[epId] ?? []).map((p) => ({
9629
- name: p.name,
9630
- in: p.in,
9631
- required: p.required,
9632
- ...p.description ? { description: p.description } : {},
9633
- schema: {
9634
- type: p.type,
9635
- ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
9636
- }
9637
- }));
9638
- const responseHeadersMap = (endpointResponseParams[epId] ?? []).reduce((acc, p) => {
9639
- acc[p.name] = {
9640
- schema: {
9641
- type: p.type,
9642
- ...p.enum && p.enum.length > 0 ? { enum: p.enum } : {}
9643
- },
9644
- required: p.required,
9645
- ...p.description ? { description: p.description } : {}
9646
- };
9647
- return acc;
9648
- }, {});
9649
- const patchedResponses = Object.fromEntries(Object.entries(selectedEndpoint.responses ?? {}).map(([code, resp]) => [code, {
9650
- ...resp,
9651
- headers: Object.keys(responseHeadersMap).length > 0 ? responseHeadersMap : resp.headers
9652
- }]));
9653
- if (selectedEndpoint.summary === patchedSummary && selectedEndpoint.description === patchedDesc && JSON.stringify(selectedEndpoint.tags ?? []) === JSON.stringify(patchedTags ?? []) && JSON.stringify(selectedEndpoint.parameters ?? []) === JSON.stringify(openApiParams) && JSON.stringify(selectedEndpoint.responses) === JSON.stringify(patchedResponses)) return;
9726
+ if (mode !== "view" || !selectedEndpoint || !viewModeApi) return;
9727
+ const patched = Object.values(viewModeApi.tags ?? {}).flat().find((e) => e.id === selectedEndpoint.id);
9728
+ if (!patched) return;
9729
+ if (selectedEndpoint.summary === patched.summary && selectedEndpoint.description === patched.description && JSON.stringify(selectedEndpoint.tags ?? []) === JSON.stringify(patched.tags ?? []) && JSON.stringify(selectedEndpoint.parameters ?? []) === JSON.stringify(patched.parameters ?? []) && JSON.stringify(selectedEndpoint.responses) === JSON.stringify(patched.responses)) return;
9654
9730
  setSelectedEndpoint({
9655
- ...selectedEndpoint,
9656
- summary: patchedSummary,
9657
- description: patchedDesc,
9658
- tags: patchedTags,
9659
- parameters: openApiParams,
9660
- responses: patchedResponses
9731
+ ...patched,
9732
+ parentApiId: selectedEndpoint.parentApiId
9661
9733
  });
9662
9734
  }, [
9663
9735
  mode,
9664
9736
  selectedEndpoint,
9665
- endpointNames,
9666
- endpointDescs,
9667
- endpointTags,
9668
- endpointParams,
9669
- endpointResponseParams,
9737
+ viewModeApi,
9670
9738
  setSelectedEndpoint
9671
9739
  ]);
9740
+ (0, react$1.useEffect)(() => {
9741
+ if (!selectedApi || !transformedData?.length) return;
9742
+ const rebuilt = buildTreeDataStructure(mode === "view" && viewModeApi ? transformedData.map((api) => api.contextPath === selectedApi.contextPath ? viewModeApi : api) : transformedData);
9743
+ if (JSON.stringify(rebuilt) !== JSON.stringify(builtTreeData)) setBuiltTreeData(rebuilt);
9744
+ }, [
9745
+ mode,
9746
+ viewModeApi,
9747
+ transformedData,
9748
+ selectedApi,
9749
+ builtTreeData,
9750
+ setBuiltTreeData
9751
+ ]);
9672
9752
  const handleAddTag = (tag) => {
9673
9753
  const newTag = {
9674
9754
  name: tag.name,