@apiboost/omnispec 1.0.0
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/LICENSE.md +202 -0
- package/README.md +166 -0
- package/core/package.json +5 -0
- package/dist/cjs/asyncapi/index.js +17 -0
- package/dist/cjs/asyncapi/index.js.map +1 -0
- package/dist/cjs/chunks/AsyncApiSpec-TBlyRxTP.js +819 -0
- package/dist/cjs/chunks/AsyncApiSpec-TBlyRxTP.js.map +1 -0
- package/dist/cjs/chunks/Collapsible-BHAHk_Ep.js +7527 -0
- package/dist/cjs/chunks/Collapsible-BHAHk_Ep.js.map +1 -0
- package/dist/cjs/chunks/ErrorBoundary-c1piU8da.js +36 -0
- package/dist/cjs/chunks/ErrorBoundary-c1piU8da.js.map +1 -0
- package/dist/cjs/chunks/OmniSpecRenderer-CE4wxVTL.js +104 -0
- package/dist/cjs/chunks/OmniSpecRenderer-CE4wxVTL.js.map +1 -0
- package/dist/cjs/chunks/OpenApiSpec-D0JtmOVQ.js +3157 -0
- package/dist/cjs/chunks/OpenApiSpec-D0JtmOVQ.js.map +1 -0
- package/dist/cjs/chunks/OpenIdConnectManual-oEnN0QJ-.js +2416 -0
- package/dist/cjs/chunks/OpenIdConnectManual-oEnN0QJ-.js.map +1 -0
- package/dist/cjs/chunks/RendererRegistry-DQ7JBLMT.js +24 -0
- package/dist/cjs/chunks/RendererRegistry-DQ7JBLMT.js.map +1 -0
- package/dist/cjs/chunks/binary-response-CSrPCI-1.js +77 -0
- package/dist/cjs/chunks/binary-response-CSrPCI-1.js.map +1 -0
- package/dist/cjs/chunks/ref-resolver-DWu6Q6E5.js +7108 -0
- package/dist/cjs/chunks/ref-resolver-DWu6Q6E5.js.map +1 -0
- package/dist/cjs/chunks/ssrf-guard-B6T2A7Ho.js +25 -0
- package/dist/cjs/chunks/ssrf-guard-B6T2A7Ho.js.map +1 -0
- package/dist/cjs/chunks/useSpecDetector-A4OwYrmY.js +252 -0
- package/dist/cjs/chunks/useSpecDetector-A4OwYrmY.js.map +1 -0
- package/dist/cjs/chunks/useSpecFetcher-BKz1jHTV.js +13669 -0
- package/dist/cjs/chunks/useSpecFetcher-BKz1jHTV.js.map +1 -0
- package/dist/cjs/core/public.js +198 -0
- package/dist/cjs/core/public.js.map +1 -0
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/openapi/index.js +19 -0
- package/dist/cjs/openapi/index.js.map +1 -0
- package/dist/cjs/server/index.js +154 -0
- package/dist/cjs/server/index.js.map +1 -0
- package/dist/cjs/wc/index.js +428 -0
- package/dist/cjs/wc/index.js.map +1 -0
- package/dist/esm/asyncapi/index.js +11 -0
- package/dist/esm/asyncapi/index.js.map +1 -0
- package/dist/esm/chunks/AsyncApiSpec-C3lsUpZk.js +817 -0
- package/dist/esm/chunks/AsyncApiSpec-C3lsUpZk.js.map +1 -0
- package/dist/esm/chunks/Collapsible-DA6-nS46.js +7482 -0
- package/dist/esm/chunks/Collapsible-DA6-nS46.js.map +1 -0
- package/dist/esm/chunks/ErrorBoundary-posRNrbt.js +34 -0
- package/dist/esm/chunks/ErrorBoundary-posRNrbt.js.map +1 -0
- package/dist/esm/chunks/OmniSpecRenderer-MqsQFXro.js +102 -0
- package/dist/esm/chunks/OmniSpecRenderer-MqsQFXro.js.map +1 -0
- package/dist/esm/chunks/OpenApiSpec-Cy-oW6jA.js +3153 -0
- package/dist/esm/chunks/OpenApiSpec-Cy-oW6jA.js.map +1 -0
- package/dist/esm/chunks/OpenIdConnectManual-COfITasf.js +2393 -0
- package/dist/esm/chunks/OpenIdConnectManual-COfITasf.js.map +1 -0
- package/dist/esm/chunks/RendererRegistry-zlh-WYbU.js +21 -0
- package/dist/esm/chunks/RendererRegistry-zlh-WYbU.js.map +1 -0
- package/dist/esm/chunks/binary-response-Cre_H-Rt.js +72 -0
- package/dist/esm/chunks/binary-response-Cre_H-Rt.js.map +1 -0
- package/dist/esm/chunks/ref-resolver-BIrHJOjz.js +7105 -0
- package/dist/esm/chunks/ref-resolver-BIrHJOjz.js.map +1 -0
- package/dist/esm/chunks/ssrf-guard-CsZoYdEq.js +23 -0
- package/dist/esm/chunks/ssrf-guard-CsZoYdEq.js.map +1 -0
- package/dist/esm/chunks/useSpecDetector-5SGcKnJx.js +248 -0
- package/dist/esm/chunks/useSpecDetector-5SGcKnJx.js.map +1 -0
- package/dist/esm/chunks/useSpecFetcher-CZvAnU7Z.js +13625 -0
- package/dist/esm/chunks/useSpecFetcher-CZvAnU7Z.js.map +1 -0
- package/dist/esm/core/public.js +102 -0
- package/dist/esm/core/public.js.map +1 -0
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/openapi/index.js +13 -0
- package/dist/esm/openapi/index.js.map +1 -0
- package/dist/esm/server/index.js +152 -0
- package/dist/esm/server/index.js.map +1 -0
- package/dist/esm/wc/index.js +403 -0
- package/dist/esm/wc/index.js.map +1 -0
- package/dist/types/asyncapi/AsyncApiSpec.d.ts +12 -0
- package/dist/types/asyncapi/AsyncApiSpec.d.ts.map +1 -0
- package/dist/types/asyncapi/components/AsyncOverview.d.ts +16 -0
- package/dist/types/asyncapi/components/AsyncOverview.d.ts.map +1 -0
- package/dist/types/asyncapi/components/ChannelDetail.d.ts +19 -0
- package/dist/types/asyncapi/components/ChannelDetail.d.ts.map +1 -0
- package/dist/types/asyncapi/components/ComponentsSection.d.ts +16 -0
- package/dist/types/asyncapi/components/ComponentsSection.d.ts.map +1 -0
- package/dist/types/asyncapi/components/ProtocolBadge.d.ts +16 -0
- package/dist/types/asyncapi/components/ProtocolBadge.d.ts.map +1 -0
- package/dist/types/asyncapi/components/ServerList.d.ts +16 -0
- package/dist/types/asyncapi/components/ServerList.d.ts.map +1 -0
- package/dist/types/asyncapi/hooks/useAsyncApiSpec.d.ts +12 -0
- package/dist/types/asyncapi/hooks/useAsyncApiSpec.d.ts.map +1 -0
- package/dist/types/asyncapi/index.d.ts +11 -0
- package/dist/types/asyncapi/index.d.ts.map +1 -0
- package/dist/types/asyncapi/parser/asyncapi-parser.d.ts +12 -0
- package/dist/types/asyncapi/parser/asyncapi-parser.d.ts.map +1 -0
- package/dist/types/asyncapi/types/asyncapi.types.d.ts +125 -0
- package/dist/types/asyncapi/types/asyncapi.types.d.ts.map +1 -0
- package/dist/types/core/components/Auth/ApiKeyAuth.d.ts +30 -0
- package/dist/types/core/components/Auth/ApiKeyAuth.d.ts.map +1 -0
- package/dist/types/core/components/Auth/AuthPanel.d.ts +18 -0
- package/dist/types/core/components/Auth/AuthPanel.d.ts.map +1 -0
- package/dist/types/core/components/Auth/AuthPanelModal.d.ts +24 -0
- package/dist/types/core/components/Auth/AuthPanelModal.d.ts.map +1 -0
- package/dist/types/core/components/Auth/BasicAuth.d.ts +20 -0
- package/dist/types/core/components/Auth/BasicAuth.d.ts.map +1 -0
- package/dist/types/core/components/Auth/BearerAuth.d.ts +20 -0
- package/dist/types/core/components/Auth/BearerAuth.d.ts.map +1 -0
- package/dist/types/core/components/Auth/OAuth2AuthManual.d.ts +37 -0
- package/dist/types/core/components/Auth/OAuth2AuthManual.d.ts.map +1 -0
- package/dist/types/core/components/Auth/OpenIdConnectManual.d.ts +33 -0
- package/dist/types/core/components/Auth/OpenIdConnectManual.d.ts.map +1 -0
- package/dist/types/core/components/Auth/SecretInput.d.ts +27 -0
- package/dist/types/core/components/Auth/SecretInput.d.ts.map +1 -0
- package/dist/types/core/components/Auth/index.d.ts +16 -0
- package/dist/types/core/components/Auth/index.d.ts.map +1 -0
- package/dist/types/core/components/CodeBlock/CodeBlock.d.ts +32 -0
- package/dist/types/core/components/CodeBlock/CodeBlock.d.ts.map +1 -0
- package/dist/types/core/components/CodeBlock/index.d.ts +12 -0
- package/dist/types/core/components/CodeBlock/index.d.ts.map +1 -0
- package/dist/types/core/components/Layout/DocLayout.d.ts +24 -0
- package/dist/types/core/components/Layout/DocLayout.d.ts.map +1 -0
- package/dist/types/core/components/Layout/MobileDrawerDismissContext.d.ts +20 -0
- package/dist/types/core/components/Layout/MobileDrawerDismissContext.d.ts.map +1 -0
- package/dist/types/core/components/Layout/SpecStatusScreen.d.ts +38 -0
- package/dist/types/core/components/Layout/SpecStatusScreen.d.ts.map +1 -0
- package/dist/types/core/components/Layout/index.d.ts +11 -0
- package/dist/types/core/components/Layout/index.d.ts.map +1 -0
- package/dist/types/core/components/MarkdownRenderer/MarkdownRenderer.d.ts +16 -0
- package/dist/types/core/components/MarkdownRenderer/MarkdownRenderer.d.ts.map +1 -0
- package/dist/types/core/components/MarkdownRenderer/index.d.ts +11 -0
- package/dist/types/core/components/MarkdownRenderer/index.d.ts.map +1 -0
- package/dist/types/core/components/Navigation/CustomNavSection.d.ts +16 -0
- package/dist/types/core/components/Navigation/CustomNavSection.d.ts.map +1 -0
- package/dist/types/core/components/Navigation/NavTree.d.ts +32 -0
- package/dist/types/core/components/Navigation/NavTree.d.ts.map +1 -0
- package/dist/types/core/components/Navigation/SearchBar.d.ts +16 -0
- package/dist/types/core/components/Navigation/SearchBar.d.ts.map +1 -0
- package/dist/types/core/components/Navigation/buildSidebar.d.ts +13 -0
- package/dist/types/core/components/Navigation/buildSidebar.d.ts.map +1 -0
- package/dist/types/core/components/Navigation/index.d.ts +13 -0
- package/dist/types/core/components/Navigation/index.d.ts.map +1 -0
- package/dist/types/core/components/Reference/ReferenceLayout.d.ts +19 -0
- package/dist/types/core/components/Reference/ReferenceLayout.d.ts.map +1 -0
- package/dist/types/core/components/Reference/ReferenceOperationDetail.d.ts +42 -0
- package/dist/types/core/components/Reference/ReferenceOperationDetail.d.ts.map +1 -0
- package/dist/types/core/components/Reference/SamplesPanel.d.ts +33 -0
- package/dist/types/core/components/Reference/SamplesPanel.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/SchemaPresentation.d.ts +147 -0
- package/dist/types/core/components/SchemaViewer/SchemaPresentation.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/SchemaPrimitives.d.ts +66 -0
- package/dist/types/core/components/SchemaViewer/SchemaPrimitives.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/SchemaTable.d.ts +16 -0
- package/dist/types/core/components/SchemaViewer/SchemaTable.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/SchemaTree.d.ts +26 -0
- package/dist/types/core/components/SchemaViewer/SchemaTree.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/index.d.ts +16 -0
- package/dist/types/core/components/SchemaViewer/index.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/schema-style.d.ts +45 -0
- package/dist/types/core/components/SchemaViewer/schema-style.d.ts.map +1 -0
- package/dist/types/core/components/SchemaViewer/schema-utils.d.ts +83 -0
- package/dist/types/core/components/SchemaViewer/schema-utils.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/CodeSamples.d.ts +26 -0
- package/dist/types/core/components/TryIt/CodeSamples.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/CustomHeaders.d.ts +24 -0
- package/dist/types/core/components/TryIt/CustomHeaders.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/InlineTryIt.d.ts +26 -0
- package/dist/types/core/components/TryIt/InlineTryIt.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/ParameterForm.d.ts +34 -0
- package/dist/types/core/components/TryIt/ParameterForm.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/RequestBodyEditor.d.ts +34 -0
- package/dist/types/core/components/TryIt/RequestBodyEditor.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/ResponseViewer.d.ts +18 -0
- package/dist/types/core/components/TryIt/ResponseViewer.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/TryItPanel.d.ts +38 -0
- package/dist/types/core/components/TryIt/TryItPanel.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/code-generators.d.ts +23 -0
- package/dist/types/core/components/TryIt/code-generators.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/curl-generator.d.ts +12 -0
- package/dist/types/core/components/TryIt/curl-generator.d.ts.map +1 -0
- package/dist/types/core/components/TryIt/index.d.ts +16 -0
- package/dist/types/core/components/TryIt/index.d.ts.map +1 -0
- package/dist/types/core/components/common/Badge.d.ts +19 -0
- package/dist/types/core/components/common/Badge.d.ts.map +1 -0
- package/dist/types/core/components/common/Button.d.ts +44 -0
- package/dist/types/core/components/common/Button.d.ts.map +1 -0
- package/dist/types/core/components/common/Collapsible.d.ts +23 -0
- package/dist/types/core/components/common/Collapsible.d.ts.map +1 -0
- package/dist/types/core/components/common/CopyButton.d.ts +16 -0
- package/dist/types/core/components/common/CopyButton.d.ts.map +1 -0
- package/dist/types/core/components/common/ErrorBoundary.d.ts +40 -0
- package/dist/types/core/components/common/ErrorBoundary.d.ts.map +1 -0
- package/dist/types/core/components/common/ErrorMessage.d.ts +16 -0
- package/dist/types/core/components/common/ErrorMessage.d.ts.map +1 -0
- package/dist/types/core/components/common/ExampleSelector.d.ts +29 -0
- package/dist/types/core/components/common/ExampleSelector.d.ts.map +1 -0
- package/dist/types/core/components/common/ExpandableCard.d.ts +27 -0
- package/dist/types/core/components/common/ExpandableCard.d.ts.map +1 -0
- package/dist/types/core/components/common/Icon.d.ts +53 -0
- package/dist/types/core/components/common/Icon.d.ts.map +1 -0
- package/dist/types/core/components/common/LinkableHeading.d.ts +19 -0
- package/dist/types/core/components/common/LinkableHeading.d.ts.map +1 -0
- package/dist/types/core/components/common/LoadingScreen.d.ts +13 -0
- package/dist/types/core/components/common/LoadingScreen.d.ts.map +1 -0
- package/dist/types/core/components/common/MethodBar.d.ts +18 -0
- package/dist/types/core/components/common/MethodBar.d.ts.map +1 -0
- package/dist/types/core/components/common/Modal.d.ts +19 -0
- package/dist/types/core/components/common/Modal.d.ts.map +1 -0
- package/dist/types/core/components/common/ResponsiveColumns.d.ts +17 -0
- package/dist/types/core/components/common/ResponsiveColumns.d.ts.map +1 -0
- package/dist/types/core/components/common/SpecToolbar.d.ts +27 -0
- package/dist/types/core/components/common/SpecToolbar.d.ts.map +1 -0
- package/dist/types/core/components/common/Tabs.d.ts +29 -0
- package/dist/types/core/components/common/Tabs.d.ts.map +1 -0
- package/dist/types/core/components/common/Tooltip.d.ts +17 -0
- package/dist/types/core/components/common/Tooltip.d.ts.map +1 -0
- package/dist/types/core/components/common/UpgradePrompt.d.ts +18 -0
- package/dist/types/core/components/common/UpgradePrompt.d.ts.map +1 -0
- package/dist/types/core/components/common/index.d.ts +18 -0
- package/dist/types/core/components/common/index.d.ts.map +1 -0
- package/dist/types/core/context/AuthContext.d.ts +35 -0
- package/dist/types/core/context/AuthContext.d.ts.map +1 -0
- package/dist/types/core/context/ConfigContext.d.ts +55 -0
- package/dist/types/core/context/ConfigContext.d.ts.map +1 -0
- package/dist/types/core/context/ExpandContext.d.ts +33 -0
- package/dist/types/core/context/ExpandContext.d.ts.map +1 -0
- package/dist/types/core/context/RendererRegistry.d.ts +24 -0
- package/dist/types/core/context/RendererRegistry.d.ts.map +1 -0
- package/dist/types/core/context/index.d.ts +14 -0
- package/dist/types/core/context/index.d.ts.map +1 -0
- package/dist/types/core/hooks/index.d.ts +12 -0
- package/dist/types/core/hooks/index.d.ts.map +1 -0
- package/dist/types/core/hooks/useHashScroll.d.ts +15 -0
- package/dist/types/core/hooks/useHashScroll.d.ts.map +1 -0
- package/dist/types/core/hooks/useScrollSpy.d.ts +33 -0
- package/dist/types/core/hooks/useScrollSpy.d.ts.map +1 -0
- package/dist/types/core/hooks/useSegmentedRouter.d.ts +19 -0
- package/dist/types/core/hooks/useSegmentedRouter.d.ts.map +1 -0
- package/dist/types/core/hooks/useSpecDetector.d.ts +13 -0
- package/dist/types/core/hooks/useSpecDetector.d.ts.map +1 -0
- package/dist/types/core/hooks/useSpecFetcher.d.ts +17 -0
- package/dist/types/core/hooks/useSpecFetcher.d.ts.map +1 -0
- package/dist/types/core/public.d.ts +86 -0
- package/dist/types/core/public.d.ts.map +1 -0
- package/dist/types/core/styles/breakpoints.d.ts +33 -0
- package/dist/types/core/styles/breakpoints.d.ts.map +1 -0
- package/dist/types/core/styles/css.d.ts +17 -0
- package/dist/types/core/styles/css.d.ts.map +1 -0
- package/dist/types/core/styles/styled.d.ts +25 -0
- package/dist/types/core/styles/styled.d.ts.map +1 -0
- package/dist/types/core/themes/ThemeProvider.d.ts +25 -0
- package/dist/types/core/themes/ThemeProvider.d.ts.map +1 -0
- package/dist/types/core/themes/index.d.ts +12 -0
- package/dist/types/core/themes/index.d.ts.map +1 -0
- package/dist/types/core/themes/tokens.d.ts +13 -0
- package/dist/types/core/themes/tokens.d.ts.map +1 -0
- package/dist/types/core/types/auth.types.d.ts +83 -0
- package/dist/types/core/types/auth.types.d.ts.map +1 -0
- package/dist/types/core/types/common.types.d.ts +141 -0
- package/dist/types/core/types/common.types.d.ts.map +1 -0
- package/dist/types/core/types/index.d.ts +16 -0
- package/dist/types/core/types/index.d.ts.map +1 -0
- package/dist/types/core/types/interactive-auth.types.d.ts +37 -0
- package/dist/types/core/types/interactive-auth.types.d.ts.map +1 -0
- package/dist/types/core/types/sidebar-nav.types.d.ts +41 -0
- package/dist/types/core/types/sidebar-nav.types.d.ts.map +1 -0
- package/dist/types/core/types/spec-detection.types.d.ts +26 -0
- package/dist/types/core/types/spec-detection.types.d.ts.map +1 -0
- package/dist/types/core/types/theme.types.d.ts +119 -0
- package/dist/types/core/types/theme.types.d.ts.map +1 -0
- package/dist/types/core/types/try-it.types.d.ts +50 -0
- package/dist/types/core/types/try-it.types.d.ts.map +1 -0
- package/dist/types/core/utils/binary-response.d.ts +24 -0
- package/dist/types/core/utils/binary-response.d.ts.map +1 -0
- package/dist/types/core/utils/detect-spec.d.ts +12 -0
- package/dist/types/core/utils/detect-spec.d.ts.map +1 -0
- package/dist/types/core/utils/direct-client.d.ts +20 -0
- package/dist/types/core/utils/direct-client.d.ts.map +1 -0
- package/dist/types/core/utils/fetch-spec.d.ts +15 -0
- package/dist/types/core/utils/fetch-spec.d.ts.map +1 -0
- package/dist/types/core/utils/index.d.ts +14 -0
- package/dist/types/core/utils/index.d.ts.map +1 -0
- package/dist/types/core/utils/proxy-client.d.ts +19 -0
- package/dist/types/core/utils/proxy-client.d.ts.map +1 -0
- package/dist/types/core/utils/ref-security.d.ts +78 -0
- package/dist/types/core/utils/ref-security.d.ts.map +1 -0
- package/dist/types/core/utils/resolve-download-link.d.ts +23 -0
- package/dist/types/core/utils/resolve-download-link.d.ts.map +1 -0
- package/dist/types/core/utils/sanitize-html.d.ts +16 -0
- package/dist/types/core/utils/sanitize-html.d.ts.map +1 -0
- package/dist/types/core/utils/tryit-storage.d.ts +45 -0
- package/dist/types/core/utils/tryit-storage.d.ts.map +1 -0
- package/dist/types/index.d.ts +29 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/openapi/OpenApiSpec.d.ts +12 -0
- package/dist/types/openapi/OpenApiSpec.d.ts.map +1 -0
- package/dist/types/openapi/components/ApiOverview.d.ts +19 -0
- package/dist/types/openapi/components/ApiOverview.d.ts.map +1 -0
- package/dist/types/openapi/components/CallbacksSection.d.ts +19 -0
- package/dist/types/openapi/components/CallbacksSection.d.ts.map +1 -0
- package/dist/types/openapi/components/ComponentsSection.d.ts +19 -0
- package/dist/types/openapi/components/ComponentsSection.d.ts.map +1 -0
- package/dist/types/openapi/components/EndpointCard.d.ts +20 -0
- package/dist/types/openapi/components/EndpointCard.d.ts.map +1 -0
- package/dist/types/openapi/components/OperationDetail.d.ts +28 -0
- package/dist/types/openapi/components/OperationDetail.d.ts.map +1 -0
- package/dist/types/openapi/components/OperationView.d.ts +19 -0
- package/dist/types/openapi/components/OperationView.d.ts.map +1 -0
- package/dist/types/openapi/components/SegmentedContent.d.ts +22 -0
- package/dist/types/openapi/components/SegmentedContent.d.ts.map +1 -0
- package/dist/types/openapi/components/ServerSelector.d.ts +18 -0
- package/dist/types/openapi/components/ServerSelector.d.ts.map +1 -0
- package/dist/types/openapi/components/TagGroup.d.ts +19 -0
- package/dist/types/openapi/components/TagGroup.d.ts.map +1 -0
- package/dist/types/openapi/hooks/useOpenApiSpec.d.ts +13 -0
- package/dist/types/openapi/hooks/useOpenApiSpec.d.ts.map +1 -0
- package/dist/types/openapi/index.d.ts +11 -0
- package/dist/types/openapi/index.d.ts.map +1 -0
- package/dist/types/openapi/parser/openapi-parser.d.ts +13 -0
- package/dist/types/openapi/parser/openapi-parser.d.ts.map +1 -0
- package/dist/types/openapi/parser/ref-resolver.d.ts +18 -0
- package/dist/types/openapi/parser/ref-resolver.d.ts.map +1 -0
- package/dist/types/openapi/search.d.ts +16 -0
- package/dist/types/openapi/search.d.ts.map +1 -0
- package/dist/types/openapi/types/openapi.types.d.ts +139 -0
- package/dist/types/openapi/types/openapi.types.d.ts.map +1 -0
- package/dist/types/server/index.d.ts +12 -0
- package/dist/types/server/index.d.ts.map +1 -0
- package/dist/types/server/proxy-router.d.ts +44 -0
- package/dist/types/server/proxy-router.d.ts.map +1 -0
- package/dist/types/server/ssrf-guard.d.ts +20 -0
- package/dist/types/server/ssrf-guard.d.ts.map +1 -0
- package/dist/types/test-setup.d.ts +11 -0
- package/dist/types/test-setup.d.ts.map +1 -0
- package/dist/types/unified/OmniSpecRenderer.d.ts +18 -0
- package/dist/types/unified/OmniSpecRenderer.d.ts.map +1 -0
- package/dist/types/unified/index.d.ts +12 -0
- package/dist/types/unified/index.d.ts.map +1 -0
- package/dist/types/wc/OmniSpecRendererElement.d.ts +48 -0
- package/dist/types/wc/OmniSpecRendererElement.d.ts.map +1 -0
- package/dist/types/wc/attribute-bridge.d.ts +96 -0
- package/dist/types/wc/attribute-bridge.d.ts.map +1 -0
- package/dist/types/wc/index.d.ts +42 -0
- package/dist/types/wc/index.d.ts.map +1 -0
- package/dist/types/wc/style-injection.d.ts +24 -0
- package/dist/types/wc/style-injection.d.ts.map +1 -0
- package/dist/wc/standalone.js +3 -0
- package/dist/wc/standalone.js.LICENSE.txt +65 -0
- package/dist/wc/standalone.js.map +1 -0
- package/package.json +167 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export { B as Button, C as ConfigProvider, c as CustomNavSection, D as DEFAULT_SCHEMA_STYLE, e as DocLayout, E as ErrorMessage, F as FREE_SCHEMA_STYLES, I as Icon, L as LoadingScreen, N as NavTree, b as SpecStatusScreen, S as SpecType, T as ThemeProvider, g as breakpoints, h as buildSidebar, d as darkTheme, f as fetchSpec, i as isSidebarNavGroup, l as lightTheme, m as mq, r as resolveSchemaStyle, j as useConfig, a as useSpecFetcher, u as useTheme } from '../chunks/useSpecFetcher-CZvAnU7Z.js';
|
|
2
|
+
export { A as AuthProvider, C as CodeSamples, L as LinkableHeading, M as Modal, O as OAuth2AuthManual, a as OpenIdConnectManual, R as ReferenceLayout, b as ReferenceOperationDetail, c as ResponseViewer, d as ResponsiveColumns, S as SamplesPanel, e as SecretInput, f as authStyles, s as sendDirectRequest, g as sendProxiedRequest, u as useAuth } from '../chunks/OpenIdConnectManual-COfITasf.js';
|
|
3
|
+
export { R as RendererRegistryProvider, u as useRendererRegistry } from '../chunks/RendererRegistry-zlh-WYbU.js';
|
|
4
|
+
export { B as Badge, C as CodeBlock, a as Collapsible, E as EnumItem, b as EnumLabel, c as EnumList, d as ExpandableCard, F as FieldDescription, e as FieldName, M as MarkdownRenderer, f as MethodBar, P as PresentationChildren, g as PresentationContainer, h as PresentationRow, i as PropDefault, j as PropDesc, k as PropFormat, l as PropName, m as PropReq, n as PropRequiredStar, o as PropType, S as SchemaBadge, p as SchemaPropChildren, q as SchemaPropRow, r as SchemaRefLink, s as SchemaSectionTitle, t as SchemaTree, u as SearchBar, v as SpecToolbar, T as Tabs, w as flattenNavItemIds, x as generateExample, y as requestExpand, z as resolveDownloadLink, A as schemaToNodes, D as useHashScroll, G as useScrollSpy } from '../chunks/Collapsible-DA6-nS46.js';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
import { useState, useCallback, useRef } from 'react';
|
|
7
|
+
import { css } from '@emotion/css';
|
|
8
|
+
export { css, cx, keyframes } from '@emotion/css';
|
|
9
|
+
export { U as UpgradePrompt, d as detectSpecType, u as useSpecDetector } from '../chunks/useSpecDetector-5SGcKnJx.js';
|
|
10
|
+
import '../chunks/binary-response-Cre_H-Rt.js';
|
|
11
|
+
import '@emotion/styled';
|
|
12
|
+
|
|
13
|
+
const copyBtnStyle = css({
|
|
14
|
+
background: "none",
|
|
15
|
+
border: "1px solid var(--omnispec-border-color)",
|
|
16
|
+
borderRadius: "var(--omnispec-border-radius)",
|
|
17
|
+
padding: "4px 10px",
|
|
18
|
+
fontSize: "var(--omnispec-font-size-xs)",
|
|
19
|
+
color: "var(--omnispec-fg-secondary)",
|
|
20
|
+
cursor: "pointer",
|
|
21
|
+
"&:hover": {
|
|
22
|
+
color: "var(--omnispec-fg-primary)",
|
|
23
|
+
borderColor: "var(--omnispec-fg-muted)"
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
function CopyButton({ text, label = "Copy" }) {
|
|
27
|
+
const [copied, setCopied] = useState(false);
|
|
28
|
+
const handleCopy = useCallback(async () => {
|
|
29
|
+
await navigator.clipboard.writeText(text);
|
|
30
|
+
setCopied(true);
|
|
31
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
32
|
+
}, [text]);
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
"button",
|
|
35
|
+
{
|
|
36
|
+
type: "button",
|
|
37
|
+
onClick: handleCopy,
|
|
38
|
+
className: copyBtnStyle,
|
|
39
|
+
"aria-label": label,
|
|
40
|
+
children: copied ? "Copied!" : label
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const wrapperStyle = css({
|
|
46
|
+
position: "relative",
|
|
47
|
+
display: "inline-block"
|
|
48
|
+
});
|
|
49
|
+
const tipStyle = css({
|
|
50
|
+
position: "fixed",
|
|
51
|
+
padding: "4px 8px",
|
|
52
|
+
backgroundColor: "var(--omnispec-fg-primary)",
|
|
53
|
+
color: "var(--omnispec-bg-primary)",
|
|
54
|
+
fontSize: "var(--omnispec-font-size-xs)",
|
|
55
|
+
borderRadius: "4px",
|
|
56
|
+
whiteSpace: "nowrap",
|
|
57
|
+
zIndex: 9999,
|
|
58
|
+
pointerEvents: "none"
|
|
59
|
+
});
|
|
60
|
+
function Tooltip({ content, children }) {
|
|
61
|
+
const [visible, setVisible] = useState(false);
|
|
62
|
+
const [pos, setPos] = useState({ top: 0, left: 0 });
|
|
63
|
+
const wrapperRef = useRef(null);
|
|
64
|
+
const handleEnter = useCallback(() => {
|
|
65
|
+
if (wrapperRef.current) {
|
|
66
|
+
const rect = wrapperRef.current.getBoundingClientRect();
|
|
67
|
+
setPos({
|
|
68
|
+
top: rect.top - 6,
|
|
69
|
+
left: rect.left + rect.width / 2
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
setVisible(true);
|
|
73
|
+
}, []);
|
|
74
|
+
return /* @__PURE__ */ jsxs(
|
|
75
|
+
"span",
|
|
76
|
+
{
|
|
77
|
+
ref: wrapperRef,
|
|
78
|
+
className: `omnispec-tooltip ${wrapperStyle}`,
|
|
79
|
+
onMouseEnter: handleEnter,
|
|
80
|
+
onMouseLeave: () => setVisible(false),
|
|
81
|
+
children: [
|
|
82
|
+
children,
|
|
83
|
+
visible && /* @__PURE__ */ jsx(
|
|
84
|
+
"span",
|
|
85
|
+
{
|
|
86
|
+
className: tipStyle,
|
|
87
|
+
role: "tooltip",
|
|
88
|
+
style: {
|
|
89
|
+
top: pos.top,
|
|
90
|
+
left: pos.left,
|
|
91
|
+
transform: "translate(-50%, -100%)"
|
|
92
|
+
},
|
|
93
|
+
children: content
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { CopyButton, Tooltip };
|
|
102
|
+
//# sourceMappingURL=public.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sources":["../../../src/core/components/common/CopyButton.tsx","../../../src/core/components/common/Tooltip.tsx"],"sourcesContent":["/**\n * This source file is part of the Apiboost(R) OmniSpec Core.\n *\n * Copyright (c) Apiboost, Inc.\n *\n * SPDX-License-Identifier: Apache-2.0\n *\n * See LICENSE.md and LICENSING.md in the project root for license information.\n */\n\nimport { useCallback, useState } from 'react'\nimport { css } from '../../styles/css'\n\ninterface CopyButtonProps {\n text: string\n label?: string\n}\n\nconst copyBtnStyle = css({\n background: 'none',\n border: '1px solid var(--omnispec-border-color)',\n borderRadius: 'var(--omnispec-border-radius)',\n padding: '4px 10px',\n fontSize: 'var(--omnispec-font-size-xs)',\n color: 'var(--omnispec-fg-secondary)',\n cursor: 'pointer',\n '&:hover': {\n color: 'var(--omnispec-fg-primary)',\n borderColor: 'var(--omnispec-fg-muted)',\n },\n})\n\nexport function CopyButton({ text, label = 'Copy' }: CopyButtonProps) {\n const [copied, setCopied] = useState(false)\n\n const handleCopy = useCallback(async () => {\n await navigator.clipboard.writeText(text)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n }, [text])\n\n return (\n <button\n type=\"button\"\n onClick={handleCopy}\n className={copyBtnStyle}\n aria-label={label}\n >\n {copied ? 'Copied!' : label}\n </button>\n )\n}\n","/**\n * This source file is part of the Apiboost(R) OmniSpec Core.\n *\n * Copyright (c) Apiboost, Inc.\n *\n * SPDX-License-Identifier: Apache-2.0\n *\n * See LICENSE.md and LICENSING.md in the project root for license information.\n */\n\nimport { useCallback, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { css } from '../../styles/css'\n\ninterface TooltipProps {\n content: string\n children: ReactNode\n}\n\nconst wrapperStyle = css({\n position: 'relative',\n display: 'inline-block',\n})\n\nconst tipStyle = css({\n position: 'fixed',\n padding: '4px 8px',\n backgroundColor: 'var(--omnispec-fg-primary)',\n color: 'var(--omnispec-bg-primary)',\n fontSize: 'var(--omnispec-font-size-xs)',\n borderRadius: '4px',\n whiteSpace: 'nowrap',\n zIndex: 9999,\n pointerEvents: 'none',\n})\n\nexport function Tooltip({ content, children }: TooltipProps) {\n const [visible, setVisible] = useState(false)\n const [pos, setPos] = useState({ top: 0, left: 0 })\n const wrapperRef = useRef<HTMLSpanElement>(null)\n\n const handleEnter = useCallback(() => {\n if (wrapperRef.current) {\n const rect = wrapperRef.current.getBoundingClientRect()\n setPos({\n top: rect.top - 6,\n left: rect.left + rect.width / 2,\n })\n }\n setVisible(true)\n }, [])\n\n return (\n <span\n ref={wrapperRef}\n className={`omnispec-tooltip ${wrapperStyle}`}\n onMouseEnter={handleEnter}\n onMouseLeave={() => setVisible(false)}\n >\n {children}\n {visible && (\n <span\n className={tipStyle}\n role=\"tooltip\"\n style={{\n top: pos.top,\n left: pos.left,\n transform: 'translate(-50%, -100%)',\n }}\n >\n {content}\n </span>\n )}\n </span>\n )\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { O as OpenApiSpec, a as authSchemeLabel } from './chunks/OpenApiSpec-Cy-oW6jA.js';
|
|
2
|
+
export { AsyncApiSpec } from './chunks/AsyncApiSpec-C3lsUpZk.js';
|
|
3
|
+
export { O as OmniSpecRenderer } from './chunks/OmniSpecRenderer-MqsQFXro.js';
|
|
4
|
+
export { R as RendererRegistryProvider, u as useRendererRegistry } from './chunks/RendererRegistry-zlh-WYbU.js';
|
|
5
|
+
export { S as SpecType, T as ThemeProvider, d as darkTheme, f as fetchSpec, i as isSidebarNavGroup, l as lightTheme, u as useTheme } from './chunks/useSpecFetcher-CZvAnU7Z.js';
|
|
6
|
+
export { d as detectSpecType } from './chunks/useSpecDetector-5SGcKnJx.js';
|
|
7
|
+
import 'react/jsx-runtime';
|
|
8
|
+
import 'react';
|
|
9
|
+
import '@emotion/css';
|
|
10
|
+
import './chunks/Collapsible-DA6-nS46.js';
|
|
11
|
+
import '@emotion/styled';
|
|
12
|
+
import './chunks/OpenIdConnectManual-COfITasf.js';
|
|
13
|
+
import './chunks/binary-response-Cre_H-Rt.js';
|
|
14
|
+
import './chunks/ref-resolver-BIrHJOjz.js';
|
|
15
|
+
import './chunks/ssrf-guard-CsZoYdEq.js';
|
|
16
|
+
import './chunks/ErrorBoundary-posRNrbt.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { O as OpenApiSpec } from '../chunks/OpenApiSpec-Cy-oW6jA.js';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
import 'react';
|
|
4
|
+
import '@emotion/css';
|
|
5
|
+
import '../chunks/useSpecFetcher-CZvAnU7Z.js';
|
|
6
|
+
import '../chunks/Collapsible-DA6-nS46.js';
|
|
7
|
+
import '@emotion/styled';
|
|
8
|
+
import '../chunks/OpenIdConnectManual-COfITasf.js';
|
|
9
|
+
import '../chunks/binary-response-Cre_H-Rt.js';
|
|
10
|
+
import '../chunks/ref-resolver-BIrHJOjz.js';
|
|
11
|
+
import '../chunks/ssrf-guard-CsZoYdEq.js';
|
|
12
|
+
import '../chunks/ErrorBoundary-posRNrbt.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { i as isPrivateIp } from '../chunks/ssrf-guard-CsZoYdEq.js';
|
|
3
|
+
import { i as isBinaryContentType } from '../chunks/binary-response-Cre_H-Rt.js';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_RATE_LIMIT = 60;
|
|
6
|
+
const DEFAULT_TIMEOUT = 3e4;
|
|
7
|
+
const DEFAULT_MAX_BODY = 1048576;
|
|
8
|
+
const createProxyRouter = (options = {}) => {
|
|
9
|
+
const {
|
|
10
|
+
rateLimitPerMinute = DEFAULT_RATE_LIMIT,
|
|
11
|
+
maxTimeout = DEFAULT_TIMEOUT,
|
|
12
|
+
maxBodySize = DEFAULT_MAX_BODY,
|
|
13
|
+
allowedDomains = [],
|
|
14
|
+
onRequest
|
|
15
|
+
} = options;
|
|
16
|
+
const router = Router();
|
|
17
|
+
try {
|
|
18
|
+
const rateLimit = require("express-rate-limit").default ?? require("express-rate-limit");
|
|
19
|
+
router.use(
|
|
20
|
+
rateLimit({
|
|
21
|
+
windowMs: 6e4,
|
|
22
|
+
max: rateLimitPerMinute,
|
|
23
|
+
standardHeaders: true,
|
|
24
|
+
legacyHeaders: false,
|
|
25
|
+
message: { error: "Too many proxy requests. Please try again later." }
|
|
26
|
+
})
|
|
27
|
+
);
|
|
28
|
+
} catch {
|
|
29
|
+
const hits = /* @__PURE__ */ new Map();
|
|
30
|
+
router.use((req, res, next) => {
|
|
31
|
+
const key = req.ip ?? "unknown";
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
const entry = hits.get(key);
|
|
34
|
+
if (!entry || now > entry.resetAt) {
|
|
35
|
+
hits.set(key, { count: 1, resetAt: now + 6e4 });
|
|
36
|
+
return next();
|
|
37
|
+
}
|
|
38
|
+
if (entry.count >= rateLimitPerMinute) {
|
|
39
|
+
return res.status(429).json({ error: "Too many proxy requests. Please try again later." });
|
|
40
|
+
}
|
|
41
|
+
entry.count++;
|
|
42
|
+
return next();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
router.post("/", async (req, res) => {
|
|
46
|
+
const proxyReq = req.body;
|
|
47
|
+
if (!proxyReq?.url || !proxyReq?.method) {
|
|
48
|
+
return res.status(400).json({ error: "Missing required fields: url, method" });
|
|
49
|
+
}
|
|
50
|
+
let targetUrl;
|
|
51
|
+
try {
|
|
52
|
+
targetUrl = new URL(proxyReq.url);
|
|
53
|
+
} catch {
|
|
54
|
+
return res.status(400).json({ error: "Invalid target URL" });
|
|
55
|
+
}
|
|
56
|
+
const hostname = targetUrl.hostname;
|
|
57
|
+
if (isPrivateIp(hostname)) {
|
|
58
|
+
return res.status(403).json({ error: "Requests to private/internal addresses are not allowed" });
|
|
59
|
+
}
|
|
60
|
+
if (allowedDomains.length > 0) {
|
|
61
|
+
const allowed = allowedDomains.some(
|
|
62
|
+
(domain) => hostname === domain || hostname.endsWith(`.${domain}`)
|
|
63
|
+
);
|
|
64
|
+
if (!allowed) {
|
|
65
|
+
return res.status(403).json({ error: `Domain ${hostname} is not in the allowed list` });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (proxyReq.body && proxyReq.body.length > maxBodySize) {
|
|
69
|
+
return res.status(413).json({ error: `Request body exceeds ${maxBodySize} byte limit` });
|
|
70
|
+
}
|
|
71
|
+
const timeout = Math.min(proxyReq.timeout ?? maxTimeout, maxTimeout);
|
|
72
|
+
const controller = new AbortController();
|
|
73
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
74
|
+
const startTime = Date.now();
|
|
75
|
+
let outboundBody = proxyReq.body ?? void 0;
|
|
76
|
+
if (outboundBody !== void 0 && proxyReq.bodyEncoding === "base64") {
|
|
77
|
+
try {
|
|
78
|
+
outboundBody = Buffer.from(outboundBody, "base64");
|
|
79
|
+
} catch {
|
|
80
|
+
return res.status(400).json({ error: "Invalid base64 request body" });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const fetchResponse = await fetch(proxyReq.url, {
|
|
85
|
+
method: proxyReq.method,
|
|
86
|
+
headers: proxyReq.headers ?? {},
|
|
87
|
+
// Buffer is a Uint8Array at runtime; Node's fetch accepts it. The DOM
|
|
88
|
+
// BodyInit typing doesn't know that, hence the cast.
|
|
89
|
+
body: outboundBody,
|
|
90
|
+
signal: controller.signal
|
|
91
|
+
});
|
|
92
|
+
const responseContentType = fetchResponse.headers.get("content-type") ?? "";
|
|
93
|
+
const isBinary = isBinaryContentType(responseContentType);
|
|
94
|
+
const responseBody = isBinary ? Buffer.from(await fetchResponse.arrayBuffer()).toString("base64") : await fetchResponse.text();
|
|
95
|
+
const duration = Date.now() - startTime;
|
|
96
|
+
if (responseBody.length > maxBodySize) {
|
|
97
|
+
return res.status(502).json({
|
|
98
|
+
status: 502,
|
|
99
|
+
statusText: "Response too large",
|
|
100
|
+
headers: {},
|
|
101
|
+
body: `Response body exceeds ${maxBodySize} byte limit`,
|
|
102
|
+
bodyEncoding: "utf-8",
|
|
103
|
+
duration
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const responseHeaders = {};
|
|
107
|
+
fetchResponse.headers.forEach((value, key) => {
|
|
108
|
+
responseHeaders[key] = value;
|
|
109
|
+
});
|
|
110
|
+
const proxyRes = {
|
|
111
|
+
status: fetchResponse.status,
|
|
112
|
+
statusText: fetchResponse.statusText,
|
|
113
|
+
headers: responseHeaders,
|
|
114
|
+
body: responseBody,
|
|
115
|
+
bodyEncoding: isBinary ? "base64" : "utf-8",
|
|
116
|
+
duration
|
|
117
|
+
};
|
|
118
|
+
if (onRequest) {
|
|
119
|
+
try {
|
|
120
|
+
onRequest({
|
|
121
|
+
targetUrl: proxyReq.url,
|
|
122
|
+
method: proxyReq.method,
|
|
123
|
+
statusCode: fetchResponse.status,
|
|
124
|
+
duration,
|
|
125
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
126
|
+
ip: req.ip ?? "unknown"
|
|
127
|
+
});
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return res.json(proxyRes);
|
|
132
|
+
} catch (err) {
|
|
133
|
+
const duration = Date.now() - startTime;
|
|
134
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
135
|
+
const isTimeout = message.includes("abort");
|
|
136
|
+
return res.status(isTimeout ? 504 : 502).json({
|
|
137
|
+
status: isTimeout ? 504 : 502,
|
|
138
|
+
statusText: isTimeout ? "Gateway Timeout" : "Bad Gateway",
|
|
139
|
+
headers: {},
|
|
140
|
+
body: message,
|
|
141
|
+
bodyEncoding: "utf-8",
|
|
142
|
+
duration
|
|
143
|
+
});
|
|
144
|
+
} finally {
|
|
145
|
+
clearTimeout(timeoutId);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return router;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export { createProxyRouter };
|
|
152
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/server/proxy-router.ts"],"sourcesContent":["/**\n * This source file is part of the Apiboost(R) OmniSpec Core.\n *\n * Copyright (c) Apiboost, Inc.\n *\n * SPDX-License-Identifier: Apache-2.0\n *\n * See LICENSE.md and LICENSING.md in the project root for license information.\n */\n\nimport { Router } from 'express'\nimport type { Request, Response } from 'express'\nimport type { ProxyRequest, ProxyResponse } from '../core/types/try-it.types'\nimport { isPrivateIp } from './ssrf-guard'\nimport { isBinaryContentType } from '../core/utils/binary-response'\n\nexport interface ProxyRouterOptions {\n /** Max requests per minute per IP. Default: 60. */\n rateLimitPerMinute?: number\n /** Max timeout for proxied requests in ms. Default: 30000. */\n maxTimeout?: number\n /** Max request/response body size in bytes. Default: 1048576 (1MB). */\n maxBodySize?: number\n /** Allowed target domains. Empty array = allow all external. */\n allowedDomains?: string[]\n /** Audit callback fired after each proxy request completes. */\n onRequest?: (audit: ProxyAuditEntry) => void\n}\n\nexport interface ProxyAuditEntry {\n targetUrl: string\n method: string\n statusCode: number\n duration: number\n timestamp: string\n ip: string\n}\n\nconst DEFAULT_RATE_LIMIT = 60\nconst DEFAULT_TIMEOUT = 30_000\nconst DEFAULT_MAX_BODY = 1_048_576\n\n/**\n * Creates an Express router that proxies Try-It requests to external APIs.\n *\n * @param options - Configuration for rate limiting, timeouts, SSRF protection.\n * @returns Express Router to mount at your proxy path (e.g. `/api/proxy`).\n *\n * @example\n * ```ts\n * import { createProxyRouter } from '@apiboost/omnispec/server'\n * app.use('/api/proxy', createProxyRouter({ rateLimitPerMinute: 60 }))\n * ```\n */\nexport const createProxyRouter = (options: ProxyRouterOptions = {}): Router => {\n const {\n rateLimitPerMinute = DEFAULT_RATE_LIMIT,\n maxTimeout = DEFAULT_TIMEOUT,\n maxBodySize = DEFAULT_MAX_BODY,\n allowedDomains = [],\n onRequest,\n } = options\n\n const router = Router()\n\n // Rate limiting — try to use express-rate-limit if available, otherwise\n // fall back to a simple in-memory counter.\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const rateLimit = require('express-rate-limit').default ?? require('express-rate-limit')\n router.use(\n rateLimit({\n windowMs: 60_000,\n max: rateLimitPerMinute,\n standardHeaders: true,\n legacyHeaders: false,\n message: { error: 'Too many proxy requests. Please try again later.' },\n }),\n )\n } catch {\n // express-rate-limit not installed — use basic in-memory limiter.\n const hits = new Map<string, { count: number; resetAt: number }>()\n router.use((req: Request, res: Response, next) => {\n const key = req.ip ?? 'unknown'\n const now = Date.now()\n const entry = hits.get(key)\n\n if (!entry || now > entry.resetAt) {\n hits.set(key, { count: 1, resetAt: now + 60_000 })\n return next()\n }\n\n if (entry.count >= rateLimitPerMinute) {\n return res.status(429).json({ error: 'Too many proxy requests. Please try again later.' })\n }\n\n entry.count++\n return next()\n })\n }\n\n router.post('/', async (req: Request, res: Response) => {\n const proxyReq = req.body as ProxyRequest\n\n // Validate required fields.\n if (!proxyReq?.url || !proxyReq?.method) {\n return res.status(400).json({ error: 'Missing required fields: url, method' })\n }\n\n // Validate URL format.\n let targetUrl: URL\n try {\n targetUrl = new URL(proxyReq.url)\n } catch {\n return res.status(400).json({ error: 'Invalid target URL' })\n }\n\n // SSRF protection — block private IPs.\n const hostname = targetUrl.hostname\n if (isPrivateIp(hostname)) {\n return res.status(403).json({ error: 'Requests to private/internal addresses are not allowed' })\n }\n\n // Domain allowlist (if configured).\n if (allowedDomains.length > 0) {\n const allowed = allowedDomains.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`),\n )\n if (!allowed) {\n return res.status(403).json({ error: `Domain ${hostname} is not in the allowed list` })\n }\n }\n\n // Enforce body size limit.\n if (proxyReq.body && proxyReq.body.length > maxBodySize) {\n return res.status(413).json({ error: `Request body exceeds ${maxBodySize} byte limit` })\n }\n\n const timeout = Math.min(proxyReq.timeout ?? maxTimeout, maxTimeout)\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n const startTime = Date.now()\n\n // Decode base64-encoded bodies (used for multipart/form-data uploads —\n // the client serializes the real multipart payload and base64-encodes it\n // to fit the JSON envelope) back to raw bytes before forwarding.\n let outboundBody: string | Buffer | undefined = proxyReq.body ?? undefined\n if (outboundBody !== undefined && proxyReq.bodyEncoding === 'base64') {\n try {\n outboundBody = Buffer.from(outboundBody as string, 'base64')\n } catch {\n return res.status(400).json({ error: 'Invalid base64 request body' })\n }\n }\n\n try {\n const fetchResponse = await fetch(proxyReq.url, {\n method: proxyReq.method,\n headers: proxyReq.headers ?? {},\n // Buffer is a Uint8Array at runtime; Node's fetch accepts it. The DOM\n // BodyInit typing doesn't know that, hence the cast.\n body: outboundBody as BodyInit | undefined,\n signal: controller.signal,\n })\n\n // Binary content types are read as bytes and base64-encoded so file\n // downloads survive the JSON envelope; text flows are unchanged.\n const responseContentType = fetchResponse.headers.get('content-type') ?? ''\n const isBinary = isBinaryContentType(responseContentType)\n const responseBody = isBinary\n ? Buffer.from(await fetchResponse.arrayBuffer()).toString('base64')\n : await fetchResponse.text()\n const duration = Date.now() - startTime\n\n // Enforce response body size limit.\n if (responseBody.length > maxBodySize) {\n return res.status(502).json({\n status: 502,\n statusText: 'Response too large',\n headers: {},\n body: `Response body exceeds ${maxBodySize} byte limit`,\n bodyEncoding: 'utf-8' as const,\n duration,\n })\n }\n\n const responseHeaders: Record<string, string> = {}\n fetchResponse.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n const proxyRes: ProxyResponse = {\n status: fetchResponse.status,\n statusText: fetchResponse.statusText,\n headers: responseHeaders,\n body: responseBody,\n bodyEncoding: isBinary ? 'base64' : 'utf-8',\n duration,\n }\n\n // Fire audit callback (non-blocking).\n if (onRequest) {\n try {\n onRequest({\n targetUrl: proxyReq.url,\n method: proxyReq.method,\n statusCode: fetchResponse.status,\n duration,\n timestamp: new Date().toISOString(),\n ip: req.ip ?? 'unknown',\n })\n } catch {\n // Audit must never block the response.\n }\n }\n\n return res.json(proxyRes)\n } catch (err) {\n const duration = Date.now() - startTime\n const message = err instanceof Error ? err.message : 'Unknown error'\n const isTimeout = message.includes('abort')\n\n return res.status(isTimeout ? 504 : 502).json({\n status: isTimeout ? 504 : 502,\n statusText: isTimeout ? 'Gateway Timeout' : 'Bad Gateway',\n headers: {},\n body: message,\n bodyEncoding: 'utf-8',\n duration,\n } satisfies ProxyResponse)\n } finally {\n clearTimeout(timeoutId)\n }\n })\n\n return router\n}\n"],"names":[],"mappings":"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"}
|