@redocly/theme 0.62.0-next.4 → 0.62.0-next.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.
Files changed (32) hide show
  1. package/lib/components/SvgViewer/SvgViewer.d.ts +15 -0
  2. package/lib/components/SvgViewer/SvgViewer.js +312 -0
  3. package/lib/components/SvgViewer/variables.d.ts +1 -0
  4. package/lib/components/SvgViewer/variables.dark.d.ts +1 -0
  5. package/lib/components/SvgViewer/variables.dark.js +8 -0
  6. package/lib/components/SvgViewer/variables.js +17 -0
  7. package/lib/components/Tag/variables.dark.js +6 -0
  8. package/lib/components/Tag/variables.js +6 -0
  9. package/lib/core/styles/dark.js +2 -0
  10. package/lib/core/styles/global.js +2 -0
  11. package/lib/core/types/catalog.d.ts +1 -1
  12. package/lib/core/types/l10n.d.ts +1 -1
  13. package/lib/core/utils/transform-revisions-to-version-history.js +8 -51
  14. package/lib/icons/FitToViewIcon/FitToViewIcon.d.ts +9 -0
  15. package/lib/icons/FitToViewIcon/FitToViewIcon.js +25 -0
  16. package/lib/index.d.ts +2 -0
  17. package/lib/index.js +2 -0
  18. package/lib/markdoc/components/Mermaid/Mermaid.js +70 -2
  19. package/package.json +4 -4
  20. package/src/components/SvgViewer/SvgViewer.tsx +405 -0
  21. package/src/components/SvgViewer/variables.dark.ts +5 -0
  22. package/src/components/SvgViewer/variables.ts +14 -0
  23. package/src/components/Tag/variables.dark.ts +6 -0
  24. package/src/components/Tag/variables.ts +6 -0
  25. package/src/core/styles/dark.ts +2 -0
  26. package/src/core/styles/global.ts +2 -0
  27. package/src/core/types/catalog.ts +1 -1
  28. package/src/core/types/l10n.ts +7 -1
  29. package/src/core/utils/transform-revisions-to-version-history.ts +8 -80
  30. package/src/icons/FitToViewIcon/FitToViewIcon.tsx +26 -0
  31. package/src/index.ts +2 -0
  32. package/src/markdoc/components/Mermaid/Mermaid.tsx +57 -8
