@redocly/marketing-pages 0.1.27 → 0.1.28
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/pages/editor/components/EditorPanel/EditorContent.d.ts +0 -2
- package/dist/pages/editor/components/EditorPanel/EditorContent.js +1 -1
- package/dist/pages/editor/components/EditorPanel.d.ts +0 -2
- package/dist/pages/editor/components/EditorPanel.js +1 -1
- package/dist/pages/editor/components/Layout/EditorLayout.d.ts +0 -2
- package/dist/pages/editor/components/Layout/EditorLayout.js +3 -3
- package/dist/pages/editor/components/Layout/MainLayout.d.ts +0 -2
- package/dist/pages/editor/components/Layout/MainLayout.js +10 -10
- package/dist/pages/editor/components/Page.d.ts +2 -7
- package/dist/pages/editor/components/Page.js +1 -1
- package/dist/pages/editor/components/PreviewPanel/IframeContainer.d.ts +0 -1
- package/dist/pages/editor/components/PreviewPanel/IframeContainer.js +1 -1
- package/dist/pages/editor/components/PreviewPanel/PreviewContent.js +3 -3
- package/dist/pages/editor/components/PreviewPanel.js +1 -1
- package/dist/pages/editor/editor.page.d.ts +2 -7
- package/dist/pages/editor/editor.page.js +1 -1
- package/dist/pages/editor/hooks/useEditorState.js +1 -1
- package/dist/pages/editor/hooks/useMonacoEditor.d.ts +13 -12
- package/dist/pages/editor/hooks/useMonacoEditor.js +1 -2
- package/dist/pages/editor/service/languageServer.d.ts +55 -0
- package/dist/pages/editor/service/languageServer.js +3 -0
- package/dist/pages/editor/templates/defaultOpenapiTemplate.d.ts +1 -1
- package/dist/pages/editor/templates/defaultOpenapiTemplate.js +15 -6
- package/dist/pages/editor-preview/components/Page.d.ts +2 -0
- package/dist/pages/editor-preview/components/Page.js +3 -0
- package/dist/pages/editor-preview/editor-preview.page.d.ts +2 -7
- package/dist/pages/editor-preview/editor-preview.page.js +1 -1
- package/dist/pages/editor-preview/hooks/useCommunicationManager.d.ts +1 -2
- package/dist/pages/editor-preview/hooks/useCommunicationManager.js +1 -1
- package/dist/pages/editor-preview/hooks/useDefinitionManager.js +1 -1
- package/package.json +10 -1
- package/dist/pages/editor/service/baseLanguageService.d.ts +0 -27
- package/dist/pages/editor/service/baseLanguageService.js +0 -1
- package/dist/pages/editor/service/index.d.ts +0 -3
- package/dist/pages/editor/service/index.js +0 -1
- package/dist/pages/editor/service/monacoIntegration.d.ts +0 -62
- package/dist/pages/editor/service/monacoIntegration.js +0 -2
- package/dist/pages/editor/service/yamlValidation.d.ts +0 -21
- package/dist/pages/editor/service/yamlValidation.js +0 -1
- package/dist/pages/editor/types/index.d.ts +0 -90
- package/dist/pages/editor/types/index.js +0 -0
- package/dist/pages/editor-preview/components/DocsRenderer.d.ts +0 -7
- package/dist/pages/editor-preview/components/DocsRenderer.js +0 -4
- package/dist/pages/editor-preview/components/PreviewContent.d.ts +0 -7
- package/dist/pages/editor-preview/components/PreviewContent.js +0 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
-
import { ILanguageServerService } from '../../types';
|
|
4
3
|
interface EditorContentProps {
|
|
5
|
-
languageService: ILanguageServerService;
|
|
6
4
|
value: string;
|
|
7
5
|
onChange: (value: string | undefined) => void;
|
|
8
6
|
onValidationUpdate?: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as n from"react";import
|
|
1
|
+
import*as n from"react";import d from"@monaco-editor/react";import{useMonacoEditor as p}from"../../hooks/useMonacoEditor";import{DEFAULT_EDITOR_OPTIONS as O,EDITOR_LANGUAGE as v,EDITOR_THEMES as R}from"../../constants/editorConfig";import{useEditorCommunication as T}from"../../hooks/useEditorCommunication";const b=({value:o,onChange:l,onValidationUpdate:m,hideWarnings:s,isFullPreview:f,gotoPosition:r})=>{const c=n.useRef(()=>{}),{activeColorMode:a,handleEditorDidMount:E,editorRef:e}=p({onValidationUpdate:m,hideWarnings:s,onClick:t=>{c.current(t.lineNumber)}}),{scrollPreviewToOperation:i}=T({value:o,isFullPreview:f||!1,editorRef:e});return n.useEffect(()=>{c.current=i},[i]),n.useEffect(()=>{r&&e.current&&(e.current.revealPositionInCenter({lineNumber:r.line,column:r.column}),e.current.setPosition({lineNumber:r.line,column:r.column}))},[r,e]),n.useEffect(()=>{if(!e.current)return;const t=new ResizeObserver(()=>{e.current&&e.current.layout()}),u=e.current.getDomNode();return u&&t.observe(u),()=>{t.disconnect()}},[e]),n.createElement(d,{language:v,theme:R[a],value:o,options:O,onChange:l,onMount:E})};var M=b;export{M as default};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
-
import { ILanguageServerService } from '../types';
|
|
4
3
|
interface EditorPanelProps {
|
|
5
|
-
languageService: ILanguageServerService;
|
|
6
4
|
value: string;
|
|
7
5
|
onChange: (value: string | undefined) => void;
|
|
8
6
|
onValidationUpdate?: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react";import
|
|
1
|
+
import*as e from"react";import f from"./EditorPanel/EditorContent";const u=({value:t,onChange:o,onValidationUpdate:n,hideWarnings:r,isFullPreview:i,gotoPosition:a})=>{const[l,s]=e.useState(!1);return e.useEffect(()=>s(!0),[]),l?e.createElement(f,{value:t,onChange:o,onValidationUpdate:n,hideWarnings:r,isFullPreview:i,gotoPosition:a}):e.createElement("div",{style:{height:"100%",minHeight:"400px",backgroundColor:"var(--background-color, #fff)"}})};var d=u;export{d as default};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
-
import { ILanguageServerService } from '../../types';
|
|
4
3
|
interface EditorLayoutProps {
|
|
5
|
-
languageService: ILanguageServerService;
|
|
6
4
|
value: string;
|
|
7
5
|
onChange: (value: string | undefined) => void;
|
|
8
6
|
onValidationUpdate: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"react";import a from"styled-components";import{Panel as n,PanelGroup as
|
|
1
|
+
import e from"react";import a from"styled-components";import{Panel as n,PanelGroup as z,PanelResizeHandle as h}from"react-resizable-panels";import y from"../EditorPanel";import{ProblemsPanel as k}from"../ProblemsPanel";import S from"../Toolbar";const w=({value:i,onChange:s,onValidationUpdate:d,hideWarnings:r,onHideWarningsChange:c,isFullPreview:m,gotoPosition:p,parsedErrors:u,onProblemClick:f,onFileLoad:P,onDownloadYaml:b,onDownloadJson:E,onToggleFullPreview:g})=>{const[l,t]=e.useState(!0),o=e.useRef(null),C=(v,x)=>{f(v,x),l&&o.current?.expand()};return e.createElement(R,{defaultSize:50,minSize:20},e.createElement(S,{onFileLoad:P,onDownloadYamlClick:b,onDownloadJsonClick:E,hideWarnings:r,onHideWarningsChange:c,onToggleFullPreview:g}),e.createElement(F,null,e.createElement(z,{direction:"vertical"},e.createElement(n,{defaultSize:95},e.createElement(y,{value:i,onChange:s,onValidationUpdate:d,hideWarnings:r,isFullPreview:m,gotoPosition:p})),e.createElement(h,{className:"resize-handle-horizontal",style:{display:l?"none":"block"}}),e.createElement(n,{ref:o,collapsible:!0,collapsedSize:5,defaultSize:5,minSize:20,onCollapse:t.bind(null,!0),onExpand:t.bind(null,!1)},e.createElement(k,{problems:u,onProblemClick:C,isCollapsed:l,onToggle:()=>{l?o.current?.expand():o.current?.collapse()}})))))};var J=w;const R=a(n)`
|
|
2
2
|
flex: 2;
|
|
3
3
|
display: flex;
|
|
4
4
|
flex-direction: column;
|
|
@@ -8,8 +8,8 @@ import e from"react";import a from"styled-components";import{Panel as n,PanelGro
|
|
|
8
8
|
--vscode-editor-background: var(--layer-color);
|
|
9
9
|
--vscode-editorGutter-background: var(--layer-color);
|
|
10
10
|
}
|
|
11
|
-
`,
|
|
11
|
+
`,F=a.div`
|
|
12
12
|
flex: 1;
|
|
13
13
|
min-height: 0;
|
|
14
14
|
display: flex;
|
|
15
|
-
`;export{
|
|
15
|
+
`;export{J as default};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
-
import { ILanguageServerService } from '../../types';
|
|
4
3
|
interface MainLayoutProps {
|
|
5
|
-
languageService: ILanguageServerService;
|
|
6
4
|
value: string;
|
|
7
5
|
onChange: (value: string | undefined) => void;
|
|
8
6
|
onValidationUpdate: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"react";import r from"styled-components";import{PanelGroup as w,PanelResizeHandle as P}from"react-resizable-panels";import k from"./EditorLayout";import x from"./PreviewLayout";const E=({value:a,onChange:n,onValidationUpdate:l,hideWarnings:i,onHideWarningsChange:t,isFullPreview:c,gotoPosition:s,parsedErrors:d,onProblemClick:h,onFileLoad:o,onDownloadYaml:u,onDownloadJson:m,onToggleFullPreview:g,definition:p,rawValue:v,hasRenderedOnce:b,hasStructErrors:f,onTemplateClick:z,isClient:y})=>e.createElement(C,null,e.createElement(L,{direction:"horizontal"},e.createElement(k,{value:a,onChange:n,onValidationUpdate:l,hideWarnings:i,onHideWarningsChange:t,isFullPreview:c,gotoPosition:s,parsedErrors:d,onProblemClick:h,onFileLoad:o,onDownloadYaml:u,onDownloadJson:m,onToggleFullPreview:g}),e.createElement(P,{className:"resize-handle"}),e.createElement(x,{definition:p,rawValue:v,hasRenderedOnce:b,hasStructErrors:f,onTemplateClick:z,onFileLoad:o,isClient:y})));var V=E;const C=r.div`
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
height: calc(100vh - var(--navbar-height));
|
|
@@ -9,31 +9,31 @@ import o from"react";import e from"styled-components";import{PanelGroup as k,Pan
|
|
|
9
9
|
[data-component-name='Layout/PageLayout']:has(&) + div + footer {
|
|
10
10
|
display: none;
|
|
11
11
|
}
|
|
12
|
-
`,
|
|
12
|
+
`,L=r(w)`
|
|
13
13
|
display: flex;
|
|
14
14
|
flex-grow: 1;
|
|
15
15
|
height: 100%;
|
|
16
16
|
overflow: visible;
|
|
17
17
|
|
|
18
18
|
.resize-handle {
|
|
19
|
-
width:
|
|
19
|
+
width: 4px;
|
|
20
20
|
background-color: var(--border-color-primary);
|
|
21
21
|
cursor: col-resize;
|
|
22
22
|
transition: background-color 0.2s ease;
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
25
|
+
.resize-handle[data-resize-handle-state="hover"] {
|
|
26
|
+
background-color: var(--color-blue-4);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.resize-handle-horizontal {
|
|
30
|
-
height:
|
|
30
|
+
height: 4px;
|
|
31
31
|
background-color: var(--border-color-primary);
|
|
32
32
|
cursor: row-resize;
|
|
33
33
|
transition: background-color 0.2s ease;
|
|
34
|
+
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
36
|
+
.resize-handle-horizontal[data-resize-handle-state="hover"] {
|
|
37
|
+
background-color: var(--color-blue-4);
|
|
38
38
|
}
|
|
39
39
|
`;export{V as default};
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
|
|
3
|
-
interface PageProps {
|
|
4
|
-
languageService: ILanguageServerService;
|
|
5
|
-
}
|
|
6
|
-
export default function Page({ languageService }: PageProps): React.JSX.Element;
|
|
7
|
-
export {};
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export default function Page(): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"react";import{useEditorState as L}from"../hooks/useEditorState";import{useOpenApiValidation as T}from"../hooks/useOpenApiValidation";import{useFileOperations as W}from"../hooks/useFileOperations";import H from"./Layout/MainLayout";import J from"./Layout/FullPreviewLayout";function Y(){const[r,p]=e.useState(!1),[s,d]=e.useState(!1);e.useEffect(()=>p(!0),[]);const{value:o,setValue:u,validatedValue:w,setValidatedValue:C,setValidationErrors:c,setFileName:E,parsedErrors:F,hasStructErrors:a,hideWarnings:P,setHideWarnings:g}=L(),{definition:t,hasRenderedOnce:f,setHasRenderedOnce:V}=T({validatedValue:w,hasStructErrors:a}),m=e.useRef(null);e.useEffect(()=>{t&&(m.current=t)},[t]);const h=t||m.current,[v,D]=e.useState(null),n=W({setValue:u,setFileName:E,setHasRenderedOnce:V,setValidationErrors:c}),R=(i,l)=>{c(i),C(l)},O=(i,l)=>{D({line:i,column:l})},S=()=>n.handleDownloadYaml(o),k=()=>n.handleDownloadJson(o);return s?e.createElement(J,{definition:h,rawValue:o,hasRenderedOnce:f,hasStructErrors:a,onTemplateClick:n.handleTemplateClick,onFileLoad:n.handleFileLoad,onExitFullPreview:()=>d(!1),isClient:r}):e.createElement(H,{value:o,onChange:u,onValidationUpdate:R,hideWarnings:P,onHideWarningsChange:g,isFullPreview:s,gotoPosition:v,parsedErrors:F,onProblemClick:O,onFileLoad:n.handleFileLoad,onDownloadYaml:S,onDownloadJson:k,onToggleFullPreview:()=>d(!0),definition:h,rawValue:o,hasRenderedOnce:f,hasStructErrors:a,onTemplateClick:n.handleTemplateClick,isClient:r})}export{Y as default};
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
interface IframeContainerProps {
|
|
3
3
|
definition: any | null;
|
|
4
4
|
onIframeReady: (iframeWindow: Window) => void;
|
|
5
|
-
onMessage: (event: MessageEvent) => void;
|
|
6
5
|
}
|
|
7
6
|
declare const IframeContainer: React.FC<IframeContainerProps>;
|
|
8
7
|
export default IframeContainer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import o,{useRef as c,useEffect as a}from"react";import u from"styled-components";const d=({definition:t,onIframeReady:s
|
|
1
|
+
import o,{useRef as c,useEffect as a}from"react";import u from"styled-components";const d=({definition:t,onIframeReady:s})=>{const l=c(null),r=c(null),[i,w]=o.useState(0);return a(()=>{const n=e=>{r.current=e,e.updateDefinition(t),s(e)};return window.onReady=n,()=>{delete window.onReady}},[t,s]),a(()=>{const n=e=>{e.data?.type==="scroll-to-operation"&&r.current&&r.current.postMessage(e.data,"*")};return window.addEventListener("message",n),()=>window.removeEventListener("message",n)},[]),a(()=>{r.current&&t&&r.current.updateDefinition(t)},[t]),o.createElement(f,null,o.createElement(m,{key:i,ref:l,title:"API Documentation Preview",src:"/preview",onLoad:()=>{}}))};var y=d;const f=u.div`
|
|
2
2
|
height: 100%;
|
|
3
3
|
overflow: hidden;
|
|
4
4
|
`,m=u.iframe`
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import e from"react";import t from"styled-components";import{Button as f}from"@redocly/theme/components/Button/Button";import{Tooltip as s}from"@redocly/theme/components/Tooltip/Tooltip";import{ViewOffIcon as d}from"@redocly/theme/icons/ViewOffIcon/ViewOffIcon";import l from"./ErrorOverlay";import E from"./IframeContainer";import u from"../EmptyState";const
|
|
1
|
+
import e from"react";import t from"styled-components";import{Button as f}from"@redocly/theme/components/Button/Button";import{Tooltip as s}from"@redocly/theme/components/Tooltip/Tooltip";import{ViewOffIcon as d}from"@redocly/theme/icons/ViewOffIcon/ViewOffIcon";import l from"./ErrorOverlay";import E from"./IframeContainer";import u from"../EmptyState";const x=({definition:n,rawValue:o,hasStructErrors:r,onTemplateClick:m,onFileLoad:p,onExitFullPreview:i,onIframeReady:c})=>!o||typeof o!="string"||o.trim()===""?e.createElement(u,{onTemplateClick:m,onUploadClick:p}):n?e.createElement(a,null,e.createElement(l,{hasStructErrors:r}),i&&e.createElement(y,null,e.createElement(g,{tip:"Exit full preview mode",width:"fit-content",placement:"right"},e.createElement(f,{variant:"secondary",onClick:i,"aria-label":"Exit full preview",icon:e.createElement(d,null)}))),e.createElement(E,{definition:n,onIframeReady:c})):e.createElement(a,null,e.createElement(l,{hasStructErrors:r}),e.createElement(v,null,"Loading..."));var w=x;const a=t.div`
|
|
2
2
|
position: relative;
|
|
3
3
|
height: 100%;
|
|
4
|
-
`,
|
|
4
|
+
`,y=t.div`
|
|
5
5
|
position: absolute;
|
|
6
6
|
top: 12px;
|
|
7
7
|
left: 12px;
|
|
8
8
|
z-index: 100;
|
|
9
|
-
`,
|
|
9
|
+
`,g=t(s)`
|
|
10
10
|
[data-component-name='Tooltip/Tooltip'] {
|
|
11
11
|
z-index: 101 !important;
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as e from"react";import m from"./PreviewPanel/PreviewContent";const c=({definition:r,rawValue:a,hasStructErrors:t,onTemplateClick:o,onFileLoad:n,onExitFullPreview:i})=>{const l=e.useCallback(d=>{},[]);return e.createElement(m,{definition:r??"",rawValue:a,hasStructErrors:t,onTemplateClick:o,onFileLoad:n,onExitFullPreview:i,onIframeReady:l})};var s=c;export{s as default};
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ILanguageServerService } from './types';
|
|
1
|
+
import Page from './components/Page';
|
|
3
2
|
export declare const frontmatter: {
|
|
4
3
|
seo: {
|
|
5
4
|
title: string;
|
|
6
5
|
};
|
|
7
6
|
slug: string;
|
|
8
7
|
};
|
|
9
|
-
|
|
10
|
-
languageService: ILanguageServerService;
|
|
11
|
-
}
|
|
12
|
-
export default function EditorPage({ languageService }: EditorPageProps): React.JSX.Element;
|
|
13
|
-
export {};
|
|
8
|
+
export default Page;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import t from"
|
|
1
|
+
import t from"./components/Page";const o={seo:{title:"Swagger Editor"},slug:"/editor"};var r=t;export{r as default,o as frontmatter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useEffect as
|
|
1
|
+
import{useEffect as S,useMemo as o,useState as e}from"react";function h(){const l=typeof localStorage<"u"&&localStorage.getItem("editorValue")||"",[a,n]=e(l),[i,u]=e(void 0),[r,c]=e([]),[d,m]=e(""),[f,V]=e(!1),g=/Rule: ([\w-_\/]+)/,s=o(()=>r.map(t=>({...t,rule:t.message.match(g)?.[1]})),[r]),E=o(()=>s.some(t=>t.rule==="struct"),[s]);return S(()=>{localStorage.setItem("editorValue",a)},[a]),{value:a,setValue:n,validatedValue:i,setValidatedValue:u,validationErrors:r,setValidationErrors:c,fileName:d,setFileName:m,hideWarnings:f,setHideWarnings:V,parsedErrors:s,hasStructErrors:E}}export{h as useEditorState};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
export interface MonacoEditorHook {
|
|
3
|
+
editorRef: React.MutableRefObject<Monaco.editor.IStandaloneCodeEditor | null>;
|
|
4
|
+
monacoRef: React.MutableRefObject<typeof Monaco | null>;
|
|
5
|
+
activeColorMode: string;
|
|
6
|
+
handleEditorDidMount: (editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco) => () => void;
|
|
7
|
+
}
|
|
3
8
|
export interface MonacoEditorOptions {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
onClick?: (position: Position) => void;
|
|
9
|
+
onValidationUpdate?: (errors: Monaco.editor.IMarkerData[], value: string) => void;
|
|
10
|
+
onClick?: (position: Monaco.Position) => void;
|
|
7
11
|
hideWarnings?: boolean;
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
handleEditorDidMount: (editor: editor.IStandaloneCodeEditor, monaco: any) => (() => void);
|
|
14
|
-
handleEditorBeforeMount: (monaco: any) => void;
|
|
15
|
-
};
|
|
13
|
+
/**
|
|
14
|
+
* Custom hook to manage Monaco editor integration with language server and scroll sync
|
|
15
|
+
*/
|
|
16
|
+
export declare const useMonacoEditor: (options?: MonacoEditorOptions) => MonacoEditorHook;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{useEffect as
|
|
2
|
-
`))&&setTimeout(()=>{const t=e.getPosition();try{const a=e.getModel();if(a&&n.current){const C=a.getLanguageId();n.current.editor.setModelLanguage(a,"plaintext"),setTimeout(()=>{n.current.editor.setModelLanguage(a,C),t&&e.setPosition(t)},10)}}catch{e.render(),e.layout(),t&&e.setPosition(t)}},0)});e._contentChangeDisposable=u}return setTimeout(()=>{if(e.layout(),s){const u=s.getValue();s.setValue(u),e.render()}},100),setTimeout(()=>{e.layout(),e.render()},500),()=>{d(),e._contentChangeDisposable&&e._contentChangeDisposable.dispose()}};return b(()=>{o.current?.setupAutoValidation(l,c)},[c]),{editorRef:i,monacoRef:n,activeColorMode:M,handleEditorDidMount:h,handleEditorBeforeMount:e=>{}}}export{x as useMonacoEditor};
|
|
1
|
+
import{useEffect as m,useRef as t}from"react";import{useColorMode as M}from"./useColorMode";import{LanguageServerService as g}from"../service/languageServer";const C=(a={})=>{const{onValidationUpdate:r,onClick:l,hideWarnings:e}=a,i=t(null),u=t(null),o=t(null),s=M(),d=(n,c)=>{i.current=n,u.current=c,o.current||(o.current=new g),o.current.initialize(n,c);const f=o.current.setupAutoValidation(r,e);return n.onMouseDown(({target:p})=>{l?.(p.position)}),()=>{f()}};return m(()=>{o.current?.setupAutoValidation(r,e)},[e]),{editorRef:i,monacoRef:u,activeColorMode:s,handleEditorDidMount:d}};export{C as useMonacoEditor};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
export interface LSPosition {
|
|
3
|
+
line: number;
|
|
4
|
+
character: number;
|
|
5
|
+
}
|
|
6
|
+
export interface DocumentProvider {
|
|
7
|
+
_lineOffsets: number[];
|
|
8
|
+
getText: (options?: {
|
|
9
|
+
start?: number;
|
|
10
|
+
end?: number;
|
|
11
|
+
}) => string;
|
|
12
|
+
offsetAt: (position: LSPosition) => number;
|
|
13
|
+
positionAt: (offset: number) => LSPosition;
|
|
14
|
+
lineCount: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ValidationCallback {
|
|
17
|
+
(errors: Monaco.editor.IMarkerData[], value: string): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Service class to handle OpenAPI Language Server integration
|
|
21
|
+
*/
|
|
22
|
+
export declare class LanguageServerService {
|
|
23
|
+
private languageServer;
|
|
24
|
+
private monaco;
|
|
25
|
+
private editor;
|
|
26
|
+
constructor();
|
|
27
|
+
/**
|
|
28
|
+
* Initialize the language server with Monaco editor instance
|
|
29
|
+
*/
|
|
30
|
+
initialize(editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco): void;
|
|
31
|
+
/**
|
|
32
|
+
* Register documents provider for the language server
|
|
33
|
+
*/
|
|
34
|
+
private registerDocumentsProvider;
|
|
35
|
+
/**
|
|
36
|
+
* Create document provider for current editor content
|
|
37
|
+
*/
|
|
38
|
+
private createDocumentProvider;
|
|
39
|
+
/**
|
|
40
|
+
* Register completion item provider
|
|
41
|
+
*/
|
|
42
|
+
private registerCompletionProvider;
|
|
43
|
+
/**
|
|
44
|
+
* Register definition provider
|
|
45
|
+
*/
|
|
46
|
+
private registerDefinitionProvider;
|
|
47
|
+
/**
|
|
48
|
+
* Get OpenAPI validation diagnostics
|
|
49
|
+
*/
|
|
50
|
+
validateContent(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Setup automatic validation on content changes
|
|
53
|
+
*/
|
|
54
|
+
setupAutoValidation(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): () => void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{OpenapiLanguageServer as d,languageServerConfig as g}from"@redocly/openapi-language-server";import{load as h}from"js-yaml";g.registerConfigFinder(async u=>(typeof globalThis.process>"u"?globalThis.process={cwd:()=>"/"}:typeof globalThis.process.cwd>"u"&&(globalThis.process.cwd=()=>"/"),"config"));class v{constructor(){this.monaco=null,this.editor=null,this.languageServer=new d}initialize(r,t){this.editor=r,this.monaco=t,globalThis.__dirname=".",this.registerDocumentsProvider(),this.languageServer.onDidConfigChange("config"),this.registerCompletionProvider(),this.registerDefinitionProvider()}registerDocumentsProvider(){g.registerDocumentsProvider({all(){return[]},get:r=>r==="config"||r==="file:///config"?{getText:()=>JSON.stringify({extends:["recommended"]},null,2)}:this.createDocumentProvider()})}createDocumentProvider(){const r=this.editor?.getModel();return{_lineOffsets:[],get lineCount(){return r?.getLineCount()||0},getText:({start:t=0,end:e=void 0}={})=>(this.editor?.getModel()?.getValue()||"").slice(t,e),offsetAt(t){const e=this.getText();this._lineOffsets=[0];for(let i=0;i<e.length;i++)e[i]===`
|
|
2
|
+
`&&this._lineOffsets.push(i+1);return r?r.getOffsetAt({lineNumber:t.line+1,column:t.character+1}):0},positionAt:t=>{if(!r)return{line:1,character:1};const e=r.getPositionAt(t);return{line:e.lineNumber,character:e.column}}}}registerCompletionProvider(){this.monaco&&this.monaco.languages.registerCompletionItemProvider("yaml",{triggerCharacters:[" ",`
|
|
3
|
+
`,"\\","/",'"',"'"],provideCompletionItems:async(r,t)=>{const e={uri:r.uri.toString()},i=m(t),l=await this.languageServer.onCompletion({textDocument:e,position:i});return l?{suggestions:l.map(n=>{let a=1;n.insertTextFormat===2&&(a=2);let s;return a===2&&(s=this.monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet),{label:n.label,kind:this.monaco.languages.CompletionItemKind[n.kind]||this.monaco.languages.CompletionItemKind.Text,insertText:n.insertText||n.label,insertTextFormat:a,sortText:n.sortText,insertTextRules:s,range:new this.monaco.Range(t.lineNumber,t.column,t.lineNumber,t.column)}})}:{suggestions:[]}}})}registerDefinitionProvider(){this.monaco&&this.monaco.languages.registerDefinitionProvider("yaml",{provideDefinition:async(r,t)=>{const e={uri:r.uri.toString()},i=m(t),l=await this.languageServer.onDefinition({textDocument:e,position:i});return l?(Array.isArray(l)?l:[l]).map(n=>({uri:this.monaco.Uri.parse(n.targetUri),originSelectionRange:new this.monaco.Range(n.originSelectionRange.start.line+1,n.originSelectionRange.start.character+1,n.originSelectionRange.end.line+1,n.originSelectionRange.end.character+1),range:new this.monaco.Range(n.targetSelectionRange.start.line+1,n.targetSelectionRange.start.character+1,n.targetSelectionRange.end.line+1,n.targetSelectionRange.end.character+1)})):[]}})}async validateContent(r,t){if(!this.editor||!this.monaco)return;const e=this.editor.getModel();if(!e)return;const i=e.getValue(),l={uri:e.uri.toString(),languageId:"yaml",version:e.getVersionId(),getText:()=>i,positionAt:a=>{const s=e.getPositionAt(a);return{line:s.lineNumber-1,character:s.column-1}},offsetAt:a=>e.getOffsetAt({lineNumber:a.line+1,column:a.character+1}),lineCount:e.getLineCount()},n={1:this.monaco.MarkerSeverity.Error,2:this.monaco.MarkerSeverity.Warning,3:this.monaco.MarkerSeverity.Info,4:this.monaco.MarkerSeverity.Hint};try{const s=(await this.languageServer.validateOpenAPI(l)).flatMap(o=>o.diagnostics.map(c=>({severity:n[c.severity]||this.monaco.MarkerSeverity.Error,startLineNumber:c.range.start.line+1,startColumn:c.range.start.character+1,endLineNumber:c.range.end.line+1,endColumn:c.range.end.character+1,message:c.message,source:""}))).filter(o=>t?o.severity!==this.monaco.MarkerSeverity.Warning:!0).sort((o,c)=>c.severity-o.severity);try{const o=h(i);i.trim()!==""&&(typeof o!="object"||o===null||(o.openapi===void 0||!o.openapi.match(/^3\.[0,1]\.\d+$/))&&(o.swagger===void 0||!o.swagger.match(/^2\.[0,1]\.\d+$/)))&&s.push({severity:8,message:"Not an OpenAPI or Swagger specification. Only OpenAPI 3.0.x and Swagger 2.0.x are supported. Rule: struct",startLineNumber:1,startColumn:1,endLineNumber:1,endColumn:1e3})}catch(o){s.push({severity:8,message:o.reason+" Rule: struct",startLineNumber:o.mark?.line||1,startColumn:0,endLineNumber:o.mark?.line||1,endColumn:1e3})}this.monaco.editor.setModelMarkers(e,"openapi-ls",s),r&&r(s,i)}catch(a){console.error("Error during validation:",a)}}setupAutoValidation(r,t){if(!this.editor)return()=>{};const e=()=>this.validateContent(r,t);e();const i=this.editor.onDidChangeModelContent(()=>{e()});return()=>i.dispose()}}function m(u){return{line:u.lineNumber-1,character:u.column-1}}export{v as LanguageServerService};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const defaultOpenapiTemplate = "openapi: 3.1.0\ninfo:\n title: Sample API\n version: 1.0.0\n description: |\n Welcome to the Resources API, a robust and efficient service for managing your data.\n ### Overview\n This API provides a standard set of RESTful endpoints to perform CRUD (Create, Read, Update, Delete) operations on resources. It is designed with standard conventions to be predictable and easy to use.\n ### Authentication\n Most endpoints are protected using the **OAuth2 Client Credentials** flow. The `/health` endpoint is public.\n `Authorization: Bearer <YOUR_ACCESS_TOKEN>`\n ### Errors\n The API uses standard HTTP status codes to indicate the success or failure of a request. In the event of an error, the response body will contain a `problem+json` object with details.\n For more information, see our [full developer documentation](https://docs.example.com).\nservers:\n - url: http://api.example.com/v1\ntags:\n - name: Health\n description: Operations to check the health of the service.\n - name: Resources\n description: Operations to manage resources.\nsecurity:\n -
|
|
1
|
+
export declare const defaultOpenapiTemplate = "openapi: 3.1.0\ninfo:\n title: Sample API\n version: 1.0.0\n contact:\n email: team@redocly.com\n description: |\n Welcome to the Resources API, a robust and efficient service for managing your data.\n ### Overview\n This API provides a standard set of RESTful endpoints to perform CRUD (Create, Read, Update, Delete) operations on resources. It is designed with standard conventions to be predictable and easy to use.\n ### Authentication\n Most endpoints are protected using the **OAuth2 Client Credentials** flow. The `/health` endpoint is public.\n `Authorization: Bearer <YOUR_ACCESS_TOKEN>`\n ### Errors\n The API uses standard HTTP status codes to indicate the success or failure of a request. In the event of an error, the response body will contain a `problem+json` object with details.\n For more information, see our [full developer documentation](https://docs.example.com).\nservers:\n - url: http://api.example.com/v1\ntags:\n - name: Health\n description: Operations to check the health of the service.\n - name: Resources\n description: Operations to manage resources.\nsecurity:\n - OAuth2AuthCode:\n - resources:read\n - resources:write\npaths:\n /health:\n get:\n tags:\n - Health\n summary: Check service health\n description: Provides a simple way to check if the API is up and running.\n operationId: getHealth\n security: [] # public\n responses:\n '200':\n description: Service is healthy.\n content:\n application/json:\n schema:\n type: object\n properties:\n status:\n type: string\n example: ok\n '503':\n description: Service unavailable.\n content:\n application/problem+json:\n schema:\n $ref: '#/components/schemas/ProblemJson'\n /resources:\n get:\n tags:\n - Resources\n summary: List all resources\n description: Retrieves a paginated list of all resources, sorted by creation date in descending order.\n operationId: listResources\n parameters:\n - $ref: '#/components/parameters/Limit'\n - $ref: '#/components/parameters/Cursor'\n responses:\n '200':\n description: A paginated list of resources.\n content:\n application/json:\n schema:\n type: object\n properties:\n pageInfo:\n $ref: '#/components/schemas/PageInfo'\n data:\n type: array\n items:\n $ref: '#/components/schemas/Resource'\n post:\n tags:\n - Resources\n summary: Create a new resource\n description: Creates a new resource. The server generates the ID and creation timestamp.\n operationId: createResource\n requestBody:\n required: true\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Resource'\n responses:\n '201':\n description: Resource created successfully.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Resource'\n '400':\n description: Bad request.\n content:\n application/problem+json:\n schema:\n $ref: '#/components/schemas/ProblemJson'\n /resources/{resourceId}:\n parameters:\n - name: resourceId\n in: path\n required: true\n description: The ID of the resource.\n schema:\n type: string\n format: uuid\n get:\n tags:\n - Resources\n summary: Get a single resource\n operationId: getResourceById\n description: Retrieves the details of a specific resource by its unique ID.\n responses:\n '200':\n description: The requested resource.\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Resource'\n '404':\n description: Resource not found.\n content:\n application/problem+json:\n schema:\n $ref: '#/components/schemas/ProblemJson'\n delete:\n tags:\n - Resources\n summary: Delete a resource\n operationId: deleteResourceById\n description: Permanently deletes a resource. This action cannot be undone.\n responses:\n '204':\n description: Resource deleted successfully.\n '404':\n description: Resource not found.\n content:\n application/problem+json:\n schema:\n $ref: '#/components/schemas/ProblemJson'\n\ncomponents:\n securitySchemes:\n OAuth2AuthCode:\n type: oauth2\n description: OAuth2 Client Credentials Grant.\n flows:\n authorizationCode:\n x-usePkce: true\n tokenUrl: https://auth.example.com/oauth2/token\n authorizationUrl: https://auth.example.com/oauth2/authorize\n scopes:\n resources:read: Read access to resources\n resources:write: Write and delete access to resources\n parameters:\n Limit:\n name: limit\n in: query\n description: The number of items to return per page.\n schema:\n type: integer\n format: int32\n default: 20\n minimum: 1\n maximum: 100\n Cursor:\n name: cursor\n in: query\n description: An opaque cursor for fetching the next page of results.\n schema:\n type: string\n schemas:\n PageInfo:\n type: object\n properties:\n hasNextPage:\n type: boolean\n description: Indicates if there are more pages of results.\n endCursor:\n type: string\n description: The cursor to use to fetch the next page of results.\n required:\n - hasNextPage\n Resource:\n type: object\n properties:\n id:\n type: string\n format: uuid\n description: The unique identifier for the resource.\n example: 'a7b3c2d9-e4f5-4a6b-8c7d-1e2f3a4b5c6d'\n readOnly: true\n name:\n type: string\n description: The name of the resource.\n example: My New Widget\n createdAt:\n type: string\n format: date-time\n description: The timestamp when the resource was created.\n example: '2025-10-09T13:31:23Z'\n readOnly: true\n required:\n - name\n ProblemJson:\n type: object\n description: A problem details object as defined in RFC 9457.\n properties:\n type:\n type: string\n format: uri\n description: An absolute URI that identifies the problem type.\n default: 'about:blank'\n example: /errors/resource-not-found\n title:\n type: string\n description: A short, human-readable summary of the problem type.\n example: Resource not found\n status:\n type: integer\n format: int32\n description: The HTTP status code.\n example: 404\n detail:\n type: string\n description: A human-readable explanation specific to this occurrence.\n example: The resource with ID xyz was not found.\n instance:\n type: string\n format: uri-reference\n description: A URI reference that identifies the specific occurrence of the problem.\n example: /resources/xyz\n required:\n - title\n - status\n";
|
|
@@ -2,6 +2,8 @@ const e=`openapi: 3.1.0
|
|
|
2
2
|
info:
|
|
3
3
|
title: Sample API
|
|
4
4
|
version: 1.0.0
|
|
5
|
+
contact:
|
|
6
|
+
email: team@redocly.com
|
|
5
7
|
description: |
|
|
6
8
|
Welcome to the Resources API, a robust and efficient service for managing your data.
|
|
7
9
|
### Overview
|
|
@@ -20,7 +22,7 @@ tags:
|
|
|
20
22
|
- name: Resources
|
|
21
23
|
description: Operations to manage resources.
|
|
22
24
|
security:
|
|
23
|
-
-
|
|
25
|
+
- OAuth2AuthCode:
|
|
24
26
|
- resources:read
|
|
25
27
|
- resources:write
|
|
26
28
|
paths:
|
|
@@ -29,6 +31,7 @@ paths:
|
|
|
29
31
|
tags:
|
|
30
32
|
- Health
|
|
31
33
|
summary: Check service health
|
|
34
|
+
description: Provides a simple way to check if the API is up and running.
|
|
32
35
|
operationId: getHealth
|
|
33
36
|
security: [] # public
|
|
34
37
|
responses:
|
|
@@ -53,6 +56,7 @@ paths:
|
|
|
53
56
|
tags:
|
|
54
57
|
- Resources
|
|
55
58
|
summary: List all resources
|
|
59
|
+
description: Retrieves a paginated list of all resources, sorted by creation date in descending order.
|
|
56
60
|
operationId: listResources
|
|
57
61
|
parameters:
|
|
58
62
|
- $ref: '#/components/parameters/Limit'
|
|
@@ -75,6 +79,7 @@ paths:
|
|
|
75
79
|
tags:
|
|
76
80
|
- Resources
|
|
77
81
|
summary: Create a new resource
|
|
82
|
+
description: Creates a new resource. The server generates the ID and creation timestamp.
|
|
78
83
|
operationId: createResource
|
|
79
84
|
requestBody:
|
|
80
85
|
required: true
|
|
@@ -109,6 +114,7 @@ paths:
|
|
|
109
114
|
- Resources
|
|
110
115
|
summary: Get a single resource
|
|
111
116
|
operationId: getResourceById
|
|
117
|
+
description: Retrieves the details of a specific resource by its unique ID.
|
|
112
118
|
responses:
|
|
113
119
|
'200':
|
|
114
120
|
description: The requested resource.
|
|
@@ -127,6 +133,7 @@ paths:
|
|
|
127
133
|
- Resources
|
|
128
134
|
summary: Delete a resource
|
|
129
135
|
operationId: deleteResourceById
|
|
136
|
+
description: Permanently deletes a resource. This action cannot be undone.
|
|
130
137
|
responses:
|
|
131
138
|
'204':
|
|
132
139
|
description: Resource deleted successfully.
|
|
@@ -139,12 +146,14 @@ paths:
|
|
|
139
146
|
|
|
140
147
|
components:
|
|
141
148
|
securitySchemes:
|
|
142
|
-
|
|
149
|
+
OAuth2AuthCode:
|
|
143
150
|
type: oauth2
|
|
144
151
|
description: OAuth2 Client Credentials Grant.
|
|
145
152
|
flows:
|
|
146
|
-
|
|
153
|
+
authorizationCode:
|
|
154
|
+
x-usePkce: true
|
|
147
155
|
tokenUrl: https://auth.example.com/oauth2/token
|
|
156
|
+
authorizationUrl: https://auth.example.com/oauth2/authorize
|
|
148
157
|
scopes:
|
|
149
158
|
resources:read: Read access to resources
|
|
150
159
|
resources:write: Write and delete access to resources
|
|
@@ -200,7 +209,7 @@ components:
|
|
|
200
209
|
- name
|
|
201
210
|
ProblemJson:
|
|
202
211
|
type: object
|
|
203
|
-
description: A problem details object
|
|
212
|
+
description: A problem details object as defined in RFC 9457.
|
|
204
213
|
properties:
|
|
205
214
|
type:
|
|
206
215
|
type: string
|
|
@@ -219,8 +228,8 @@ components:
|
|
|
219
228
|
example: 404
|
|
220
229
|
detail:
|
|
221
230
|
type: string
|
|
222
|
-
description: A human-readable explanation specific to this occurrence
|
|
223
|
-
example: The resource with ID
|
|
231
|
+
description: A human-readable explanation specific to this occurrence.
|
|
232
|
+
example: The resource with ID xyz was not found.
|
|
224
233
|
instance:
|
|
225
234
|
type: string
|
|
226
235
|
format: uri-reference
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{useCommunicationManager as o}from"../hooks/useCommunicationManager";import r from"styled-components";import*as e from"react";import{RedoclyOpenAPIDocs as a,safeSlugify as s}from"@redocly/openapi-docs";function f(){const[t,i]=e.useState(null);return o({definition:t,safeSlugify:s}),e.useEffect(()=>{window.updateDefinition=n=>{i(n)},window.parent.onReady(window)},[t]),t?e.createElement(l,null,e.createElement(a,{store:{options:{routingBasePath:"/preview",disableRouter:!0,hideSidebar:!0,scrollYOffset:0,hideInfoMetadata:!0},definition:t}})):e.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh",fontFamily:"system-ui, -apple-system, sans-serif",color:"#666"}},"No API definition available")}const l=r.div`
|
|
2
|
+
--sidebar-width: 0px;
|
|
3
|
+
`;export{f as default};
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
RedoclyOpenAPIDocs: any;
|
|
4
|
-
safeSlugify: (value: string) => string;
|
|
5
|
-
}
|
|
6
|
-
export default function Page({ RedoclyOpenAPIDocs, safeSlugify }: PageProps): React.JSX.Element;
|
|
7
|
-
export {};
|
|
1
|
+
import Page from './components/Page';
|
|
2
|
+
export default Page;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"./components/Page";var r=e;export{r as default};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
interface UseCommunicationManagerProps {
|
|
2
2
|
definition: any;
|
|
3
|
-
lastGoodDefinition: any;
|
|
4
3
|
safeSlugify: (value: string) => string;
|
|
5
4
|
}
|
|
6
|
-
export declare const useCommunicationManager: ({ definition,
|
|
5
|
+
export declare const useCommunicationManager: ({ definition, safeSlugify }: UseCommunicationManagerProps) => {
|
|
7
6
|
scrollToPointer: (pointer: string) => void;
|
|
8
7
|
scrollToOperationInEditor: (path: string, method?: string) => void;
|
|
9
8
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useEffect as l}from"react";import{extractOperationFromButton as
|
|
1
|
+
import{useEffect as l}from"react";import{extractOperationFromButton as E}from"../utils/html";const L=({definition:f,safeSlugify:d})=>{const s=t=>{const e=f;if(!e?.paths){console.warn("[EditorPreview] No definition or paths available");return}let o="",n="";if(t.startsWith("#/")){const a=t.slice(2).split("/");n=a[2]||"",o=(a[1]||"").replaceAll("~1","/")}else{const a=t.split("/"),w=a[1]||"";n=a[2]||"",o=w.replace(/^paths/,"").replaceAll("~1","/")}if(!o||!n){console.warn("[EditorPreview] Invalid pointer format:",t);return}const r=e.paths[o]?.[n];if(!r){console.warn("[EditorPreview] No operation found for",{path:o,verb:n,pointer:t});return}const m=r.tags?.[0],v=m?d(m)+"/":"";let i="";if(r?.operationId?i="/preview/"+v+d(r.operationId):i="/preview/"+v+"paths/"+d(o)+"/"+n.toLowerCase(),i&&i!==window.location.pathname){window.history.replaceState({},"",i);const a=n.toLowerCase(),w=o,P=()=>{const g=document.querySelectorAll('button[data-component-name="Button/Button"]');for(const c of g){const u=E(c);if(u&&u.path===w&&u.method.toLowerCase()===a)return c.click(),!0}return!1};let p=P();p||[0,100,300,800].forEach(c=>{setTimeout(()=>{p||(p=P())},c)})}else i||console.warn("[EditorPreview] could not compute url for pointer:",t)},h=(t,e)=>{let o=t;e&&(o=`#/paths/${t.replace(/\//g,"~1")}/${e.toLowerCase()}`),window.parent.postMessage({type:"scroll-to-operation",operationPath:o,source:"preview"},"*")};return l(()=>{try{window.parent&&typeof window.parent.onReady=="function"?window.parent.onReady(window):(console.warn("[EditorPreview] Parent onReady not available, retrying..."),setTimeout(()=>{window.parent&&typeof window.parent.onReady=="function"?window.parent.onReady(window):console.error("[EditorPreview] Failed to register with parent window")},100))}catch(t){console.error("[EditorPreview] Error registering with parent:",t)}},[]),l(()=>(window.scrollToPointer=s,()=>{delete window.scrollToPointer}),[f]),l(()=>{const t=e=>{e.data?.type==="scroll-to-operation"&&e.data?.source==="editor"&&s(e.data.operationPath)};return window.addEventListener("message",t),()=>{window.removeEventListener("message",t)}},[s]),l(()=>{const t=e=>{const n=e.target.closest("button");if(n){const r=E(n);r&&h(r.path,r.method)}};return document.addEventListener("click",t),()=>{document.removeEventListener("click",t)}},[]),{scrollToPointer:s,scrollToOperationInEditor:h}};export{L as useCommunicationManager};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useState as
|
|
1
|
+
import{useState as i,useRef as l,useEffect as p}from"react";const y=()=>{const[f,o]=i(null),s=l(null),n=l(null),c=e=>{try{const r={...e};return Array.isArray(r.servers)&&(r.servers=r.servers.filter(t=>t&&typeof t=="object").filter(t=>typeof t.url=="string"&&t.url.trim().length>0)),r}catch{return e}},a=e=>{const r=e&&typeof e=="object"&&typeof e.openapi=="string",t=e&&typeof e=="object"&&typeof e.swagger=="string";if(r||t){const u=c(e);s.current=u,o(u)}else s.current?n.current!==s.current&&o(s.current):o(null);n.current=e};return p(()=>(window.updateDefinition=a,()=>{delete window.updateDefinition}),[]),{definition:f,lastGoodDefinition:s.current}};export{y as useDefinitionManager};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/marketing-pages",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"keywords": [],
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"@monaco-editor/react": "^4.7.0",
|
|
27
27
|
"@rebilly/lead-source-tracker": "^2.18.13",
|
|
28
28
|
"@redocly/json-to-json-schema": "^0.0.1",
|
|
29
|
+
"@redocly/openapi-docs": "^3.14.1",
|
|
29
30
|
"@redocly/openapi-language-server": "^0.6.9",
|
|
30
31
|
"@uiw/react-codemirror": "^4.23.12",
|
|
31
32
|
"dayjs": "^1.11.13",
|
|
@@ -73,5 +74,13 @@
|
|
|
73
74
|
"react-dom": "^18.3.1",
|
|
74
75
|
"styled-components": ">=5.3.11",
|
|
75
76
|
"typescript": "^5.8.3"
|
|
77
|
+
},
|
|
78
|
+
"overrides": {
|
|
79
|
+
"@redocly/openapi-docs": {
|
|
80
|
+
"@redocly/theme": "$@redocly/theme",
|
|
81
|
+
"@markdoc/markdoc": "$@markdoc/markdoc",
|
|
82
|
+
"react": "$react",
|
|
83
|
+
"react-dom": "$react-dom"
|
|
84
|
+
}
|
|
76
85
|
}
|
|
77
86
|
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
-
import { ValidationCallback } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* Base language service with Monaco editor integration
|
|
5
|
-
* This handles all browser-compatible logic
|
|
6
|
-
*/
|
|
7
|
-
export declare abstract class BaseLanguageService {
|
|
8
|
-
protected monaco: typeof Monaco | null;
|
|
9
|
-
protected editor: Monaco.editor.IStandaloneCodeEditor | null;
|
|
10
|
-
/**
|
|
11
|
-
* Initialize the language server with Monaco editor instance
|
|
12
|
-
*/
|
|
13
|
-
initialize(editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco): void;
|
|
14
|
-
/**
|
|
15
|
-
* Validate content and return diagnostics
|
|
16
|
-
* Subclasses should override this to add their own validation
|
|
17
|
-
*/
|
|
18
|
-
protected getValidationDiagnostics(model: Monaco.editor.ITextModel): Promise<Monaco.editor.IMarkerData[]>;
|
|
19
|
-
/**
|
|
20
|
-
* Validate content with YAML and custom validation
|
|
21
|
-
*/
|
|
22
|
-
validateContent(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): Promise<void>;
|
|
23
|
-
/**
|
|
24
|
-
* Setup automatic validation on content changes
|
|
25
|
-
*/
|
|
26
|
-
setupAutoValidation(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): () => void;
|
|
27
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{validateYAML as c,createYAMLErrorMarker as d}from"./yamlValidation";class g{constructor(){this.monaco=null,this.editor=null}initialize(t,e){this.editor=t,this.monaco=e,typeof globalThis.__dirname>"u"&&(globalThis.__dirname=".")}async getValidationDiagnostics(t){return[]}async validateContent(t,e){if(!this.editor||!this.monaco)return;const i=this.editor.getModel();if(!i)return;const o=i.getValue();try{const r=(await this.getValidationDiagnostics(i)).filter(n=>e?n.severity!==this.monaco.MarkerSeverity.Warning:!0).sort((n,l)=>l.severity-n.severity),s=c(o);!s.isValid&&s.error&&r.push(d(s.error,this.monaco)),this.monaco.editor.setModelMarkers(i,"language-service",r),t&&t(r,o)}catch(a){console.error("Error during validation:",a)}}setupAutoValidation(t,e){if(!this.editor)return()=>{};const i=()=>this.validateContent(t,e);i();const o=this.editor.onDidChangeModelContent(()=>{i()});return()=>{o.dispose()}}}export{g as BaseLanguageService};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export*from"./baseLanguageService";export*from"./monacoIntegration";export*from"./yamlValidation";
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
-
/**
|
|
3
|
-
* Monaco-specific utilities that don't depend on language server
|
|
4
|
-
*/
|
|
5
|
-
export interface LSPosition {
|
|
6
|
-
line: number;
|
|
7
|
-
character: number;
|
|
8
|
-
}
|
|
9
|
-
export interface DocumentProvider {
|
|
10
|
-
_lineOffsets: number[];
|
|
11
|
-
getText: (options?: {
|
|
12
|
-
start?: number;
|
|
13
|
-
end?: number;
|
|
14
|
-
}) => string;
|
|
15
|
-
offsetAt: (position: LSPosition) => number;
|
|
16
|
-
positionAt: (offset: number) => LSPosition;
|
|
17
|
-
lineCount: number;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Create document provider for Monaco editor content
|
|
21
|
-
*/
|
|
22
|
-
export declare function createDocumentProvider(editor: Monaco.editor.IStandaloneCodeEditor | null): DocumentProvider & {
|
|
23
|
-
_lineOffsets: number[];
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Map language server severity to Monaco severity
|
|
27
|
-
*/
|
|
28
|
-
export declare function mapSeverityToMonaco(severity: number, monaco: typeof Monaco): Monaco.MarkerSeverity;
|
|
29
|
-
/**
|
|
30
|
-
* Convert language server position to Monaco position
|
|
31
|
-
*/
|
|
32
|
-
export declare function lsPositionToMonaco(position: {
|
|
33
|
-
line: number;
|
|
34
|
-
character: number;
|
|
35
|
-
}): {
|
|
36
|
-
lineNumber: number;
|
|
37
|
-
column: number;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Convert Monaco position to language server position
|
|
41
|
-
*/
|
|
42
|
-
export declare function monacoPositionToLS(position: Monaco.IPosition): {
|
|
43
|
-
line: number;
|
|
44
|
-
character: number;
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* Convert language server range to Monaco range
|
|
48
|
-
*/
|
|
49
|
-
export declare function lsRangeToMonaco(range: {
|
|
50
|
-
start: {
|
|
51
|
-
line: number;
|
|
52
|
-
character: number;
|
|
53
|
-
};
|
|
54
|
-
end: {
|
|
55
|
-
line: number;
|
|
56
|
-
character: number;
|
|
57
|
-
};
|
|
58
|
-
}, monaco: typeof Monaco): Monaco.Range;
|
|
59
|
-
/**
|
|
60
|
-
* Map completion item kind from language server to Monaco
|
|
61
|
-
*/
|
|
62
|
-
export declare function mapCompletionKind(kind: any, monaco: typeof Monaco): Monaco.languages.CompletionItemKind;
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function o(e){const t=e?.getModel();return{_lineOffsets:[],get lineCount(){return t?.getLineCount()||0},getText:({start:r=0,end:n=void 0}={})=>(e?.getModel()?.getValue()||"").slice(r,n),offsetAt(r){const n=this.getText();this._lineOffsets=[0];for(let i=0;i<n.length;i++)n[i]===`
|
|
2
|
-
`&&this._lineOffsets.push(i+1);return t?t.getOffsetAt({lineNumber:r.line+1,column:r.character+1}):0},positionAt:r=>{if(!t)return{line:1,character:1};const n=t.getPositionAt(r);return{line:n.lineNumber,character:n.column}}}}function u(e,t){return{1:t.MarkerSeverity.Error,2:t.MarkerSeverity.Warning,3:t.MarkerSeverity.Info,4:t.MarkerSeverity.Hint}[e]||t.MarkerSeverity.Error}function l(e){return{lineNumber:e.line+1,column:e.character+1}}function a(e){return{line:e.lineNumber-1,character:e.column-1}}function c(e,t){return new t.Range(e.start.line+1,e.start.character+1,e.end.line+1,e.end.character+1)}function s(e,t){return t.languages.CompletionItemKind[e]||t.languages.CompletionItemKind.Text}export{o as createDocumentProvider,l as lsPositionToMonaco,c as lsRangeToMonaco,s as mapCompletionKind,u as mapSeverityToMonaco,a as monacoPositionToLS};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
-
export interface YAMLValidationResult {
|
|
3
|
-
isValid: boolean;
|
|
4
|
-
error?: {
|
|
5
|
-
message: string;
|
|
6
|
-
line: number;
|
|
7
|
-
column: number;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Parse YAML and validate it's a valid OpenAPI/Swagger specification
|
|
12
|
-
*/
|
|
13
|
-
export declare function validateYAML(content: string): YAMLValidationResult;
|
|
14
|
-
/**
|
|
15
|
-
* Create Monaco marker from YAML validation error
|
|
16
|
-
*/
|
|
17
|
-
export declare function createYAMLErrorMarker(error: {
|
|
18
|
-
message: string;
|
|
19
|
-
line: number;
|
|
20
|
-
column: number;
|
|
21
|
-
}, monaco: typeof Monaco): Monaco.editor.IMarkerData;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{load as n}from"js-yaml";function t(r){try{const e=n(r);return r.trim()===""?{isValid:!0}:typeof e!="object"||e===null||(e.openapi===void 0||!e.openapi.match(/^3\.[0,1]\.\d+$/))&&(e.swagger===void 0||!e.swagger.match(/^2\.[0,1]\.\d+$/))?{isValid:!1,error:{message:"Not an OpenAPI or Swagger specification. Only OpenAPI 3.0.x and Swagger 2.0.x are supported. Rule: struct",line:1,column:1}}:{isValid:!0}}catch(e){return{isValid:!1,error:{message:(e.reason||e.message)+" Rule: struct",line:e.mark?.line||1,column:e.mark?.column||0}}}}function i(r,e){return{severity:e.MarkerSeverity.Error,message:r.message,startLineNumber:r.line,startColumn:r.column,endLineNumber:r.line,endColumn:1e3}}export{i as createYAMLErrorMarker,t as validateYAML};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
-
export interface EditorPosition {
|
|
3
|
-
line: number;
|
|
4
|
-
column: number;
|
|
5
|
-
}
|
|
6
|
-
export interface EditorValidationUpdate {
|
|
7
|
-
errors: Monaco.editor.IMarkerData[];
|
|
8
|
-
value: string | undefined;
|
|
9
|
-
}
|
|
10
|
-
export interface PreviewDefinition {
|
|
11
|
-
[key: string]: any;
|
|
12
|
-
}
|
|
13
|
-
export interface PreviewPanelProps {
|
|
14
|
-
definition: PreviewDefinition | null;
|
|
15
|
-
rawValue: string;
|
|
16
|
-
hasRenderedOnce: boolean;
|
|
17
|
-
hasStructErrors: boolean;
|
|
18
|
-
onTemplateClick: () => void;
|
|
19
|
-
onFileLoad: (content: string, fileName: string) => void;
|
|
20
|
-
onExitFullPreview?: () => void;
|
|
21
|
-
}
|
|
22
|
-
export interface FileOperations {
|
|
23
|
-
handleTemplateClick: () => void;
|
|
24
|
-
handleFileLoad: (content: string, fileName: string) => void;
|
|
25
|
-
handleDownloadYaml: (value: string) => void;
|
|
26
|
-
handleDownloadJson: (value: string) => void;
|
|
27
|
-
}
|
|
28
|
-
export interface LayoutProps {
|
|
29
|
-
isClient: boolean;
|
|
30
|
-
}
|
|
31
|
-
export interface EditorLayoutProps extends LayoutProps {
|
|
32
|
-
value: string;
|
|
33
|
-
onChange: (value: string | undefined) => void;
|
|
34
|
-
onValidationUpdate: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
35
|
-
hideWarnings: boolean;
|
|
36
|
-
onHideWarningsChange: (hide: boolean) => void;
|
|
37
|
-
isFullPreview: boolean;
|
|
38
|
-
gotoPosition: EditorPosition | null;
|
|
39
|
-
parsedErrors: Monaco.editor.IMarkerData[];
|
|
40
|
-
onProblemClick: (line: number, column: number) => void;
|
|
41
|
-
onFileLoad: (content: string, fileName: string) => void;
|
|
42
|
-
onDownloadYaml: () => void;
|
|
43
|
-
onDownloadJson: () => void;
|
|
44
|
-
onToggleFullPreview: () => void;
|
|
45
|
-
}
|
|
46
|
-
export interface PreviewLayoutProps extends LayoutProps {
|
|
47
|
-
definition: PreviewDefinition | null;
|
|
48
|
-
rawValue: string;
|
|
49
|
-
hasRenderedOnce: boolean;
|
|
50
|
-
hasStructErrors: boolean;
|
|
51
|
-
onTemplateClick: () => void;
|
|
52
|
-
onFileLoad: (content: string, fileName: string) => void;
|
|
53
|
-
}
|
|
54
|
-
export interface FullPreviewLayoutProps extends PreviewLayoutProps {
|
|
55
|
-
onExitFullPreview: () => void;
|
|
56
|
-
}
|
|
57
|
-
export interface ScrollToOperationMessage {
|
|
58
|
-
type: 'scroll-to-operation';
|
|
59
|
-
operationPath: string;
|
|
60
|
-
source: 'editor' | 'preview';
|
|
61
|
-
}
|
|
62
|
-
export interface OperationPath {
|
|
63
|
-
path: string;
|
|
64
|
-
verb: string;
|
|
65
|
-
pointer: string;
|
|
66
|
-
}
|
|
67
|
-
export interface ValidationCallback {
|
|
68
|
-
(errors: Monaco.editor.IMarkerData[], value: string): void;
|
|
69
|
-
}
|
|
70
|
-
export interface ILanguageServerService {
|
|
71
|
-
/**
|
|
72
|
-
* Initialize the language server with Monaco editor instance
|
|
73
|
-
* @param editor - Monaco editor instance
|
|
74
|
-
* @param monaco - Monaco editor API
|
|
75
|
-
*/
|
|
76
|
-
initialize(editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco): void;
|
|
77
|
-
/**
|
|
78
|
-
* Validate OpenAPI content and provide diagnostics
|
|
79
|
-
* @param onValidationUpdate - Optional callback for validation updates
|
|
80
|
-
* @param hideWarnings - Whether to hide warnings from validation results
|
|
81
|
-
*/
|
|
82
|
-
validateContent(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* Setup automatic validation on content changes
|
|
85
|
-
* @param onValidationUpdate - Optional callback for validation updates
|
|
86
|
-
* @param hideWarnings - Whether to hide warnings from validation results
|
|
87
|
-
* @returns Cleanup function to dispose the validation listener
|
|
88
|
-
*/
|
|
89
|
-
setupAutoValidation(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): () => void;
|
|
90
|
-
}
|
|
File without changes
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import e from"react";import i from"styled-components";const m=({RedoclyOpenAPIDocs:o,definition:t})=>{const r=e.useMemo(()=>({options:{routingBasePath:"/preview",disableRouter:!0,hideSidebar:!0},definition:t}),[t]);return e.createElement(n,null,e.createElement(o,{router:"memory",withCommonStyles:!0,store:r}))};var a=m;const n=i.div`
|
|
2
|
-
height: 100vh;
|
|
3
|
-
overflow: auto;
|
|
4
|
-
`;export{a as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import t from"react";import{useThemeManager as i}from"../hooks/useThemeManager";import{useDefinitionManager as m}from"../hooks/useDefinitionManager";import{useCommunicationManager as a}from"../hooks/useCommunicationManager";import f from"./DocsRenderer";import c from"./EmptyState";const p=({RedoclyOpenAPIDocs:o,safeSlugify:r})=>{i();const{definition:e,lastGoodDefinition:n}=m();return a({definition:e,lastGoodDefinition:n,safeSlugify:r}),e?t.createElement(f,{RedoclyOpenAPIDocs:o,definition:e}):t.createElement(c,null)};var E=p;export{E as default};
|