@redocly/marketing-pages 0.1.16 → 0.1.18

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 (37) hide show
  1. package/dist/pages/editor/components/EditorPanel.d.ts +14 -0
  2. package/dist/pages/editor/components/EditorPanel.js +1 -0
  3. package/dist/pages/editor/components/EmptyState.d.ts +7 -0
  4. package/dist/pages/editor/components/EmptyState.js +31 -0
  5. package/dist/pages/editor/components/Page.d.ts +2 -0
  6. package/dist/pages/editor/components/Page.js +59 -0
  7. package/dist/pages/editor/components/PreviewPanel.d.ts +11 -0
  8. package/dist/pages/editor/components/PreviewPanel.js +20 -0
  9. package/dist/pages/editor/components/ProblemsPanel.d.ts +10 -0
  10. package/dist/pages/editor/components/ProblemsPanel.js +71 -0
  11. package/dist/pages/editor/components/Toolbar.d.ts +10 -0
  12. package/dist/pages/editor/components/Toolbar.js +50 -0
  13. package/dist/pages/editor/constants/editorConfig.d.ts +7 -0
  14. package/dist/pages/editor/constants/editorConfig.js +1 -0
  15. package/dist/pages/editor/editor.page.d.ts +8 -0
  16. package/dist/pages/editor/editor.page.js +1 -0
  17. package/dist/pages/editor/hooks/useColorMode.d.ts +1 -0
  18. package/dist/pages/editor/hooks/useColorMode.js +1 -0
  19. package/dist/pages/editor/hooks/useEditorState.d.ts +18 -0
  20. package/dist/pages/editor/hooks/useEditorState.js +1 -0
  21. package/dist/pages/editor/hooks/useFileOperations.d.ts +13 -0
  22. package/dist/pages/editor/hooks/useFileOperations.js +1 -0
  23. package/dist/pages/editor/hooks/useMonacoEditor.d.ts +12 -0
  24. package/dist/pages/editor/hooks/useMonacoEditor.js +1 -0
  25. package/dist/pages/editor/hooks/useOpenApiValidation.d.ts +14 -0
  26. package/dist/pages/editor/hooks/useOpenApiValidation.js +1 -0
  27. package/dist/pages/editor/services/languageServerService.d.ts +52 -0
  28. package/dist/pages/editor/services/languageServerService.js +3 -0
  29. package/dist/pages/editor/templates/defaultOpenapiTemplate.d.ts +1 -0
  30. package/dist/pages/editor/templates/defaultOpenapiTemplate.js +22 -0
  31. package/dist/pages/editor/utils/download.d.ts +1 -0
  32. package/dist/pages/editor/utils/download.js +1 -0
  33. package/dist/pages/editor-preview/editor-preview.page.d.ts +6 -0
  34. package/dist/pages/editor-preview/editor-preview.page.js +1 -0
  35. package/dist/pages/pricing/pricingData/data.js +1 -1
  36. package/dist/pages/reef/components/TransformAPIManagement.js +1 -1
  37. package/package.json +14 -8
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
3
+ interface EditorPanelProps {
4
+ value: string;
5
+ onChange: (value: string | undefined) => void;
6
+ onValidationUpdate?: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
7
+ hideWarnings: boolean;
8
+ gotoPosition?: {
9
+ line: number;
10
+ column: number;
11
+ } | null;
12
+ }
13
+ declare const EditorPanel: React.FC<EditorPanelProps>;
14
+ export default EditorPanel;
@@ -0,0 +1 @@
1
+ import*as t from"react";import f from"@monaco-editor/react";import{useMonacoEditor as s}from"../hooks/useMonacoEditor";import{DEFAULT_EDITOR_OPTIONS as d,EDITOR_LANGUAGE as p,EDITOR_THEMES as C}from"../constants/editorConfig";const I=({value:r,onChange:l,onValidationUpdate:o,hideWarnings:u,gotoPosition:e})=>{const[c,i]=t.useState(!1);t.useEffect(()=>i(!0),[]);const{activeColorMode:a,handleEditorDidMount:m,editorRef:n}=s({onValidationUpdate:o,hideWarnings:u,onClick:E=>{console.log("Editor clicked at position:",E)}});return t.useEffect(()=>{e&&n.current&&(n.current.revealPositionInCenter({lineNumber:e.line,column:e.column}),n.current.setPosition({lineNumber:e.line,column:e.column}),n.current.focus())},[e,n]),c?t.createElement(f,{language:p,theme:C[a],value:r,options:d,onChange:l,onMount:m}):null};var O=I;export{O as default};
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface EmptyStateProps {
3
+ onTemplateClick?: () => void;
4
+ onUploadClick?: (content: string, fileName: string) => void;
5
+ }
6
+ export default function EmptyState({ onTemplateClick, onUploadClick }: EmptyStateProps): React.JSX.Element;
7
+ export {};
@@ -0,0 +1,31 @@
1
+ import e from"react";import t from"styled-components";import{Button as n}from"@redocly/theme/components/Button/Button";function o({onTemplateClick:i,onUploadClick:r}){return e.createElement(l,null,e.createElement(a,null),e.createElement(c,null,"Redocly Editor"),e.createElement(p,null,"Write, test, and preview your API references in a fully interactive environment. Use real-time rendering to build and refine your docs before publishing."),e.createElement(m,null,e.createElement(n,{onClick:i},"Use template"),e.createElement(n,{variant:"outlined",onClick:r},"Upload file")))}const l=t.div`
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ height: 100%;
7
+ padding: 24px;
8
+ text-align: center;
9
+ `,a=t.div`
10
+ width: 160px;
11
+ height: 160px;
12
+ border-radius: 12px;
13
+ background-color: #f5f5f7;
14
+ margin-bottom: 24px;
15
+ `,c=t.h2`
16
+ margin: 0 0 12px 0;
17
+ font-size: 20px;
18
+ font-weight: 600;
19
+ color: var(--text-color-primary);
20
+ `,p=t.p`
21
+ max-width: 560px;
22
+ margin: 0 0 24px 0;
23
+ font-size: 15px;
24
+ line-height: 1.45;
25
+ color: #4b5563;
26
+ `,m=t.div`
27
+ display: flex;
28
+ gap: 8px;
29
+ `,f=t.span`
30
+ font-size: 10px;
31
+ `;export{o as default};
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export default function Page(): React.JSX.Element;
@@ -0,0 +1,59 @@
1
+ import r from"styled-components";import e from"react";import{Panel as t,PanelGroup as f,PanelResizeHandle as h}from"react-resizable-panels";import{useEditorState as L}from"../hooks/useEditorState";import{useOpenApiValidation as O}from"../hooks/useOpenApiValidation";import{useFileOperations as W}from"../hooks/useFileOperations";import H from"./EditorPanel";import{ProblemsPanel as N}from"./ProblemsPanel";import T from"./Toolbar";import G from"./PreviewPanel";function J(){const[v,g]=e.useState(!1);e.useEffect(()=>g(!0),[]);const{value:a,setValue:d,validatedValue:b,setValidatedValue:E,validationErrors:q,setValidationErrors:c,fileName:B,setFileName:P,parsedErrors:z,hasStructErrors:m,hideWarnings:p,setHideWarnings:x}=L(),{definition:y,hasRenderedOnce:C,setHasRenderedOnce:k}=O({validatedValue:b,hasStructErrors:m}),[w,S]=e.useState(null),[l,u]=e.useState(!0),n=e.useRef(null),o=W({setValue:d,setFileName:P,setHasRenderedOnce:k,setValidationErrors:c}),V=(i,s)=>{c(i),E(s)},R=(i,s)=>{S({line:i,column:s}),l&&n.current?.expand()},D=()=>o.handleDownloadYaml(a),F=()=>o.handleDownloadJson(a);return e.createElement(Y,null,e.createElement(U,{direction:"horizontal"},e.createElement(A,{defaultSize:50,minSize:20},e.createElement(T,{onFileLoad:o.handleFileLoad,onDownloadYamlClick:D,onDownloadJsonClick:F,hideWarnings:p,onHideWarningsChange:x}),e.createElement(I,null,e.createElement(f,{direction:"vertical"},e.createElement(t,{defaultSize:95},e.createElement(H,{value:a,onChange:d,onValidationUpdate:V,hideWarnings:p,gotoPosition:w})),e.createElement(h,{className:"resize-handle-horizontal",style:{display:l?"none":"block"}}),e.createElement(t,{ref:n,collapsible:!0,collapsedSize:5,defaultSize:5,minSize:20,onCollapse:u.bind(null,!0),onExpand:u.bind(null,!1)},e.createElement(N,{problems:z,onProblemClick:R,isCollapsed:l,onToggle:()=>{l?n.current?.expand():n.current?.collapse()}}))))),e.createElement(h,{className:"resize-handle"}),e.createElement(j,{defaultSize:50,minSize:20,collapsible:!0,collapsedSize:0},v&&e.createElement(G,{definition:y,rawValue:a,hasRenderedOnce:C,hasStructErrors:m,onTemplateClick:o.handleTemplateClick,onFileLoad:o.handleFileLoad}))))}const Y=r.div`
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: calc(100vh - var(--navbar-height));
5
+
6
+ background-color: var(--bg-color);
7
+ color: var(--text-color-primary);
8
+
9
+ [data-component-name='Layout/PageLayout']:has(&) + div + footer {
10
+ display: none;
11
+ }
12
+ `,U=r(f)`
13
+ display: flex;
14
+ flex-grow: 1;
15
+ height: 100%;
16
+ overflow: visible;
17
+
18
+ .resize-handle {
19
+ width: 8px;
20
+ background-color: var(--border-color-primary);
21
+ cursor: col-resize;
22
+ transition: background-color 0.2s ease;
23
+
24
+ &:hover {
25
+ background-color: var(--color-primary-variant);
26
+ }
27
+ }
28
+
29
+ .resize-handle-horizontal {
30
+ height: 8px;
31
+ background-color: var(--border-color-primary);
32
+ cursor: row-resize;
33
+ transition: background-color 0.2s ease;
34
+
35
+ &:hover {
36
+ background-color: var(--color-primary-variant);
37
+ }
38
+ }
39
+ `,A=r(t)`
40
+ flex: 2;
41
+ display: flex;
42
+ flex-direction: column;
43
+ overflow: visible;
44
+
45
+ .monaco-editor {
46
+ --vscode-editor-background: var(--layer-color);
47
+ --vscode-editorGutter-background: var(--layer-color);
48
+ }
49
+ `,I=r.div`
50
+ flex: 1;
51
+ min-height: 0;
52
+ display: flex;
53
+ `,j=r(t)`
54
+ flex: 3;
55
+ position: relative;
56
+ border-left: 1px solid var(--border-color-primary);
57
+ --sidebar-width: 0px;
58
+ --panel-gap-horizontal: var(--spacing-md);
59
+ `;export{J as default};
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ interface PreviewPanelProps {
3
+ definition: any | null;
4
+ rawValue: string;
5
+ hasRenderedOnce: boolean;
6
+ hasStructErrors: boolean;
7
+ onTemplateClick: () => void;
8
+ onFileLoad: (content: string, fileName: string) => void;
9
+ }
10
+ declare const PreviewPanel: React.FC<PreviewPanelProps>;
11
+ export default PreviewPanel;
@@ -0,0 +1,20 @@
1
+ import*as e from"react";import d from"styled-components";import{useEffect as o,useRef as i}from"react";import R from"./EmptyState";import{useColorMode as b}from"../hooks/useColorMode";const I=d.div`
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ right: 0;
6
+ background-color: rgba(255, 235, 238, 0.95);
7
+ color: #5c2121;
8
+ padding: 8px 16px;
9
+ border-bottom: 1px solid #f5c6cb;
10
+ text-align: center;
11
+ font-size: 0.9em;
12
+ z-index: 10;
13
+ `,x=d.iframe`
14
+ width: 100%;
15
+ height: 100%;
16
+ border: none;
17
+ `,M=({definition:s,rawValue:l,hasStructErrors:g,onTemplateClick:h,onFileLoad:y})=>{const f=i(null),n=s||f.current,u=b(),v=i(null),t=i(null),[a,w]=e.useState(!1),[E,S]=e.useState(0),m=i(!1);o(()=>{const c=r=>{r.data?.type!=="scroll-sync"||r.data?.source==="preview"||!t.current||m.current||(m.current=!0,t.current.postMessage(r.data,"*"),setTimeout(()=>{m.current=!1},50))};return window.addEventListener("message",c),()=>window.removeEventListener("message",c)},[]),o(()=>{const c=r=>{t.current=r,r.updateDefinition(n),w(!0),setTimeout(()=>{r.postMessage({type:"theme-change",theme:u},"*")},100)};window.onReady=c},[n]),o(()=>{s&&(f.current=s)},[s]),o(()=>{t.current&&a&&t.current.updateDefinition(n)},[n,a]),o(()=>{t.current&&a&&t.current.postMessage({type:"theme-change",theme:u},"*")},[u,a]);const p=g&&e.createElement(I,null,"Preview is showing the last valid version. The current content has structural errors. Please check editor messages.")||null;return!l||typeof l!="string"||l.trim()===""?e.createElement(R,{onTemplateClick:h,onUploadClick:y}):n?e.createElement(e.Fragment,null,p,e.createElement(P,null,e.createElement(x,{key:E,ref:v,title:"API Documentation Preview",src:"/preview",onLoad:()=>{}}))):p||"Loading..."};var L=M;const P=d.div`
18
+ height: 100%;
19
+ overflow: hidden;
20
+ `;export{L as default};
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import type { editor as MonacoEditor } from 'monaco-editor';
3
+ interface ProblemsPanelProps {
4
+ problems: MonacoEditor.IMarkerData[];
5
+ onProblemClick: (line: number, column: number) => void;
6
+ isCollapsed: boolean;
7
+ onToggle: () => void;
8
+ }
9
+ export declare const ProblemsPanel: React.FC<ProblemsPanelProps>;
10
+ export {};
@@ -0,0 +1,71 @@
1
+ import*as e from"react";import n from"styled-components";import{ChevronDownIcon as b}from"@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon";import{ChevronUpIcon as k}from"@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon";const E={8:"Error",4:"Warning",2:"Info",1:"Hint"},h={8:"var(--color-error)",4:"var(--color-warning)",2:"var(--color-info)",1:"var(--color-info)"},T=({problems:o,onProblemClick:m,isCollapsed:a,onToggle:v})=>{const[r,f]=e.useState({key:"severity",direction:"descending"}),p=e.useMemo(()=>{let t=[...o];return r!==null&&t.sort((i,c)=>r.key==="line"?i.startLineNumber<c.startLineNumber?r.direction==="ascending"?-1:1:i.startLineNumber>c.startLineNumber?r.direction==="ascending"?1:-1:0:i[r.key]<c[r.key]?r.direction==="ascending"?-1:1:i[r.key]>c[r.key]?r.direction==="ascending"?1:-1:0),t},[o,r]),s=t=>{let i="ascending";r&&r.key===t&&r.direction==="ascending"&&(i="descending"),f({key:t,direction:i})},y=o.filter(t=>t.severity===8).length,x=o.filter(t=>t.severity===4).length;return e.createElement(C,{$collapsed:a},e.createElement(w,{onClick:v},e.createElement($,null,"Problems ",o.length,e.createElement(L,null,"(",e.createElement(d,{color:"var(--color-error)"},y," Errors"),e.createElement(d,{color:"var(--color-warning)"},x," Warnings"),")")),a?e.createElement(k,null):e.createElement(b,null)),!a&&e.createElement(S,null,e.createElement(g,null,e.createElement(l,{onClick:()=>s("severity")},"Severity ",r?.key==="severity"?r?.direction==="ascending"?"\u2191":"\u2193":""),e.createElement(l,{onClick:()=>s("message")},"Message ",r?.key==="message"?r?.direction==="ascending"?"\u2191":"\u2193":""),e.createElement(l,{onClick:()=>s("line")},"Line ",r?.key==="line"?r?.direction==="ascending"?"\u2191":"\u2193":"")),e.createElement(P,null,p.map((t,i)=>e.createElement(u,{key:i,onClick:()=>m(t.startLineNumber,t.startColumn)},e.createElement(l,null,e.createElement(z,{color:h[t.severity]},E[t.severity])),e.createElement(l,null,t.message),e.createElement(l,null,t.startLineNumber,":",t.startColumn))))))},C=n.div`
2
+ display: flex;
3
+ flex-direction: column;
4
+ height: ${o=>o.$collapsed?"34px":"100%"};
5
+ max-height: ${o=>o.$collapsed?"34px":"none"};
6
+ background-color: var(--bg-color);
7
+ `,w=n.div`
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ box-sizing: border-box;
12
+ height: 34px;
13
+ padding: 0 12px;
14
+ border-top: 1px solid var(--border-color-primary);
15
+ cursor: pointer;
16
+ user-select: none;
17
+ `,$=n.div`
18
+ font-size: 0.875rem;
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 16px;
22
+ `,L=n.div`
23
+ display: flex;
24
+ gap: 8px;
25
+ `,d=n.span`
26
+ color: ${o=>o.color};
27
+ `,S=n.div`
28
+ flex-grow: 1;
29
+ overflow: auto;
30
+ display: flex;
31
+ flex-direction: column;
32
+ font-size: var(--font-size-sm);
33
+ `,N="100px 1fr 100px 100px",u=n.div`
34
+ display: grid;
35
+ grid-template-columns: ${N};
36
+ border-bottom: 1px solid var(--border-color-primary);
37
+ cursor: pointer;
38
+ &:hover {
39
+ background-color: var(--layer-color);
40
+ }
41
+ `,g=n(u)`
42
+ position: sticky;
43
+ top: 0;
44
+ background-color: var(--bg-color);
45
+ font-weight: bold;
46
+ border-bottom-width: 2px;
47
+ cursor: default;
48
+
49
+ &:hover {
50
+ background-color: var(--bg-color);
51
+ }
52
+ `,P=n.div`
53
+ overflow-y: auto;
54
+ `,l=n.div`
55
+ padding: 6px 12px;
56
+ text-align: left;
57
+ white-space: nowrap;
58
+ overflow: hidden;
59
+ text-overflow: ellipsis;
60
+
61
+ ${g} & {
62
+ cursor: pointer;
63
+ user-select: none;
64
+ &:hover {
65
+ background-color: var(--lay);
66
+ }
67
+ }
68
+ `,z=n.span`
69
+ color: ${o=>o.color};
70
+ font-weight: bold;
71
+ `;export{T as ProblemsPanel};
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface ToolbarProps {
3
+ onFileLoad: (content: string, fileName: string) => void;
4
+ onDownloadYamlClick: () => void;
5
+ onDownloadJsonClick: () => void;
6
+ hideWarnings: boolean;
7
+ onHideWarningsChange: (hide: boolean) => void;
8
+ }
9
+ export default function Toolbar({ hideWarnings, onHideWarningsChange, onDownloadYamlClick, onDownloadJsonClick, onFileLoad }: ToolbarProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,50 @@
1
+ import e,{useRef as v,useState as E}from"react";import o from"styled-components";import{Button as i}from"@redocly/theme/components/Button/Button";import{DownloadIcon as p}from"@redocly/theme/icons/DownloadIcon/DownloadIcon";import{ChevronDownIcon as k}from"@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon";function C({hideWarnings:m,onHideWarningsChange:f,onDownloadYamlClick:c,onDownloadJsonClick:u,onFileLoad:g}){const d=v(null),[x,t]=E(!1),b=()=>{d.current?.click()},h=()=>t(n=>!n),w=n=>{const r=n.target.files?.[0];if(!r)return;const l=new FileReader;l.onload=a=>{const y=a.target?.result;g(y,r.name)},l.onerror=a=>{console.error("Failed to read file!",a)},l.readAsText(r),n.target.value=""};return e.createElement(D,null,e.createElement(I,null,e.createElement("input",{type:"checkbox",checked:m,onChange:n=>f(n.target.checked),id:"hide-warnings"}),"Hide warnings"),e.createElement(F,null,e.createElement(i,{variant:"text",icon:e.createElement(p,{style:{transform:"rotate(180deg)"}}),onClick:b,"aria-label":"Upload spec"}),e.createElement(A,{type:"file",ref:d,onChange:w,accept:".yaml,.yml,.json"}),e.createElement(R,null,e.createElement(i,{onClick:c,iconPosition:"left",icon:e.createElement(p,null)},"Download"),e.createElement(i,{icon:e.createElement(k,null),onClick:h,"aria-label":"Download options"}),x&&e.createElement(z,null,e.createElement(s,{onClick:()=>{c(),t(!1)}},"Download YAML"),e.createElement(s,{onClick:()=>{u(),t(!1)}},"Download JSON")))))}const D=o.div`
2
+ padding: 6px 12px;
3
+ border-bottom: 1px solid var(--border-color-primary);
4
+ display: flex;
5
+ align-items: center;
6
+ background-color: var(--bg-color);
7
+ color: var(--text-color-primary);
8
+ gap: 16px;
9
+ `,I=o.label`
10
+ display: flex;
11
+ align-items: center;
12
+ gap: 8px;
13
+ font-size: 0.875rem;
14
+ cursor: pointer;
15
+ `,F=o.div`
16
+ display: flex;
17
+ align-items: center;
18
+ gap: 8px;
19
+ margin-left: auto; /* Push to far right */
20
+ `,R=o.div`
21
+ position: relative;
22
+ display: inline-flex;
23
+ align-items: center;
24
+ display: flex;
25
+ flex-direction: row;
26
+ gap: calc(var(--spacing-xxs) / 2);
27
+ `,z=o.ul`
28
+ position: absolute;
29
+ right: 0;
30
+ top: 100%;
31
+ margin: 4px 0 0 0;
32
+ padding: 4px 0;
33
+ list-style: none;
34
+ border: 1px solid var(--border-color-primary, #ccc);
35
+ background-color: var(--bg-color, #fff);
36
+ color: var(--text-color-primary, #111);
37
+ border-radius: 4px;
38
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
39
+ min-width: 140px;
40
+ z-index: 20;
41
+ `,s=o.li`
42
+ padding: 6px 12px;
43
+ font-size: 0.875rem;
44
+ cursor: pointer;
45
+ &:hover {
46
+ background-color: var(--bg-color-active, #f5f5f5);
47
+ }
48
+ `,A=o.input`
49
+ display: none;
50
+ `;export{C as default};
@@ -0,0 +1,7 @@
1
+ import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
2
+ export declare const DEFAULT_EDITOR_OPTIONS: Monaco.editor.IStandaloneEditorConstructionOptions;
3
+ export declare const EDITOR_LANGUAGE = "yaml";
4
+ export declare const EDITOR_THEMES: {
5
+ readonly light: "light";
6
+ readonly dark: "vs-dark";
7
+ };
@@ -0,0 +1 @@
1
+ const t={padding:{top:12,bottom:12},fontSize:14,tabSize:2,detectIndentation:!0,minimap:{enabled:!1},renderLineHighlight:"all",placeholder:"Drag your file here or start typing...",stickyScroll:{enabled:!0}},e="yaml",r={light:"light",dark:"vs-dark"};export{t as DEFAULT_EDITOR_OPTIONS,e as EDITOR_LANGUAGE,r as EDITOR_THEMES};
@@ -0,0 +1,8 @@
1
+ import Page from './components/Page';
2
+ export declare const frontmatter: {
3
+ seo: {
4
+ title: string;
5
+ };
6
+ slug: string;
7
+ };
8
+ export default Page;
@@ -0,0 +1 @@
1
+ import t from"./components/Page";const e={seo:{title:"Redocly Editor"},slug:"/editor"};var r=t;export{r as default,e as frontmatter};
@@ -0,0 +1 @@
1
+ export declare const useColorMode: () => string;
@@ -0,0 +1 @@
1
+ import{useEffect as r,useState as s}from"react";const d=()=>{const[t,o]=s(typeof document<"u"&&document.documentElement.classList.contains("dark")?"dark":"light");return r(()=>{if(typeof document>"u")return;const e=new MutationObserver(()=>{const n=document.documentElement.classList.contains("dark");o(n?"dark":"light")});return e.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}),()=>{e.disconnect()}},[]),t};export{d as useColorMode};
@@ -0,0 +1,18 @@
1
+ import { editor } from 'monaco-editor';
2
+ export interface EditorState {
3
+ value: string;
4
+ setValue: (value: string) => void;
5
+ validatedValue: string | undefined;
6
+ setValidatedValue: (value: string | undefined) => void;
7
+ validationErrors: editor.IMarkerData[];
8
+ setValidationErrors: (errors: editor.IMarkerData[]) => void;
9
+ fileName: string;
10
+ setFileName: (fileName: string) => void;
11
+ parsedErrors: (editor.IMarkerData & {
12
+ rule: string;
13
+ })[];
14
+ hasStructErrors: boolean;
15
+ hideWarnings: boolean;
16
+ setHideWarnings: (hide: boolean) => void;
17
+ }
18
+ export declare function useEditorState(): EditorState;
@@ -0,0 +1 @@
1
+ import{useEffect as l,useMemo as n,useState as t}from"react";function h(){const i=typeof localStorage<"u"&&localStorage.getItem("editorValue")||"",[e,u]=t(i),[c,o]=t(void 0),[r,d]=t([]),[m,f]=t(""),[V,g]=t(!1),E=/Rule: ([\w-_\/]+)/,s=n(()=>r.map(a=>({...a,rule:a.message.match(E)?.[1]})),[r]),S=n(()=>s.some(a=>a.rule==="struct"),[s]);return l(()=>{localStorage.setItem("editorValue",e)},[e]),l(()=>{o(e)},[e]),{value:e,setValue:u,validatedValue:c,setValidatedValue:o,validationErrors:r,setValidationErrors:d,fileName:m,setFileName:f,hideWarnings:V,setHideWarnings:g,parsedErrors:s,hasStructErrors:S}}export{h as useEditorState};
@@ -0,0 +1,13 @@
1
+ interface FileOperationsCallbacks {
2
+ setValue: (value: string) => void;
3
+ setFileName: (name: string) => void;
4
+ setHasRenderedOnce: (hasRendered: boolean) => void;
5
+ setValidationErrors: (errors: any[]) => void;
6
+ }
7
+ export declare function useFileOperations(callbacks: FileOperationsCallbacks): {
8
+ handleFileLoad: (content: string, fileName: string) => void;
9
+ handleTemplateClick: () => void;
10
+ handleDownloadYaml: (value: string) => void;
11
+ handleDownloadJson: (value: string) => void;
12
+ };
13
+ export {};
@@ -0,0 +1 @@
1
+ import{dump as p,load as e}from"js-yaml";import{downloadFile as d}from"../utils/download";import{defaultOpenapiTemplate as m}from"../templates/defaultOpenapiTemplate";function L(s){const{setValue:a,setFileName:i,setHasRenderedOnce:r,setValidationErrors:l}=s;return{handleFileLoad:(n,o)=>{a(n),console.log(`Loaded file: ${o}`),i(o),r(!1),l([])},handleTemplateClick:()=>{a(m),console.log("Loaded default template."),r(!1),l([])},handleDownloadYaml:n=>{let o=n;try{if(n.trim().startsWith("{")){const t=JSON.parse(n);o=p(t)}else e(n),o=n}catch(t){try{e(n),o=n}catch(c){alert("Content is not valid JSON or YAML. Cannot convert to YAML for download."),console.error("Error preparing YAML for download:",t,c);return}}d(o,"openapi.yaml","application/x-yaml")},handleDownloadJson:n=>{try{const o=e(n);if(typeof o!="object"||o===null)throw new Error("Parsed content is not an object.");const t=JSON.stringify(o,null,2);d(t,"openapi.json","application/json")}catch(o){alert("Content is not valid YAML/JSON. Cannot convert to JSON for download."),console.error("Error preparing JSON for download:",o)}}}}export{L as useFileOperations};
@@ -0,0 +1,12 @@
1
+ import type { editor, Position } from "monaco-editor";
2
+ export interface MonacoEditorOptions {
3
+ onValidationUpdate?: (errors: editor.IMarkerData[], value: string) => void;
4
+ onClick?: (position: Position) => void;
5
+ hideWarnings?: boolean;
6
+ }
7
+ export declare function useMonacoEditor({ onValidationUpdate, onClick, hideWarnings }: MonacoEditorOptions): {
8
+ editorRef: import("react").MutableRefObject<editor.IStandaloneCodeEditor | null>;
9
+ monacoRef: import("react").MutableRefObject<null>;
10
+ activeColorMode: string;
11
+ handleEditorDidMount: (editor: editor.IStandaloneCodeEditor, monaco: any) => () => void;
12
+ };
@@ -0,0 +1 @@
1
+ import{useEffect as M,useRef as r}from"react";import{LanguageServerService as d}from"../services/languageServerService";import{useColorMode as v}from"./useColorMode";import{useThemeHooks as D}from"@redocly/theme/core/hooks";function w({onValidationUpdate:n,onClick:i,hideWarnings:e}){const u=r(null),c=r(null),o=r(null),{useGlobalData:s}=D(),R=s(),a=v(),f=(t,l)=>{u.current=t,c.current=l,o.current||(o.current=new d),o.current.initialize(t,l);const m=o.current.setupAutoValidation(n,e);return t.onMouseDown(({target:p})=>{i?.(p.position)}),()=>{m()}};return M(()=>{o.current?.setupAutoValidation(n,e)},[e]),{editorRef:u,monacoRef:c,activeColorMode:a,handleEditorDidMount:f}}export{w as useMonacoEditor};
@@ -0,0 +1,14 @@
1
+ interface OpenApiValidationHook {
2
+ definition: any | null;
3
+ hasRenderedOnce: boolean;
4
+ setHasRenderedOnce: (hasRendered: boolean) => void;
5
+ }
6
+ interface ValidationDependencies {
7
+ validatedValue: string | undefined;
8
+ hasStructErrors: boolean;
9
+ }
10
+ /**
11
+ * Custom hook to handle OpenAPI definition validation and parsing
12
+ */
13
+ export declare function useOpenApiValidation({ validatedValue, hasStructErrors }: ValidationDependencies): OpenApiValidationHook;
14
+ export {};
@@ -0,0 +1 @@
1
+ import{useState as s,useEffect as p}from"react";import{load as c}from"js-yaml";function O({validatedValue:t,hasStructErrors:o}){const[f,n]=s(null),[i,r]=s(!1);return p(()=>{try{if(o){n(null);return}if(!t){n(null);return}const e=c(t);if(!(e&&typeof e=="object"&&e.openapi&&typeof e.openapi=="string")){n(null);return}n(e),i||r(!0)}catch{n(null)}},[t,o,i]),{definition:f,hasRenderedOnce:i,setHasRenderedOnce:r}}export{O as useOpenApiValidation};
@@ -0,0 +1,52 @@
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
+ getText: (options?: {
8
+ start?: number;
9
+ end?: number;
10
+ }) => string;
11
+ offsetAt: (position: LSPosition) => number;
12
+ positionAt: (offset: number) => Monaco.IPosition;
13
+ }
14
+ export interface ValidationCallback {
15
+ (errors: Monaco.editor.IMarkerData[], value: string): void;
16
+ }
17
+ /**
18
+ * Service class to handle OpenAPI Language Server integration
19
+ */
20
+ export declare class LanguageServerService {
21
+ private monaco;
22
+ private editor;
23
+ constructor();
24
+ /**
25
+ * Initialize the language server with Monaco editor instance
26
+ */
27
+ initialize(editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco): void;
28
+ /**
29
+ * Register documents provider for the language server
30
+ */
31
+ private registerDocumentsProvider;
32
+ /**
33
+ * Create document provider for current editor content
34
+ */
35
+ private createDocumentProvider;
36
+ /**
37
+ * Register completion item provider
38
+ */
39
+ private registerCompletionProvider;
40
+ /**
41
+ * Register definition provider
42
+ */
43
+ private registerDefinitionProvider;
44
+ /**
45
+ * Validate OpenAPI content and provide diagnostics
46
+ */
47
+ validateContent(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): Promise<void>;
48
+ /**
49
+ * Setup automatic validation on content changes
50
+ */
51
+ setupAutoValidation(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): () => void;
52
+ }
@@ -0,0 +1,3 @@
1
+ import{load as v}from"js-yaml";class M{constructor(){this.monaco=null,this.editor=null}initialize(n,r){this.editor=n,this.monaco=r}registerDocumentsProvider(){}createDocumentProvider(){return{getText:({start:n=0,end:r=void 0}={})=>(this.editor?.getModel()?.getValue()||"").slice(n,r),offsetAt:n=>{const r=this.editor?.getModel();return r?r.getOffsetAt({lineNumber:n.line+1,column:n.character+1}):0},positionAt:n=>{const r=this.editor?.getModel();if(!r)return{lineNumber:1,column:1};const s=r.getPositionAt(n);return{lineNumber:s.lineNumber,column:s.column}}}}registerCompletionProvider(){this.monaco&&this.monaco.languages.registerCompletionItemProvider("yaml",{triggerCharacters:[" ",`
2
+ `,"\\","/",'"',"'"],provideCompletionItems:async(n,r)=>({suggestions:[]})})}registerDefinitionProvider(){this.monaco&&this.monaco.languages.registerDefinitionProvider("yaml",{provideDefinition:async(n,r)=>[]})}async validateContent(n,r){if(!this.editor||!this.monaco)return;const s=this.editor.getModel();if(!s)return;const o=s.getValue(),C={uri:s.uri.toString(),languageId:"yaml",version:s.getVersionId(),getText:()=>o,positionAt:e=>{const c=s.getPositionAt(e);return{line:c.lineNumber-1,character:c.column-1}},offsetAt:e=>s.getOffsetAt({lineNumber:e.line+1,column:e.character+1}),lineCount:s.getLineCount()};try{let e=[];r&&(e=e.filter(t=>t.severity!==4));let c=null;try{v(o)}catch(t){c={severity:8,message:t.reason+" Rule: struct",startLineNumber:t.mark?.line||1,startColumn:0,endLineNumber:t.mark?.line||1,endColumn:1e3},e.push(c)}const u=o.split(`
3
+ `);u.forEach((t,i)=>{const p=t.match(/^\s*type:\s*([^\s#]+)\s*(?:#.*)?$/);if(p){const l=L(u,i),m=l?new Set(["apiKey","http","oauth2","openIdConnect"]):new Set(["string","number","integer","boolean","array","object"]),a=p[1].trim();if(!m.has(a)){const g=t.indexOf("type:")+5+2;e.push({severity:8,message:l?`Invalid security scheme type '${a}'. Allowed: apiKey, http, oauth2, openIdConnect. Rule: struct`:`Invalid schema type '${a}'. Allowed: string, number, integer, boolean, array, object. Rule: struct`,startLineNumber:i+1,startColumn:Math.max(1,g),endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"})}}const f=t.match(/^(\s*)-(\s*)$/);if(f){const l={severity:8,message:"Empty list item detected. List items should have content. Rule: struct",startLineNumber:i+1,startColumn:f[1].length+1,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(l)}const d=t.match(/^(\s*)([^#\s][^:]*):\s*$/);if(d&&!t.trim().endsWith(":")){const l=d[2].trim().toLowerCase();if(["version","title","description","type","format","required","default","example"].some(a=>l.includes(a))){const a={severity:8,message:"Key without value detected. This key typically requires a value. Rule: struct",startLineNumber:i+1,startColumn:d[1].length+1,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(a)}}const y=t.match(/^(\s*)-(\s*)(.*)$/);if(y){const[l,m,a,g]=y;if(g.trim().length>0&&a.length!==1){const b={severity:8,message:a.length===0?"Missing space after dash in list item. There should be exactly one space between the dash and content. Rule: struct":"Too many spaces after dash in list item. There should be exactly one space between the dash and content. Rule: struct",startLineNumber:i+1,startColumn:m.length+2,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(b)}}}),this.monaco.editor.setModelMarkers(s,"openapi-ls",e),n&&n(e,o)}catch(e){console.error("Error during validation:",e)}}setupAutoValidation(n,r){if(!this.editor)return()=>{};const s=()=>this.validateContent(n,r);s();const o=this.editor.onDidChangeModelContent(()=>{s()});return()=>o.dispose()}}function L(h,n){const s=(h[n]||"").match(/^\s*/)?.[0].length||0;for(let o=n;o>=0;o--){const e=(h[o]??"").replace(/#.*$/,"");if(!e.trim())continue;const c=e.match(/^\s*/)?.[0].length||0,u=e.match(/^\s*([A-Za-z0-9_\-]+):\s*$/);if(u&&c<s&&u[1]==="components")return!1;if(u&&c<=s){const t=u[1];if(t==="securitySchemes")return!0;if(new Set(["schemas","responses","parameters","examples","requestBodies","headers","links","callbacks","pathItems"]).has(t))return!1}}return!1}export{M as LanguageServerService};
@@ -0,0 +1 @@
1
+ export declare const defaultOpenapiTemplate = "openapi: 3.0.0\ninfo:\n title: My API\n version: 1.0.0\n description: A new API to be documented.\npaths:\n /example:\n get:\n summary: Example endpoint\n description: This is a sample endpoint.\n responses:\n '200':\n description: Successful response\n content:\n application/json:\n schema:\n type: object\n properties:\n message:\n type: string\n example: Hello World!\n";
@@ -0,0 +1,22 @@
1
+ const e=`openapi: 3.0.0
2
+ info:
3
+ title: My API
4
+ version: 1.0.0
5
+ description: A new API to be documented.
6
+ paths:
7
+ /example:
8
+ get:
9
+ summary: Example endpoint
10
+ description: This is a sample endpoint.
11
+ responses:
12
+ '200':
13
+ description: Successful response
14
+ content:
15
+ application/json:
16
+ schema:
17
+ type: object
18
+ properties:
19
+ message:
20
+ type: string
21
+ example: Hello World!
22
+ `;export{e as defaultOpenapiTemplate};
@@ -0,0 +1 @@
1
+ export declare const downloadFile: (content: string, fileName: string, contentType: string) => void;
@@ -0,0 +1 @@
1
+ const c=(o,t,d)=>{const e=document.createElement("a"),n=new Blob([o],{type:d});e.href=URL.createObjectURL(n),e.download=t,document.body.appendChild(e),e.click(),document.body.removeChild(e)};export{c as downloadFile};
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ interface PageProps {
3
+ RedoclyOpenAPIDocs: any;
4
+ }
5
+ export default function Page({ RedoclyOpenAPIDocs }: PageProps): React.JSX.Element;
6
+ export {};
@@ -0,0 +1 @@
1
+ import*as t from"react";function g({RedoclyOpenAPIDocs:c}){const[n,r]=t.useState(null),a=t.useRef(null),[h,d]=t.useState("light"),u=t.useRef(!1),p=t.useRef(null);return t.useEffect(()=>{const s=new URLSearchParams(window.location.search).get("theme");if(s)d(s);else{const e=document.documentElement.classList.contains("dark");d(e?"dark":"light")}window.updateDefinition=e=>{if(e&&typeof e=="object"&&typeof e.openapi=="string"){const o=y(e);a.current=o,r(o)}else a.current?p.current!==a.current&&r(a.current):r(null);p.current=e},window.parent.onReady(window)},[]),t.useEffect(()=>{h==="dark"?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")},[h]),t.useEffect(()=>{const f=()=>{if(u.current)return;const e=document.querySelector("article");if(!e)return;const i=window.innerHeight,o=e.scrollHeight,m=window.scrollY,l=o-i;if(l<=0)return;const w=Math.round(m/l*100);window.parent.postMessage({type:"scroll-sync",position:{absolute:m,relative:w},source:"preview"},"*")},s=e=>{if(e.data?.type==="theme-change"){d(e.data.theme);return}if(e.data?.type!=="scroll-sync"||e.data?.source==="preview"||u.current)return;const i=document.querySelector("article");if(!i)return;const o=window.innerHeight,l=i.scrollHeight-o;if(l<=0)return;u.current=!0;const w=Math.round(e.data.position.relative/100*l);window.scrollTo({top:w,behavior:"smooth"}),setTimeout(()=>{u.current=!1},50)};return window.addEventListener("scroll",f),window.addEventListener("message",s),()=>{window.removeEventListener("scroll",f),window.removeEventListener("message",s)}},[]),n?t.createElement(c,{store:{options:{routingBasePath:"/preview",disableRouter:!0,hideSidebar:!0,scrollYOffset:0},definition:n}}):t.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh",fontFamily:"system-ui, -apple-system, sans-serif",color:"#666"}},"No API definition available")}function y(c){try{const n={...c};return Array.isArray(n.servers)&&(n.servers=n.servers.filter(r=>r&&typeof r=="object").filter(r=>typeof r.url=="string"&&r.url.trim().length>0)),n}catch{return c}}export{g as default};
@@ -1 +1 @@
1
- import{Period as r,Plan as o,Product as a,ProductBundle as i}from"../types/types";const l=[{title:a.REALM,description:"All combined (Redoc + Revel + Reef)",bgColor:"linear-gradient(90deg, rgba(22, 119, 255, 0.08) 0%, rgba(8, 199, 224, 0.08) 100%)",titleColor:"linear-gradient(90deg, #1677FF 0%, #08C7E0 100%)"},{title:a.REDOC,description:"Streamline API development with support for OpenAPI, GraphQL, and AsyncAPI, with mock servers and advanced linting.",bgColor:"#E5F1FF",titleColor:"#1677FF",features:["OpenAPI","GraphQL","AsyncAPI","Mock servers","Lint"]},{title:a.REVEL,description:"Showcase your APIs. Add guides. Localize. Add contextual docs. Landing pages. Multi-product support.",bgColor:"#EDEBFF",titleColor:"#735CFF",features:["Markdown docs","React pages","Component ejections","Localization","Multi-product support"]},{title:a.REEF,description:"API catalog and registry are great for internal use cases. Scorecard for governance. API functions for custom integration capabilities.",bgColor:"#F1E5FF",titleColor:"#A45CFF",features:["API catalog","API registry","Scorecard for governance","API functions","Markdown docs","Dynamic client registration"]}],d=[{property:"reunite",name:"Reunite",tooltip:"Reunite is a full collaboration suite with Git integration, editor, visual reviews, and more."},{property:"hasHosting",name:"Custom domain hosting",tooltip:"Host your project on your custom domain"},{property:"projects",name:"Project",tooltip:"The number of projects included under this plan. Extra available for USD $49/month."},{property:"pages",name:"Pages",tooltip:"Total number of pages included across all your projects. Extra available for USD $0.12/month."},{property:"SSO",name:"SSO",tooltip:"Single Sign-On integration for streamlined and secure login"},{property:"guestSSO",name:"Guest SSO",tooltip:"Single Sign-On integration for external guest login"},{property:"RBAC",name:"RBAC",tooltip:"Role-Based Access Control to manage user permissions"},{property:"residencyOptions",name:"Data residency options",tooltip:"Choose where your data is stored to comply with regional regulations"},{property:"IPNetworkRestrictions",name:"IP network restrictions and more",tooltip:"Set IP restrictions to enhance security and control access"},{property:"salesAssistance",name:"Sales-assistance",tooltip:"Get support from our sales team for finding the best solutions for your organization"},{property:"forms",name:"Procurement forms",tooltip:"Access and submit necessary procurement documentation"},{property:"securityQuestionnaires",name:"Security questionnaires",tooltip:"Receive and complete security questionnaires to ensure compliance"},{property:"payByInvoice",name:"Pay-by-invoice / PO process",tooltip:"Flexible payment options including invoices and purchase orders"},{property:"reviews",name:"Legal reviews",tooltip:"Get assistance with legal reviews and compliance checks"},{property:"singleTenant",name:"Single-tenant hosting options",tooltip:"Opt for dedicated hosting for enhanced security and performance"},{property:"premiumSupport",name:"Premium support and professional services options",tooltip:"Access priority support and professional services for your projects"},{property:"remoteContent",name:"Remote content",tooltip:"Remote content allows you to automate sourcing content from a remote source. This is different from sourcing the entire project repository. Remote content can be sourced from Git repos, CICD push command, or a remote URL."},{property:"aiSearch",name:"AI search",tooltip:"Use AI to search your content"},{property:"typesense",name:"Typesense search",tooltip:"Use Typesense to search your content. Create additional search facets. Better relevance for search results."},{property:"apiFunctions",name:"API functions",tooltip:"Custom API endpoints for dynamic and server-side logic"},{property:"analytics",name:"Analytics",tooltip:"Get a clear picture of what users see and search for\u2014page views, search trends, and AI-powered query details"}],u=[{name:o.PRO,features:{reunite:!0,hasHosting:!0,projects:1,pages:100}},{name:o.ENTERPRISE,features:{pages:500,SSO:!0,guestSSO:!0,RBAC:!0,remoteContent:!0,aiSearch:!0,typesense:!0,analytics:!0}},{name:o.ENTERPRISE_PLUS,features:{residencyOptions:!0,salesAssistance:!0,forms:!0,securityQuestionnaires:!0,payByInvoice:!0,reviews:!0,singleTenant:!0,premiumSupport:!0}}],m=[r.MONTH,r.YEAR],n=[{tierStart:1,tierEnd:20},{tierStart:21,tierEnd:50},{tierStart:51,tierEnd:100},{tierStart:101,tierEnd:250},{tierStart:251,tierEnd:500},{tierStart:501,tierEnd:1e3},{tierStart:1001,tierEnd:1/0}],E={[i.ONE]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[24,21.6,19.2,16.8,15.6,14.4,13.2][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[264,237.6,211.2,184.8,171.6,158.4,145.2][t]}))},[i.TWO]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[48,43.2,38.4,33.6,31.2,28.8,26.4][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[528,475.2,422.4,369.6,343.2,316.8,290.4][t]}))},[i.REALM]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[66,59.4,52.8,46.2,42.9,39.6,36.3][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[708,653.4,580.8,508.2,471.9,435.6,399.3][t]}))}},S={[i.ONE]:{[r.MONTH]:10,[r.YEAR]:108},[i.TWO]:{[r.MONTH]:20,[r.YEAR]:216},[i.REALM]:{[r.MONTH]:28,[r.YEAR]:300}},s=[{tierStart:1,tierEnd:500},{tierStart:501,tierEnd:1/0}],p=[{tierStart:1,tierEnd:100},{tierStart:101,tierEnd:1/0}],y={[o.PRO]:{[r.MONTH]:p.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:p.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))},[o.ENTERPRISE]:{[r.MONTH]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))},[o.ENTERPRISE_PLUS]:{[r.MONTH]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))}},g=49,f={[o.PRO]:1,[o.ENTERPRISE]:1,[o.ENTERPRISE_PLUS]:1};export{d as featuresList,y as pageIntervals,m as periodsList,u as plansList,g as pricePerProject,l as productItems,E as seatIntervals,S as seatProPlanIntervals,f as startNumOfProjectPerPlan};
1
+ import{Period as r,Plan as o,Product as a,ProductBundle as i}from"../types/types";const l=[{title:a.REALM,description:"All combined (Redoc + Revel + Reef)",bgColor:"linear-gradient(90deg, rgba(22, 119, 255, 0.08) 0%, rgba(8, 199, 224, 0.08) 100%)",titleColor:"linear-gradient(90deg, #1677FF 0%, #08C7E0 100%)"},{title:a.REDOC,description:"Streamline API development with support for OpenAPI, GraphQL, and AsyncAPI, with mock servers and advanced linting.",bgColor:"#E5F1FF",titleColor:"#1677FF",features:["OpenAPI","GraphQL","AsyncAPI","Mock servers","Lint"]},{title:a.REVEL,description:"Showcase your APIs. Add guides. Localize. Add contextual docs. Landing pages. Multi-product support.",bgColor:"#EDEBFF",titleColor:"#735CFF",features:["Markdown docs","React pages","Component ejections","Localization","Multi-product support"]},{title:a.REEF,description:"API catalog is great for internal use cases. Scorecard for governance. API functions for custom integration capabilities.",bgColor:"#F1E5FF",titleColor:"#A45CFF",features:["API catalog","Scorecard for governance","API functions","Markdown docs","Dynamic client registration"]}],d=[{property:"reunite",name:"Reunite",tooltip:"Reunite is a full collaboration suite with Git integration, editor, visual reviews, and more."},{property:"hasHosting",name:"Custom domain hosting",tooltip:"Host your project on your custom domain"},{property:"projects",name:"Project",tooltip:"The number of projects included under this plan. Extra available for USD $49/month."},{property:"pages",name:"Pages",tooltip:"Total number of pages included across all your projects. Extra available for USD $0.12/month."},{property:"SSO",name:"SSO",tooltip:"Single Sign-On integration for streamlined and secure login"},{property:"guestSSO",name:"Guest SSO",tooltip:"Single Sign-On integration for external guest login"},{property:"RBAC",name:"RBAC",tooltip:"Role-Based Access Control to manage user permissions"},{property:"residencyOptions",name:"Data residency options",tooltip:"Choose where your data is stored to comply with regional regulations"},{property:"IPNetworkRestrictions",name:"IP network restrictions and more",tooltip:"Set IP restrictions to enhance security and control access"},{property:"salesAssistance",name:"Sales-assistance",tooltip:"Get support from our sales team for finding the best solutions for your organization"},{property:"forms",name:"Procurement forms",tooltip:"Access and submit necessary procurement documentation"},{property:"securityQuestionnaires",name:"Security questionnaires",tooltip:"Receive and complete security questionnaires to ensure compliance"},{property:"payByInvoice",name:"Pay-by-invoice / PO process",tooltip:"Flexible payment options including invoices and purchase orders"},{property:"reviews",name:"Legal reviews",tooltip:"Get assistance with legal reviews and compliance checks"},{property:"singleTenant",name:"Single-tenant hosting options",tooltip:"Opt for dedicated hosting for enhanced security and performance"},{property:"premiumSupport",name:"Premium support and professional services options",tooltip:"Access priority support and professional services for your projects"},{property:"remoteContent",name:"Remote content",tooltip:"Remote content allows you to automate sourcing content from a remote source. This is different from sourcing the entire project repository. Remote content can be sourced from Git repos, CICD push command, or a remote URL."},{property:"aiSearch",name:"AI search",tooltip:"Use AI to search your content"},{property:"typesense",name:"Typesense search",tooltip:"Use Typesense to search your content. Create additional search facets. Better relevance for search results."},{property:"apiFunctions",name:"API functions",tooltip:"Custom API endpoints for dynamic and server-side logic"},{property:"analytics",name:"Analytics",tooltip:"Get a clear picture of what users see and search for\u2014page views, search trends, and AI-powered query details"}],u=[{name:o.PRO,features:{reunite:!0,hasHosting:!0,projects:1,pages:100}},{name:o.ENTERPRISE,features:{pages:500,SSO:!0,guestSSO:!0,RBAC:!0,remoteContent:!0,aiSearch:!0,typesense:!0,analytics:!0}},{name:o.ENTERPRISE_PLUS,features:{residencyOptions:!0,salesAssistance:!0,forms:!0,securityQuestionnaires:!0,payByInvoice:!0,reviews:!0,singleTenant:!0,premiumSupport:!0}}],m=[r.MONTH,r.YEAR],n=[{tierStart:1,tierEnd:20},{tierStart:21,tierEnd:50},{tierStart:51,tierEnd:100},{tierStart:101,tierEnd:250},{tierStart:251,tierEnd:500},{tierStart:501,tierEnd:1e3},{tierStart:1001,tierEnd:1/0}],E={[i.ONE]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[24,21.6,19.2,16.8,15.6,14.4,13.2][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[264,237.6,211.2,184.8,171.6,158.4,145.2][t]}))},[i.TWO]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[48,43.2,38.4,33.6,31.2,28.8,26.4][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[528,475.2,422.4,369.6,343.2,316.8,290.4][t]}))},[i.REALM]:{[r.MONTH]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[66,59.4,52.8,46.2,42.9,39.6,36.3][t]})),[r.YEAR]:n.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[708,653.4,580.8,508.2,471.9,435.6,399.3][t]}))}},S={[i.ONE]:{[r.MONTH]:10,[r.YEAR]:108},[i.TWO]:{[r.MONTH]:20,[r.YEAR]:216},[i.REALM]:{[r.MONTH]:28,[r.YEAR]:300}},s=[{tierStart:1,tierEnd:500},{tierStart:501,tierEnd:1/0}],p=[{tierStart:1,tierEnd:100},{tierStart:101,tierEnd:1/0}],y={[o.PRO]:{[r.MONTH]:p.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:p.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))},[o.ENTERPRISE]:{[r.MONTH]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))},[o.ENTERPRISE_PLUS]:{[r.MONTH]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,.12][t]})),[r.YEAR]:s.map((e,t)=>({tierStart:e.tierStart,tierEnd:e.tierEnd,price:[0,1.44][t]}))}},g=49,f={[o.PRO]:1,[o.ENTERPRISE]:1,[o.ENTERPRISE_PLUS]:1};export{d as featuresList,y as pageIntervals,m as periodsList,u as plansList,g as pricePerProject,l as productItems,E as seatIntervals,S as seatProPlanIntervals,f as startNumOfProjectPerPlan};
@@ -1,4 +1,4 @@
1
- import e from"react";import t from"styled-components";import{breakpoints as n}from"@redocly/theme/core/utils";import{ResponsiveImg as o}from"../../../components/ImageComponents";const w=()=>e.createElement(l,null,e.createElement(m,null,e.createElement(s,null,e.createElement("img",{src:require("../images/line-5.svg")}),e.createElement(d,null),e.createElement("img",{src:require("../images/line-5.svg")})),e.createElement(c,null,"Transform API management")),e.createElement(p,null,e.createElement("div",{style:{minWidth:"240px",maxWidth:"724px",flex:1}},e.createElement(i,null,"Centralize with Confidence"),e.createElement(r,null,"Imagine a hub where all your API definitions, documentation, and versions coexist in harmony. Alongside all the important metadata that helps you categorize, track, and understand the who, what, where, and why of every API. Reef's centralized registry means fewer errors, enhanced collaboration, and a single source of truth accessible by everyone, anytime.")),e.createElement(g,null,e.createElement(o,{src:require("../images/cards-img.svg")}))),e.createElement(h,null,e.createElement(a,null,e.createElement(i,null,"Govern with Ease throughout the Lifecycle"),e.createElement(r,null,"Set a gold standard for your APIs with governance that blends seamlessly into your development process. With Reef, consistency and compliance are achieved without compromising on creativity, elevating the quality and security of your APIs.")),e.createElement(a,null,e.createElement(i,null,"Beyond Management: A Beacon of Innovation"),e.createElement(r,null,"Reef is more than a tool; it's your partner in bringing your API strategy to life. It's about making every API accessible, manageable, and primed for innovation, setting the stage for your ideas to flourish. It\u2019s about the experience of the consumers, publishers, and governors working together.")))),l=t.div``,m=t.div`
1
+ import e from"react";import t from"styled-components";import{breakpoints as n}from"@redocly/theme/core/utils";import{ResponsiveImg as o}from"../../../components/ImageComponents";const w=()=>e.createElement(l,null,e.createElement(m,null,e.createElement(s,null,e.createElement("img",{src:require("../images/line-5.svg")}),e.createElement(d,null),e.createElement("img",{src:require("../images/line-5.svg")})),e.createElement(c,null,"Transform API management")),e.createElement(p,null,e.createElement("div",{style:{minWidth:"240px",maxWidth:"724px",flex:1}},e.createElement(i,null,"Centralize with Confidence"),e.createElement(r,null,"Imagine a hub where all your API definitions, documentation, and versions coexist in harmony. Alongside all the important metadata that helps you categorize, track, and understand the who, what, where, and why of every API. Reef's centralized catalog means fewer errors, enhanced collaboration, and a single source of truth accessible by everyone, anytime.")),e.createElement(g,null,e.createElement(o,{src:require("../images/cards-img.svg")}))),e.createElement(h,null,e.createElement(a,null,e.createElement(i,null,"Govern with Ease throughout the Lifecycle"),e.createElement(r,null,"Set a gold standard for your APIs with governance that blends seamlessly into your development process. With Reef, consistency and compliance are achieved without compromising on creativity, elevating the quality and security of your APIs.")),e.createElement(a,null,e.createElement(i,null,"Beyond Management: A Beacon of Innovation"),e.createElement(r,null,"Reef is more than a tool; it's your partner in bringing your API strategy to life. It's about making every API accessible, manageable, and primed for innovation, setting the stage for your ideas to flourish. It\u2019s about the experience of the consumers, publishers, and governors working together.")))),l=t.div``,m=t.div`
2
2
  display: flex;