@@ -0,0 +1,15 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ export type SvgViewerLabels = {
3
+ zoomIn?: string;
4
+ zoomOut?: string;
5
+ fitToView?: string;
6
+ close?: string;
7
+ dialogLabel?: string;
8
+ };
9
+ export type SvgViewerProps = {
10
+ isOpen: boolean;
11
+ onClose: () => void;
12
+ children: ReactNode;
13
+ labels?: SvgViewerLabels;
14
+ };
15
+ export declare function SvgViewer({ isOpen, onClose, children, labels, }: SvgViewerProps): JSX.Element | null;
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SvgViewer = SvgViewer;
37
+ const react_1 = __importStar(require("react"));
38
+ const styled_components_1 = __importStar(require("styled-components"));
39
+ const hooks_1 = require("../../core/hooks");
40
+ const Button_1 = require("../../components/Button/Button");
41
+ const Tooltip_1 = require("../../components/Tooltip/Tooltip");
42
+ const AddIcon_1 = require("../../icons/AddIcon/AddIcon");
43
+ const SubtractIcon_1 = require("../../icons/SubtractIcon/SubtractIcon");
44
+ const CloseIcon_1 = require("../../icons/CloseIcon/CloseIcon");
45
+ const FitToViewIcon_1 = require("../../icons/FitToViewIcon/FitToViewIcon");
46
+ const MIN_SCALE_FACTOR = 0.1;
47
+ const MAX_SCALE_FACTOR = 5;
48
+ const ZOOM_STEP = 0.1;
49
+ const WHEEL_SENSITIVITY = 0.002;
50
+ const VIEWPORT_PADDING = 60;
51
+ const FIT_SCALE_FACTOR = 0.9;
52
+ function SvgViewer({ isOpen, onClose, children, labels = {}, }) {
53
+ const [scale, setScale] = (0, react_1.useState)(1);
54
+ const [baseScale, setBaseScale] = (0, react_1.useState)(1);
55
+ const [position, setPosition] = (0, react_1.useState)({ x: 0, y: 0 });
56
+ const [isDragging, setIsDragging] = (0, react_1.useState)(false);
57
+ const [dragStart, setDragStart] = (0, react_1.useState)({ x: 0, y: 0 });
58
+ const [pinchState, setPinchState] = (0, react_1.useState)(null);
59
+ const [isWheelZooming, setIsWheelZooming] = (0, react_1.useState)(false);
60
+ const wheelTimeoutRef = (0, react_1.useRef)(null);
61
+ const overlayRef = (0, react_1.useRef)(null);
62
+ const viewportRef = (0, react_1.useRef)(null);
63
+ const contentRef = (0, react_1.useRef)(null);
64
+ const renderedScaleRef = (0, react_1.useRef)(scale);
65
+ (0, hooks_1.useModalScrollLock)(isOpen);
66
+ // Keep track of the actually rendered scale for accurate measurements
67
+ (0, react_1.useLayoutEffect)(() => {
68
+ renderedScaleRef.current = scale;
69
+ }, [scale]);
70
+ const minScale = baseScale * MIN_SCALE_FACTOR;
71
+ const maxScale = baseScale * MAX_SCALE_FACTOR;
72
+ const clampScale = (0, react_1.useCallback)((value) => Math.min(maxScale, Math.max(minScale, value)), [minScale, maxScale]);
73
+ const calculateFitScale = (0, react_1.useCallback)(() => {
74
+ if (!viewportRef.current || !contentRef.current)
75
+ return 1;
76
+ const viewport = viewportRef.current.getBoundingClientRect();
77
+ const svg = contentRef.current.querySelector('svg');
78
+ if (!svg)
79
+ return 1;
80
+ const svgRect = svg.getBoundingClientRect();
81
+ if (!svgRect.width || !svgRect.height)
82
+ return 1;
83
+ // getBoundingClientRect returns transformed size, so compensate for current scale
84
+ const currentScale = renderedScaleRef.current || 1;
85
+ const naturalWidth = svgRect.width / currentScale;
86
+ const naturalHeight = svgRect.height / currentScale;
87
+ const availableWidth = viewport.width - VIEWPORT_PADDING * 2;
88
+ const availableHeight = viewport.height - VIEWPORT_PADDING * 2;
89
+ return (Math.min(availableWidth / naturalWidth, availableHeight / naturalHeight) * FIT_SCALE_FACTOR);
90
+ }, []);
91
+ const resetView = (0, react_1.useCallback)(() => {
92
+ setScale(baseScale);
93
+ setPosition({ x: 0, y: 0 });
94
+ }, [baseScale]);
95
+ const zoomIn = (0, react_1.useCallback)(() => {
96
+ setScale((s) => clampScale(s + baseScale * ZOOM_STEP));
97
+ }, [baseScale, clampScale]);
98
+ const zoomOut = (0, react_1.useCallback)(() => {
99
+ setScale((s) => clampScale(s - baseScale * ZOOM_STEP));
100
+ }, [baseScale, clampScale]);
101
+ const handleKeyDown = (0, react_1.useCallback)((e) => {
102
+ switch (e.key) {
103
+ case 'Escape':
104
+ onClose();
105
+ break;
106
+ case '+':
107
+ case '=':
108
+ zoomIn();
109
+ break;
110
+ case '-':
111
+ zoomOut();
112
+ break;
113
+ case '0':
114
+ resetView();
115
+ break;
116
+ }
117
+ }, [onClose, zoomIn, zoomOut, resetView]);
118
+ const handleWheel = (0, react_1.useCallback)((e) => {
119
+ e.preventDefault();
120
+ e.stopPropagation();
121
+ setIsWheelZooming(true);
122
+ if (wheelTimeoutRef.current)
123
+ clearTimeout(wheelTimeoutRef.current);
124
+ wheelTimeoutRef.current = setTimeout(() => setIsWheelZooming(false), 150);
125
+ const delta = -e.deltaY * WHEEL_SENSITIVITY;
126
+ setScale((s) => clampScale(s + s * delta));
127
+ }, [clampScale]);
128
+ const handleMouseDown = (0, react_1.useCallback)((e) => {
129
+ if (e.button !== 0)
130
+ return;
131
+ e.preventDefault();
132
+ setIsDragging(true);
133
+ setDragStart({ x: e.clientX - position.x, y: e.clientY - position.y });
134
+ }, [position]);
135
+ const handleMouseMove = (0, react_1.useCallback)((e) => {
136
+ if (!isDragging)
137
+ return;
138
+ setPosition({ x: e.clientX - dragStart.x, y: e.clientY - dragStart.y });
139
+ }, [isDragging, dragStart]);
140
+ const handleMouseUp = (0, react_1.useCallback)(() => setIsDragging(false), []);
141
+ const getTouchDistance = (touches) => {
142
+ if (touches.length !== 2)
143
+ return 0;
144
+ const dx = touches[0].clientX - touches[1].clientX;
145
+ const dy = touches[0].clientY - touches[1].clientY;
146
+ return Math.hypot(dx, dy);
147
+ };
148
+ const handleTouchStart = (0, react_1.useCallback)((e) => {
149
+ if (e.touches.length === 2) {
150
+ setPinchState({ distance: getTouchDistance(e.touches), scale });
151
+ }
152
+ else if (e.touches.length === 1) {
153
+ setIsDragging(true);
154
+ setDragStart({
155
+ x: e.touches[0].clientX - position.x,
156
+ y: e.touches[0].clientY - position.y,
157
+ });
158
+ }
159
+ }, [position, scale]);
160
+ const handleTouchMove = (0, react_1.useCallback)((e) => {
161
+ e.preventDefault();
162
+ if (e.touches.length === 2 && pinchState) {
163
+ const distance = getTouchDistance(e.touches);
164
+ setScale(clampScale(pinchState.scale * (distance / pinchState.distance)));
165
+ }
166
+ else if (e.touches.length === 1 && isDragging) {
167
+ setPosition({
168
+ x: e.touches[0].clientX - dragStart.x,
169
+ y: e.touches[0].clientY - dragStart.y,
170
+ });
171
+ }
172
+ }, [pinchState, isDragging, dragStart, clampScale]);
173
+ const handleTouchEnd = (0, react_1.useCallback)(() => {
174
+ setIsDragging(false);
175
+ setPinchState(null);
176
+ }, []);
177
+ (0, react_1.useEffect)(() => {
178
+ var _a;
179
+ if (!isOpen)
180
+ return;
181
+ setPosition({ x: 0, y: 0 });
182
+ (_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.focus();
183
+ // Wait for DOM to be ready before measuring
184
+ requestAnimationFrame(() => {
185
+ const fitScale = calculateFitScale();
186
+ setBaseScale(fitScale);
187
+ setScale(fitScale);
188
+ });
189
+ }, [isOpen, calculateFitScale]);
190
+ if (!isOpen)
191
+ return null;
192
+ const zoomPercentage = baseScale > 0 ? Math.round((scale / baseScale) * 100) : 100;
193
+ const isAnimating = !isDragging && !isWheelZooming && !pinchState;
194
+ return (react_1.default.createElement(Overlay, { ref: overlayRef, onClick: onClose, onKeyDown: handleKeyDown, tabIndex: 0, "aria-modal": "true", role: "dialog", "aria-label": labels.dialogLabel || 'SVG viewer' },
195
+ react_1.default.createElement(Viewport, { ref: viewportRef, onClick: (e) => e.stopPropagation(), onWheel: handleWheel, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, "$isDragging": isDragging },
196
+ react_1.default.createElement(Content, { ref: contentRef, "$isAnimating": isAnimating, style: {
197
+ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px)) scale(${scale})`,
198
+ } }, children),
199
+ react_1.default.createElement(Controls, null,
200
+ react_1.default.createElement(ControlGroup, null,
201
+ react_1.default.createElement(Tooltip_1.Tooltip, { tip: labels.zoomOut || 'Zoom out', placement: "top" },
202
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", icon: react_1.default.createElement(SubtractIcon_1.SubtractIcon, null), onClick: zoomOut, disabled: scale <= minScale })),
203
+ react_1.default.createElement(ZoomLabel, null,
204
+ zoomPercentage,
205
+ "%"),
206
+ react_1.default.createElement(Tooltip_1.Tooltip, { tip: labels.zoomIn || 'Zoom in', placement: "top" },
207
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", icon: react_1.default.createElement(AddIcon_1.AddIcon, null), onClick: zoomIn, disabled: scale >= maxScale })),
208
+ react_1.default.createElement(Divider, null),
209
+ react_1.default.createElement(Tooltip_1.Tooltip, { tip: labels.fitToView || 'Fit to view', placement: "top" },
210
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", icon: react_1.default.createElement(FitToViewIcon_1.FitToViewIcon, null), onClick: resetView })),
211
+ react_1.default.createElement(Tooltip_1.Tooltip, { tip: labels.close || 'Close', placement: "top" },
212
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", icon: react_1.default.createElement(CloseIcon_1.CloseIcon, null), onClick: onClose })))))));
213
+ }
214
+ const scaleIn = (0, styled_components_1.keyframes) `
215
+ from {
216
+ transform: scale(0.9);
217
+ }
218
+ to {
219
+ transform: scale(1);
220
+ }
221
+ `;
222
+ const slideUp = (0, styled_components_1.keyframes) `
223
+ from {
224
+ opacity: 0;
225
+ transform: translateX(-50%) translateY(10px);
226
+ }
227
+ to {
228
+ opacity: 1;
229
+ transform: translateX(-50%) translateY(0);
230
+ }
231
+ `;
232
+ const Overlay = styled_components_1.default.div `
233
+ position: fixed;
234
+ inset: 0;
235
+ background-color: var(--svg-viewer-overlay-bg-color);
236
+ backdrop-filter: blur(var(--spacing-unit));
237
+ z-index: var(--z-index-overlay, 1000);
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: center;
241
+ padding: var(--spacing-xxl);
242
+
243
+ &:focus {
244
+ outline: none;
245
+ }
246
+
247
+ @media (max-width: 768px) {
248
+ padding: var(--spacing-md);
249
+ }
250
+ `;
251
+ const Viewport = styled_components_1.default.div `
252
+ position: relative;
253
+ width: 100%;
254
+ height: 100%;
255
+ background-color: var(--svg-viewer-bg-color);
256
+ border-radius: var(--svg-viewer-border-radius);
257
+ overflow: hidden;
258
+ cursor: ${({ $isDragging }) => ($isDragging ? 'grabbing' : 'grab')};
259
+ touch-action: none;
260
+ box-shadow: var(--svg-viewer-box-shadow);
261
+ animation: ${scaleIn} 0.25s ease-in-out forwards;
262
+ `;
263
+ const Content = styled_components_1.default.div `
264
+ position: absolute;
265
+ top: 50%;
266
+ left: 50%;
267
+ transform-origin: center center;
268
+ user-select: none;
269
+ pointer-events: none;
270
+ transition: ${({ $isAnimating }) => ($isAnimating ? 'transform 0.25s ease-in-out' : 'none')};
271
+
272
+ svg {
273
+ display: block;
274
+ max-width: none !important;
275
+ }
276
+ `;
277
+ const Controls = styled_components_1.default.div `
278
+ position: absolute;
279
+ bottom: var(--spacing-sm);
280
+ left: 50%;
281
+ transform: translateX(-50%);
282
+ z-index: 10;
283
+ animation: ${slideUp} 0.3s ease-out 0.1s backwards;
284
+ `;
285
+ const ControlGroup = styled_components_1.default.div `
286
+ display: flex;
287
+ align-items: center;
288
+ gap: 2px;
289
+ padding: var(--spacing-xxs);
290
+ background: var(--bg-color-raised);
291
+ border: 1px solid var(--border-color-primary);
292
+ border-radius: var(--border-radius-lg);
293
+ box-shadow: var(--bg-raised-shadow);
294
+ `;
295
+ const ControlButton = (0, styled_components_1.default)(Button_1.Button) `
296
+ --button-icon-size: 16px;
297
+ `;
298
+ const ZoomLabel = styled_components_1.default.span `
299
+ min-width: 40px;
300
+ font-size: var(--font-size-sm);
301
+ font-weight: var(--font-weight-semibold);
302
+ color: var(--text-color-secondary);
303
+ text-align: center;
304
+ font-variant-numeric: tabular-nums;
305
+ `;
306
+ const Divider = styled_components_1.default.div `
307
+ width: 1px;
308
+ height: var(--spacing-base);
309
+ background: var(--border-color-primary);
310
+ margin: 0 var(--spacing-xxs);
311
+ `;
312
+ //# sourceMappingURL=SvgViewer.js.map
@@ -0,0 +1 @@
1
+ export declare const svgViewer: import("styled-components").FlattenSimpleInterpolation;
@@ -0,0 +1 @@
1
+ export declare const svgViewerDarkMode: import("styled-components").FlattenSimpleInterpolation;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.svgViewerDarkMode = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.svgViewerDarkMode = (0, styled_components_1.css) `
6
+ --svg-viewer-bg-color: var(--color-warm-grey-9);
7
+ `;
8
+ //# sourceMappingURL=variables.dark.js.map
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.svgViewer = void 0;
4
+ const styled_components_1 = require("styled-components");
5
+ exports.svgViewer = (0, styled_components_1.css) `
6
+ /**
7
+ * @tokens SVG Viewer
8
+ */
9
+
10
+ --svg-viewer-overlay-bg-color: var(--bg-color-modal-overlay); // @presenter Color
11
+ --svg-viewer-bg-color: var(--bg-color); // @presenter Color
12
+ --svg-viewer-border-radius: var(--border-radius-xl); // @presenter BorderRadius
13
+ --svg-viewer-box-shadow: var(--bg-raised-shadow); // @presenter BoxShadow
14
+
15
+ // @tokens End
16
+ `;
17
+ //# sourceMappingURL=variables.js.map
@@ -184,6 +184,12 @@ exports.tagDarkMode = (0, styled_components_1.css) `
184
184
  --tag-bg-color-hover: #3A465F; // @presenter Color
185
185
  }
186
186
 
187
+ .tag-query {
188
+ --tag-color: #68cc97; // @presenter Color
189
+ --tag-bg-color: #1F3D2D; // @presenter Color
190
+ --tag-bg-color-hover: #34654B; // @presenter Color
191
+ }
192
+
187
193
  .tag-put {
188
194
  --tag-color: #e0a663; // @presenter Color
189
195
  --tag-bg-color: #3D2D1B; // @presenter Color
@@ -297,6 +297,12 @@ exports.tag = (0, styled_components_1.css) `
297
297
  --tag-bg-color-hover: #CEDDFD; // @presenter Color
298
298
  }
299
299
 
300
+ .tag-query {
301
+ --tag-color: #25b869; // @presenter Color
302
+ --tag-bg-color: #e5faef; // @presenter Color
303
+ --tag-bg-color-hover: #D4F7E5; // @presenter Color
304
+ }
305
+
300
306
  .tag-put {
301
307
  --tag-color: #f5901d; // @presenter Color
302
308
  --tag-bg-color: #fef1e2; // @presenter Color
@@ -18,6 +18,7 @@ const variables_dark_13 = require("../../components/PageActions/variables.dark")
18
18
  const variables_dark_14 = require("../../components/Tooltip/variables.dark");
19
19
  const variables_dark_15 = require("../../components/Banner/variables.dark");
20
20
  const variables_dark_16 = require("../../components/Admonition/variables.dark");
21
+ const variables_dark_17 = require("../../components/SvgViewer/variables.dark");
21
22
  const replayDarkMode = (0, styled_components_1.css) `
22
23
  /**
23
24
  * @tokens Replay Colors
@@ -331,6 +332,7 @@ exports.darkMode = (0, styled_components_1.css) `
331
332
  ${variables_dark_14.tooltipDarkMode}
332
333
  ${variables_dark_15.bannerDarkMode}
333
334
  ${variables_dark_16.admonitionDarkMode}
335
+ ${variables_dark_17.svgViewerDarkMode}
334
336
 
335
337
  /**
336
338
  * @tokens Dark Theme Scrollbar Config
@@ -44,6 +44,7 @@ const variables_39 = require("../../markdoc/components/Cards/variables");
44
44
  const variables_40 = require("../../markdoc/components/CodeWalkthrough/variables");
45
45
  const variables_41 = require("../../components/SkipContent/variables");
46
46
  const variables_42 = require("../../components/PageActions/variables");
47
+ const variables_43 = require("../../components/SvgViewer/variables");
47
48
  const dark_1 = require("./dark");
48
49
  const themeColors = (0, styled_components_1.css) `
49
50
  /* === Palette === */
@@ -1296,6 +1297,7 @@ exports.styles = (0, styled_components_1.css) `
1296
1297
  ${replay}
1297
1298
  ${variables_41.skipContent}
1298
1299
  ${variables_42.pageActions}
1300
+ ${variables_43.svgViewer}
1299
1301
 
1300
1302
  background-color: var(--bg-color);
1301
1303
  color: var(--text-color-primary);
@@ -127,7 +127,7 @@ export type BffCatalogRelatedEntity = {
127
127
  key: string;
128
128
  title: string;
129
129
  summary?: string | null;
130
- readonly source: 'api' | 'file';
130
+ readonly source: 'remote' | 'file';
131
131
  relationRole: 'source' | 'target';
132
132
  relationType: EntityRelationType;
133
133
  sourceFile?: string | null;
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.tags.more' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.tags.more' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'mermaid.openFullscreen' | 'mermaid.zoomIn' | 'mermaid.zoomOut' | 'mermaid.reset' | 'mermaid.close' | 'mermaid.viewer';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -3,44 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformRevisionsToVersionHistory = transformRevisionsToVersionHistory;
4
4
  const constants_1 = require("../../core/constants");
5
5
  const date_1 = require("./date");
6
- function compareVersionsDescending(versionA, versionB) {
7
- return versionB.localeCompare(versionA, undefined, { numeric: true });
8
- }
9
- function extractGroupComparisonData(group) {
10
- var _a, _b;
11
- const version = group.version;
12
- const isNotSpecified = version === constants_1.VERSION_NOT_SPECIFIED;
13
- // Get version dates (oldest revision date for each group - the version's creation date)
14
- // This ensures versions stay in their original order even when new revisions are added
15
- const date = group.singleRevisionDate ||
16
- (group.revisions && group.revisions.length > 0
17
- ? (_a = group.revisions[group.revisions.length - 1]) === null || _a === void 0 ? void 0 : _a.revisionDate
18
- : undefined) ||
19
- '';
20
- const time = date ? new Date(date).getTime() : 0;
21
- const hasCurrent = (_b = group.hasCurrentRevisionFromBackend) !== null && _b !== void 0 ? _b : false;
22
- return { version, isNotSpecified, time, hasCurrent };
23
- }
24
- function compareVersionGroupsDescending(groupA, groupB) {
25
- const { version: versionA, isNotSpecified: isNotSpecifiedA, time: timeA, hasCurrent: hasCurrentA, } = extractGroupComparisonData(groupA);
26
- const { version: versionB, isNotSpecified: isNotSpecifiedB, time: timeB, hasCurrent: hasCurrentB, } = extractGroupComparisonData(groupB);
27
- // First, compare by version date (oldest first, so most recent versions come first)
28
- const dateComparison = timeB - timeA;
29
- if (dateComparison !== 0) {
30
- return dateComparison;
31
- }
32
- // If dates are equal, prioritize the one with isCurrent from backend
33
- if (hasCurrentA !== hasCurrentB) {
34
- return hasCurrentB ? 1 : -1; // hasCurrentB comes first if true
35
- }
36
- // If both have same isCurrent status, compare by version
37
- // If both are unknown or both are real versions, compare by version
38
- if (isNotSpecifiedA === isNotSpecifiedB) {
39
- return compareVersionsDescending(versionA, versionB);
40
- }
41
- // If one is unknown and one is a real version, unknown comes last
42
- return isNotSpecifiedA ? 1 : -1;
43
- }
44
6
  function transformRevisionsToVersionHistory({ revisions, currentRevisionDate, currentVersion, locale = typeof navigator !== 'undefined' ? navigator.language : 'en-US', }) {
45
7
  const normalizedCurrentVersion = currentVersion === null ? constants_1.VERSION_NOT_SPECIFIED : currentVersion;
46
8
  const versionMap = new Map();
@@ -54,17 +16,12 @@ function transformRevisionsToVersionHistory({ revisions, currentRevisionDate, cu
54
16
  });
55
17
  const versionGroups = Array.from(versionMap.entries()).map(([version, versionRevisions]) => {
56
18
  var _a, _b, _c;
57
- const sortedRevisions = [...versionRevisions].sort((a, b) => {
58
- const dateA = a.revision ? new Date(a.revision).getTime() : 0;
59
- const dateB = b.revision ? new Date(b.revision).getTime() : 0;
60
- return dateB - dateA;
61
- });
62
- const latestRevision = sortedRevisions[0];
19
+ const latestRevision = versionRevisions[0];
63
20
  const versionMatches = normalizedCurrentVersion === undefined || normalizedCurrentVersion === version;
64
21
  let isCurrent;
65
22
  if (currentRevisionDate !== undefined) {
66
23
  // Check if revision matches AND version matches
67
- const revisionMatches = sortedRevisions.some((rev) => rev.revision === currentRevisionDate);
24
+ const revisionMatches = versionRevisions.some((rev) => rev.revision === currentRevisionDate);
68
25
  isCurrent = revisionMatches && versionMatches;
69
26
  }
70
27
  else {
@@ -73,9 +30,9 @@ function transformRevisionsToVersionHistory({ revisions, currentRevisionDate, cu
73
30
  isCurrent = ((_a = latestRevision === null || latestRevision === void 0 ? void 0 : latestRevision.isCurrent) !== null && _a !== void 0 ? _a : false) && versionMatches;
74
31
  }
75
32
  // Check if any revision in this version group is the default version
76
- const isDefaultVersion = sortedRevisions.some((rev) => rev.isDefaultVersion === true);
77
- const revisions = sortedRevisions.length > 1
78
- ? sortedRevisions.map((rev, index) => {
33
+ const isDefaultVersion = versionRevisions.some((rev) => rev.isDefaultVersion === true);
34
+ const revisions = versionRevisions.length > 1
35
+ ? versionRevisions.map((rev, index) => {
79
36
  var _a;
80
37
  const revisionMatches = currentRevisionDate
81
38
  ? rev.revision === currentRevisionDate
@@ -86,7 +43,7 @@ function transformRevisionsToVersionHistory({ revisions, currentRevisionDate, cu
86
43
  index === 0 &&
87
44
  isCurrent;
88
45
  return {
89
- name: `r.${sortedRevisions.length - index}`,
46
+ name: `r.${versionRevisions.length - index}`,
90
47
  date: (0, date_1.toLocalizedShortDateTime)(rev.revision, locale),
91
48
  revisionDate: rev.revision,
92
49
  isActive: isActiveRevision || isCurrentByDefault,
@@ -102,9 +59,9 @@ function transformRevisionsToVersionHistory({ revisions, currentRevisionDate, cu
102
59
  hasCurrentRevisionFromBackend: (_b = latestRevision === null || latestRevision === void 0 ? void 0 : latestRevision.isCurrent) !== null && _b !== void 0 ? _b : false,
103
60
  isDefaultVersion,
104
61
  revisions,
105
- singleRevisionDate: sortedRevisions.length === 1 ? (_c = sortedRevisions[0]) === null || _c === void 0 ? void 0 : _c.revision : undefined,
62
+ singleRevisionDate: versionRevisions.length === 1 ? (_c = versionRevisions[0]) === null || _c === void 0 ? void 0 : _c.revision : undefined,
106
63
  };
107
64
  });
108
- return versionGroups.sort(compareVersionGroupsDescending);
65
+ return versionGroups;
109
66
  }
110
67
  //# sourceMappingURL=transform-revisions-to-version-history.js.map
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { IconProps } from '../../icons/types';
3
+ export declare const FitToViewIcon: import("styled-components").StyledComponent<(props: IconProps) => React.JSX.Element, any, {
4
+ 'data-component-name': string;
5
+ } & {
6
+ color?: string;
7
+ size?: string;
8
+ className?: string;
9
+ } & React.SVGProps<SVGSVGElement>, "data-component-name">;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FitToViewIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const Icon = (props) => (react_1.default.createElement("svg", Object.assign({ viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, props),
11
+ react_1.default.createElement("path", { d: "M1 1H5V2.5H2.5V5H1V1Z" }),
12
+ react_1.default.createElement("path", { d: "M15 1H11V2.5H13.5V5H15V1Z" }),
13
+ react_1.default.createElement("path", { d: "M1 15H5V13.5H2.5V11H1V15Z" }),
14
+ react_1.default.createElement("path", { d: "M15 15H11V13.5H13.5V11H15V15Z" })));
15
+ exports.FitToViewIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
16
+ 'data-component-name': 'icons/FitToViewIcon/FitToViewIcon',
17
+ })) `
18
+ path {
19
+ fill: ${({ color }) => (0, utils_1.getCssColorVariable)(color)};
20
+ }
21
+
22
+ height: ${({ size }) => size || '16px'};
23
+ width: ${({ size }) => size || '16px'};
24
+ `;
25
+ //# sourceMappingURL=FitToViewIcon.js.map