3
3
  align-items: center;
4
4
  `,s=t.div`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/marketing-pages",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "keywords": [],
5
5
  "author": "",
6
6
  "license": "UNLICENSED",
@@ -23,38 +23,44 @@
23
23
  "@codemirror/language": "^6.11.0",
24
24
  "@codemirror/legacy-modes": "^6.5.1",
25
25
  "@itseasy21/react-elastic-carousel": "^0.12.3",
26
+ "@monaco-editor/react": "^4.7.0",
26
27
  "@rebilly/lead-source-tracker": "^2.18.13",
27
28
  "@redocly/json-to-json-schema": "^0.0.1",
28
29
  "@uiw/react-codemirror": "^4.23.12",
29
30
  "dayjs": "^1.11.13",
30
31
  "framer-motion": "^12.10.5",
32
+ "highlight-words-core": "^1.2.3",
33
+ "html2canvas": "^1.4.1",
31
34
  "js-yaml": "^4.1.0",
35
+ "json-schema-to-ts": "^3.1.0",
36
+ "jspdf": "^3.0.2",
32
37
  "lottie-react": "^2.4.0",
38
+ "monaco-editor": "^0.53.0",
33
39
  "polished": "^4.2.2",
34
40
  "react-copy-to-clipboard": "^5.1.0",
35
41
  "react-helmet": "^6.1.0",
36
42
  "react-hook-form": "^7.56.3",
37
43
  "react-hubspot-form": "^1.3.7",
44
+ "react-resizable-panels": "^3.0.6",
38
45
  "react-responsive-carousel": "^3.2.23",
39
- "react-spring": "^9.7.3",
46
+ "react-spring": "^9.6.2",
40
47
  "react-tabs": "^6.1.0",
41
48
  "react-tooltip": "^4.2.21",
42
49
  "reactjs-popup": "^2.0.6",
50
+ "styled-system": "^5.1.5",
43
51
  "ulid": "^2.3.0",
44
- "vitest": "^3.1.3",
45
- "html2canvas": "^1.4.1",
46
- "jspdf": "^3.0.2",
47
- "json-schema-to-ts": "^3.1.0"
52
+ "vitest": "^3.1.3"
48
53
  },
49
54
  "peerDependencies": {
50
- "react": "^18.3.1",
51
- "react-dom": "^18.3.1",
55
+ "react": "^18.3.1 || ^19.0.0",
56
+ "react-dom": "^18.3.1 || ^19.0.0",
52
57
  "styled-components": ">=5.3.11"
53
58
  },
54
59
  "devDependencies": {
55
60
  "@changesets/cli": "^2.29.5",
56
61
  "@redocly/config": "^0.24.0",
57
62
  "@redocly/theme": "^0.53.0",
63
+ "@markdoc/markdoc": "0.5.1",
58
64
  "@shikijs/types": "3.4.0",
59
65
  "@types/js-yaml": "^4.0.9",
60
66
  "@types/node": "^22.15.17",