@lukoweb/apitogo 0.2.22 → 0.2.24
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/README.md +94 -94
- package/cli.js +13 -13
- package/client.d.ts +8 -8
- package/dist/cli/cli.js +561 -232
- package/dist/declarations/cli/platform/client/platform-api.d.ts +18 -0
- package/dist/declarations/config/validators/InputNavigationSchema.d.ts +7 -7
- package/dist/declarations/config/validators/ZudokuConfig.d.ts +1 -1
- package/docs/cli/commands.md +75 -75
- package/docs/cli/go-live.md +123 -123
- package/docs/cli/overview.md +91 -91
- package/docs/cli/setup.md +141 -141
- package/docs/cli/shape.md +127 -127
- package/docs/components/alert.mdx +130 -130
- package/docs/components/badge.mdx +70 -70
- package/docs/components/button.mdx +132 -132
- package/docs/components/callout.mdx +112 -112
- package/docs/components/card.mdx +104 -104
- package/docs/components/checkbox.mdx +72 -72
- package/docs/components/client-only.mdx +79 -79
- package/docs/components/code-tabs.mdx +179 -179
- package/docs/components/dialog.mdx +167 -167
- package/docs/components/head.mdx +200 -200
- package/docs/components/icons.mdx +27 -27
- package/docs/components/input.mdx +96 -96
- package/docs/components/label.mdx +86 -86
- package/docs/components/link.mdx +242 -242
- package/docs/components/markdown.mdx +151 -151
- package/docs/components/mermaid.mdx +81 -81
- package/docs/components/playground.mdx +85 -85
- package/docs/components/secret.mdx +79 -79
- package/docs/components/select.mdx +176 -176
- package/docs/components/shadcn.mdx +73 -73
- package/docs/components/slider.mdx +108 -108
- package/docs/components/slot.mdx +119 -119
- package/docs/components/stepper.mdx +138 -138
- package/docs/components/switch.mdx +96 -96
- package/docs/components/syntax-highlight.mdx +602 -602
- package/docs/components/textarea.mdx +78 -78
- package/docs/components/tooltip.mdx +195 -195
- package/docs/components/typography.mdx +61 -61
- package/docs/components.mdx +60 -60
- package/docs/concepts/auth-provider-api-identities.md +105 -105
- package/docs/configuration/ai-assistants.md +65 -65
- package/docs/configuration/api-catalog.md +109 -109
- package/docs/configuration/api-reference.md +397 -397
- package/docs/configuration/authentication-auth0.md +181 -181
- package/docs/configuration/authentication-azure-ad.md +245 -245
- package/docs/configuration/authentication-clerk.md +117 -117
- package/docs/configuration/authentication-firebase.md +69 -69
- package/docs/configuration/authentication-pingfederate.md +143 -143
- package/docs/configuration/authentication-supabase.md +233 -233
- package/docs/configuration/authentication.md +159 -159
- package/docs/configuration/build-configuration.mdx +147 -147
- package/docs/configuration/docs.md +282 -282
- package/docs/configuration/footer.mdx +118 -118
- package/docs/configuration/gateway.md +221 -221
- package/docs/configuration/llms.md +90 -90
- package/docs/configuration/make-config.mdx +124 -124
- package/docs/configuration/manifest.md +128 -128
- package/docs/configuration/navigation.mdx +421 -421
- package/docs/configuration/overview.md +166 -166
- package/docs/configuration/plans.md +153 -153
- package/docs/configuration/protected-routes.md +150 -150
- package/docs/configuration/search.md +164 -164
- package/docs/configuration/sentry.mdx +44 -44
- package/docs/configuration/site.md +124 -124
- package/docs/configuration/slots.mdx +125 -125
- package/docs/configuration/vite-config.md +18 -18
- package/docs/custom-plugins.md +285 -285
- package/docs/customization/colors-theme.mdx +278 -278
- package/docs/customization/fonts.md +110 -110
- package/docs/customization/landing-page.md +188 -188
- package/docs/deploy/apache-nginx.md +41 -41
- package/docs/deploy/apitogo.md +17 -17
- package/docs/deploy/cloudflare-pages.md +74 -74
- package/docs/deploy/direct-upload.md +17 -17
- package/docs/deploy/github-pages.md +49 -49
- package/docs/deploy/vercel.md +101 -101
- package/docs/deployment.md +9 -9
- package/docs/extending/events.md +124 -124
- package/docs/guides/custom-pages.md +110 -110
- package/docs/guides/environment-variables.md +94 -94
- package/docs/guides/managing-api-keys-and-identities.md +89 -89
- package/docs/guides/mermaid.mdx +70 -70
- package/docs/guides/navigation-rules.mdx +203 -203
- package/docs/guides/processors.mdx +234 -234
- package/docs/guides/static-files.md +55 -55
- package/docs/guides/transforming-examples.md +156 -156
- package/docs/guides/using-multiple-apis.md +87 -87
- package/docs/markdown/admonitions.md +128 -128
- package/docs/markdown/code-blocks.md +196 -196
- package/docs/markdown/frontmatter.md +173 -173
- package/docs/markdown/mdx.md +68 -68
- package/docs/markdown/overview.md +275 -275
- package/docs/mcp/go-live.md +100 -100
- package/docs/mcp/overview.md +76 -76
- package/docs/mcp/setup.md +173 -173
- package/docs/mcp/shape.md +77 -77
- package/docs/mcp/tools.md +102 -102
- package/docs/plugins.md +24 -24
- package/docs/quickstart.md +72 -72
- package/docs/writing.mdx +72 -72
- package/package.json +1 -1
- package/src/app/ZuploBuildConfig.ts +36 -36
- package/src/app/apitogoBrandTheme.ts +47 -47
- package/src/app/defaultTheme.css +77 -77
- package/src/app/demo-cdn.html +37 -37
- package/src/app/demo.html +21 -21
- package/src/app/demo.tsx +77 -77
- package/src/app/entry.client.tsx +107 -107
- package/src/app/entry.server.tsx +160 -160
- package/src/app/env.ts +40 -40
- package/src/app/main.css +400 -400
- package/src/app/main.tsx +167 -167
- package/src/app/polyfills.ts +47 -47
- package/src/app/processRoutes.tsx +51 -51
- package/src/app/sentry.ts +24 -24
- package/src/app/standalone.html +23 -23
- package/src/app/standalone.tsx +60 -60
- package/src/app/utils/createRedirectRoutes.ts +11 -11
- package/src/config/apitogo-config-core.ts +7 -3
- package/src/config/apitogo-config-loader.browser.ts +17 -17
- package/src/config/apitogo-config-loader.node.ts +88 -88
- package/src/config/apitogo-config-loader.ts +6 -6
- package/src/config/build-apitogo-config.ts +61 -61
- package/src/config/config.ts +74 -74
- package/src/config/create-plugin.ts +71 -71
- package/src/config/default-landing-content.ts +149 -149
- package/src/config/file-exists.ts +6 -6
- package/src/config/gateway-limits.ts +128 -128
- package/src/config/landing-manifest.ts +11 -11
- package/src/config/landing-openapi-showcase.ts +124 -124
- package/src/config/loader.ts +375 -375
- package/src/config/local-manifest.ts +545 -545
- package/src/config/resolve-modules.ts +354 -354
- package/src/config/v2/__fixtures__/scenario-a-docs-only.json +6 -6
- package/src/config/v2/__fixtures__/scenario-b-managed-origin.json +14 -14
- package/src/config/v2/__fixtures__/scenario-c-proxy-oidc.json +15 -15
- package/src/config/v2/__fixtures__/scenario-h-full-stack.json +28 -28
- package/src/config/v2/docs-navigation.ts +72 -72
- package/src/config/v2/errors.ts +42 -42
- package/src/config/v2/gateway-reference.ts +220 -220
- package/src/config/v2/gateway-request.ts +123 -123
- package/src/config/v2/home-redirect.ts +98 -98
- package/src/config/v2/index.ts +126 -126
- package/src/config/v2/init.ts +273 -273
- package/src/config/v2/layout.ts +237 -237
- package/src/config/v2/ledger.ts +235 -235
- package/src/config/v2/link-directory.ts +34 -0
- package/src/config/v2/load.ts +70 -70
- package/src/config/v2/manifest.ts +452 -452
- package/src/config/v2/parse.ts +214 -214
- package/src/config/v2/paths.ts +54 -54
- package/src/config/v2/portal-profile.ts +88 -88
- package/src/config/v2/resolve.ts +188 -188
- package/src/config/v2/rules.ts +714 -714
- package/src/config/v2/schema.ts +245 -245
- package/src/config/v2/services.ts +663 -663
- package/src/config/v2/workspace.ts +3 -2
- package/src/config/v2/wrapper.ts +24 -2
- package/src/config/validators/BuildSchema.ts +95 -95
- package/src/config/validators/HeaderNavigationSchema.ts +44 -44
- package/src/config/validators/InputNavigationSchema.test-d.ts +178 -178
- package/src/config/validators/InputNavigationSchema.ts +206 -206
- package/src/config/validators/ModulesSchema.ts +502 -502
- package/src/config/validators/NavigationSchema.ts +352 -352
- package/src/config/validators/ProtectedRoutesSchema.ts +35 -35
- package/src/config/validators/ZudokuConfig.ts +792 -792
- package/src/config/validators/auth.ts +3 -3
- package/src/config/validators/reason-codes.ts +7 -7
- package/src/env.d.ts +11 -11
- package/src/index.ts +83 -83
- package/src/lib/MissingIcon.tsx +22 -22
- package/src/lib/assets/language-icons/bun.tsx +50 -50
- package/src/lib/assets/language-icons/c.tsx +31 -31
- package/src/lib/assets/language-icons/commonlisp.tsx +22 -22
- package/src/lib/assets/language-icons/cpp.tsx +35 -35
- package/src/lib/assets/language-icons/csharp.tsx +35 -35
- package/src/lib/assets/language-icons/css.tsx +36 -36
- package/src/lib/assets/language-icons/dart.tsx +39 -39
- package/src/lib/assets/language-icons/elixir.tsx +19 -19
- package/src/lib/assets/language-icons/go.tsx +19 -19
- package/src/lib/assets/language-icons/graphql.tsx +19 -19
- package/src/lib/assets/language-icons/html.tsx +24 -24
- package/src/lib/assets/language-icons/java.tsx +35 -35
- package/src/lib/assets/language-icons/javascript.tsx +11 -11
- package/src/lib/assets/language-icons/json.tsx +19 -19
- package/src/lib/assets/language-icons/kotlin.tsx +30 -30
- package/src/lib/assets/language-icons/markdown.tsx +19 -19
- package/src/lib/assets/language-icons/mdx.tsx +23 -23
- package/src/lib/assets/language-icons/npm.tsx +15 -15
- package/src/lib/assets/language-icons/objectivec.tsx +23 -23
- package/src/lib/assets/language-icons/ocaml.tsx +34 -34
- package/src/lib/assets/language-icons/php.tsx +19 -19
- package/src/lib/assets/language-icons/pnpm.tsx +32 -32
- package/src/lib/assets/language-icons/powershell.tsx +27 -27
- package/src/lib/assets/language-icons/python.tsx +23 -23
- package/src/lib/assets/language-icons/react.tsx +21 -21
- package/src/lib/assets/language-icons/ruby.tsx +19 -19
- package/src/lib/assets/language-icons/rust.tsx +19 -19
- package/src/lib/assets/language-icons/scala.tsx +19 -19
- package/src/lib/assets/language-icons/shell.tsx +19 -19
- package/src/lib/assets/language-icons/swift.tsx +19 -19
- package/src/lib/assets/language-icons/toml.tsx +23 -23
- package/src/lib/assets/language-icons/typescript.tsx +23 -23
- package/src/lib/assets/language-icons/xml.tsx +19 -19
- package/src/lib/assets/language-icons/yaml.tsx +23 -23
- package/src/lib/assets/language-icons/yarn.tsx +17 -17
- package/src/lib/assets/language-icons/zig.tsx +32 -32
- package/src/lib/auth/issuer.ts +34 -34
- package/src/lib/authentication/AuthenticationPlugin.tsx +33 -33
- package/src/lib/authentication/auth-header-nav.ts +46 -46
- package/src/lib/authentication/authentication.ts +51 -51
- package/src/lib/authentication/components/CallbackHandler.tsx +45 -45
- package/src/lib/authentication/components/OAuthErrorPage.tsx +197 -197
- package/src/lib/authentication/components/ProductionUnlockPage.tsx +26 -26
- package/src/lib/authentication/components/SignIn.tsx +46 -46
- package/src/lib/authentication/components/SignOut.tsx +15 -15
- package/src/lib/authentication/components/SignUp.tsx +48 -48
- package/src/lib/authentication/constants.ts +1 -1
- package/src/lib/authentication/errors.ts +34 -34
- package/src/lib/authentication/header-nav-filter.ts +35 -35
- package/src/lib/authentication/hook.ts +141 -141
- package/src/lib/authentication/providers/auth0.tsx +91 -91
- package/src/lib/authentication/providers/azureb2c.tsx +223 -223
- package/src/lib/authentication/providers/clerk.tsx +224 -224
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +602 -602
- package/src/lib/authentication/providers/dev-portal-constants.ts +38 -38
- package/src/lib/authentication/providers/dev-portal-demo.ts +151 -151
- package/src/lib/authentication/providers/dev-portal-utils.ts +279 -279
- package/src/lib/authentication/providers/dev-portal.tsx +448 -448
- package/src/lib/authentication/providers/firebase.tsx +486 -486
- package/src/lib/authentication/providers/openid.tsx +516 -516
- package/src/lib/authentication/providers/supabase.tsx +412 -412
- package/src/lib/authentication/providers/util.ts +26 -26
- package/src/lib/authentication/state.ts +180 -180
- package/src/lib/authentication/ui/AuthCard.tsx +7 -7
- package/src/lib/authentication/ui/EmailLinkCallbackUi.tsx +129 -129
- package/src/lib/authentication/ui/EmailLinkSentUi.tsx +105 -105
- package/src/lib/authentication/ui/EmailLinkSignInUi.tsx +100 -100
- package/src/lib/authentication/ui/EmailVerificationUi.tsx +128 -128
- package/src/lib/authentication/ui/ZudokuAuthUi.tsx +620 -620
- package/src/lib/authentication/ui/icons/Apple.tsx +10 -10
- package/src/lib/authentication/ui/icons/Facebook.tsx +15 -15
- package/src/lib/authentication/ui/icons/Github.tsx +16 -16
- package/src/lib/authentication/ui/icons/Google.tsx +16 -16
- package/src/lib/authentication/ui/icons/Microsoft.tsx +12 -12
- package/src/lib/authentication/ui/icons/X.tsx +10 -10
- package/src/lib/authentication/utils/relativeRedirectUrl.ts +16 -16
- package/src/lib/components/AiAssistantMenuItems.tsx +102 -102
- package/src/lib/components/AnchorLink.tsx +24 -24
- package/src/lib/components/Autocomplete.tsx +123 -123
- package/src/lib/components/Banner.tsx +52 -52
- package/src/lib/components/Bootstrap.tsx +77 -77
- package/src/lib/components/BuildCheck.tsx +87 -87
- package/src/lib/components/CategoryHeading.tsx +19 -19
- package/src/lib/components/ClientOnly.tsx +19 -19
- package/src/lib/components/DeveloperHint.tsx +39 -39
- package/src/lib/components/ErrorPage.tsx +26 -26
- package/src/lib/components/Footer.tsx +146 -146
- package/src/lib/components/Framed.tsx +51 -51
- package/src/lib/components/Header.tsx +261 -261
- package/src/lib/components/HeaderAuthActions.tsx +32 -32
- package/src/lib/components/HeaderNavigation.tsx +176 -176
- package/src/lib/components/Heading.tsx +84 -84
- package/src/lib/components/InlineCode.tsx +15 -15
- package/src/lib/components/LandingLayout.tsx +27 -27
- package/src/lib/components/LanguageIcon.tsx +199 -199
- package/src/lib/components/Layout.tsx +59 -59
- package/src/lib/components/Main.tsx +52 -52
- package/src/lib/components/Markdown.tsx +55 -55
- package/src/lib/components/Mermaid.tsx +74 -74
- package/src/lib/components/Meta.tsx +46 -46
- package/src/lib/components/MobileTopNavigation.tsx +283 -283
- package/src/lib/components/MultiSelect.tsx +86 -86
- package/src/lib/components/NotFoundPage.tsx +37 -37
- package/src/lib/components/PageProgress.tsx +28 -28
- package/src/lib/components/PagefindSearchMeta.tsx +14 -14
- package/src/lib/components/Pagination.tsx +44 -44
- package/src/lib/components/PathRenderer.tsx +61 -61
- package/src/lib/components/PluginHeads.tsx +17 -17
- package/src/lib/components/Search.tsx +70 -70
- package/src/lib/components/SiteTitle.tsx +58 -58
- package/src/lib/components/Slot.tsx +65 -65
- package/src/lib/components/Spinner.tsx +5 -5
- package/src/lib/components/StatusPage.tsx +96 -96
- package/src/lib/components/ThemeSwitch.tsx +99 -99
- package/src/lib/components/TopNavigation.tsx +90 -90
- package/src/lib/components/Typography.tsx +12 -12
- package/src/lib/components/Zudoku.tsx +105 -105
- package/src/lib/components/cache.ts +27 -27
- package/src/lib/components/context/RenderContext.ts +11 -11
- package/src/lib/components/context/RouterEventsEmitter.tsx +19 -19
- package/src/lib/components/context/SlotProvider.tsx +149 -149
- package/src/lib/components/context/ViewportAnchorContext.tsx +137 -137
- package/src/lib/components/context/ZudokuContext.ts +140 -140
- package/src/lib/components/context/ZudokuProvider.tsx +20 -20
- package/src/lib/components/context/ZudokuReactContext.tsx +17 -17
- package/src/lib/components/index.ts +36 -36
- package/src/lib/components/navigation/Navigation.tsx +51 -51
- package/src/lib/components/navigation/NavigationBadge.tsx +48 -48
- package/src/lib/components/navigation/NavigationCategory.tsx +157 -157
- package/src/lib/components/navigation/NavigationFilterContext.tsx +28 -28
- package/src/lib/components/navigation/NavigationFilterInput.tsx +35 -35
- package/src/lib/components/navigation/NavigationItem.tsx +181 -181
- package/src/lib/components/navigation/NavigationWrapper.tsx +49 -49
- package/src/lib/components/navigation/PoweredByZudoku.tsx +39 -39
- package/src/lib/components/navigation/Toc.tsx +137 -137
- package/src/lib/components/navigation/ZudokuLogo.tsx +25 -25
- package/src/lib/components/navigation/ZuploLogo.tsx +14 -14
- package/src/lib/components/navigation/utils.ts +234 -234
- package/src/lib/core/RouteGuard.tsx +260 -260
- package/src/lib/core/ZudokuContext.ts +272 -272
- package/src/lib/core/plugins.ts +139 -139
- package/src/lib/core/react-query.ts +1 -1
- package/src/lib/core/router.ts +1 -1
- package/src/lib/core/transform-config.ts +67 -67
- package/src/lib/demo/DemoAnnouncement.tsx +17 -17
- package/src/lib/errors/ErrorAlert.tsx +28 -28
- package/src/lib/errors/ErrorMessage.tsx +50 -50
- package/src/lib/errors/RouterError.tsx +18 -18
- package/src/lib/errors/ServerError.tsx +5 -5
- package/src/lib/errors/TopLevelError.tsx +6 -6
- package/src/lib/hooks/index.ts +13 -13
- package/src/lib/hooks/useEvent.ts +41 -41
- package/src/lib/hooks/useHighlighter.ts +15 -15
- package/src/lib/hooks/useHotkey.ts +70 -70
- package/src/lib/icons.ts +2 -2
- package/src/lib/navigation/applyRules.ts +127 -127
- package/src/lib/navigation/pathMatcher.ts +81 -81
- package/src/lib/oas/graphql/circular.ts +69 -69
- package/src/lib/oas/graphql/constants.ts +2 -2
- package/src/lib/oas/graphql/index.ts +791 -791
- package/src/lib/oas/parser/dereference/index.ts +84 -84
- package/src/lib/oas/parser/dereference/resolveRef.ts +32 -32
- package/src/lib/oas/parser/index.ts +129 -129
- package/src/lib/oas/parser/schemas/v3.0.json +1489 -1489
- package/src/lib/oas/parser/schemas/v3.1.json +1298 -1298
- package/src/lib/oas/parser/upgrade/index.ts +174 -174
- package/src/lib/plugins/api-catalog/Catalog.tsx +80 -80
- package/src/lib/plugins/api-catalog/index.tsx +119 -119
- package/src/lib/plugins/api-keys/CreateApiKey.tsx +128 -128
- package/src/lib/plugins/api-keys/CreateApiKeyDialog.tsx +49 -49
- package/src/lib/plugins/api-keys/ProtectedRoute.tsx +33 -33
- package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +72 -72
- package/src/lib/plugins/api-keys/index.tsx +274 -274
- package/src/lib/plugins/api-keys/settings/ApiKeyItem.tsx +342 -342
- package/src/lib/plugins/api-keys/settings/ApiKeyList.tsx +67 -67
- package/src/lib/plugins/api-keys/settings/RevealApiKey.tsx +127 -127
- package/src/lib/plugins/custom-pages/index.tsx +32 -32
- package/src/lib/plugins/markdown/MdxPage.tsx +260 -260
- package/src/lib/plugins/markdown/assets/ChatGPTLogo.tsx +11 -11
- package/src/lib/plugins/markdown/assets/ClaudeLogo.tsx +19 -19
- package/src/lib/plugins/markdown/index.tsx +82 -82
- package/src/lib/plugins/openapi/ApiHeader.tsx +96 -96
- package/src/lib/plugins/openapi/CollapsibleCode.tsx +88 -88
- package/src/lib/plugins/openapi/ColorizedParam.tsx +115 -115
- package/src/lib/plugins/openapi/DownloadSchemaButton.tsx +94 -94
- package/src/lib/plugins/openapi/Endpoint.tsx +85 -85
- package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +52 -52
- package/src/lib/plugins/openapi/MCPEndpoint.tsx +273 -273
- package/src/lib/plugins/openapi/OasProvider.tsx +74 -74
- package/src/lib/plugins/openapi/OperationList.tsx +275 -275
- package/src/lib/plugins/openapi/OperationListItem.tsx +183 -183
- package/src/lib/plugins/openapi/ParamInfos.tsx +96 -96
- package/src/lib/plugins/openapi/ParameterList.tsx +53 -53
- package/src/lib/plugins/openapi/ParameterListItem.tsx +161 -161
- package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +67 -67
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +63 -63
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +120 -120
- package/src/lib/plugins/openapi/SchemaInfo.tsx +344 -344
- package/src/lib/plugins/openapi/SchemaList.tsx +113 -113
- package/src/lib/plugins/openapi/Sidecar.tsx +314 -314
- package/src/lib/plugins/openapi/SidecarBox.tsx +57 -57
- package/src/lib/plugins/openapi/SidecarExamples.tsx +177 -177
- package/src/lib/plugins/openapi/SimpleSelect.tsx +46 -46
- package/src/lib/plugins/openapi/client/GraphQLClient.tsx +73 -73
- package/src/lib/plugins/openapi/client/GraphQLContext.tsx +16 -16
- package/src/lib/plugins/openapi/client/createServer.ts +35 -35
- package/src/lib/plugins/openapi/client/useCreateQuery.ts +44 -44
- package/src/lib/plugins/openapi/components/ConstValue.tsx +24 -24
- package/src/lib/plugins/openapi/components/EnumValues.tsx +58 -58
- package/src/lib/plugins/openapi/components/NonHighlightedCode.tsx +22 -22
- package/src/lib/plugins/openapi/components/ResponseContent.tsx +117 -117
- package/src/lib/plugins/openapi/components/SelectOnClick.tsx +29 -29
- package/src/lib/plugins/openapi/context.tsx +16 -16
- package/src/lib/plugins/openapi/graphql/fragment-masking.ts +104 -104
- package/src/lib/plugins/openapi/graphql/gql.ts +95 -95
- package/src/lib/plugins/openapi/graphql/graphql.ts +835 -835
- package/src/lib/plugins/openapi/graphql/index.ts +2 -2
- package/src/lib/plugins/openapi/index.tsx +221 -221
- package/src/lib/plugins/openapi/interfaces.ts +100 -100
- package/src/lib/plugins/openapi/playground/BodyPanel.tsx +274 -274
- package/src/lib/plugins/openapi/playground/CollapsibleHeader.tsx +51 -51
- package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +60 -60
- package/src/lib/plugins/openapi/playground/Headers.tsx +194 -194
- package/src/lib/plugins/openapi/playground/IdentityDialog.tsx +75 -75
- package/src/lib/plugins/openapi/playground/IdentitySelector.tsx +38 -38
- package/src/lib/plugins/openapi/playground/ParamsGrid.tsx +45 -45
- package/src/lib/plugins/openapi/playground/PathParams.tsx +53 -53
- package/src/lib/plugins/openapi/playground/Playground.tsx +602 -602
- package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +62 -62
- package/src/lib/plugins/openapi/playground/QueryParams.tsx +151 -151
- package/src/lib/plugins/openapi/playground/RequestLoginDialog.tsx +70 -70
- package/src/lib/plugins/openapi/playground/Spinner.tsx +87 -87
- package/src/lib/plugins/openapi/playground/createUrl.ts +25 -25
- package/src/lib/plugins/openapi/playground/fileUtils.ts +36 -36
- package/src/lib/plugins/openapi/playground/rememberedIdentity.ts +26 -26
- package/src/lib/plugins/openapi/playground/request-panel/MultipartField.tsx +91 -91
- package/src/lib/plugins/openapi/playground/request-panel/UrlPath.tsx +31 -31
- package/src/lib/plugins/openapi/playground/request-panel/UrlQueryParams.tsx +29 -29
- package/src/lib/plugins/openapi/playground/request-panel/useKeyValueFieldManager.ts +340 -340
- package/src/lib/plugins/openapi/playground/result-panel/AudioPlayer.tsx +50 -50
- package/src/lib/plugins/openapi/playground/result-panel/ResponseStatusBar.tsx +117 -117
- package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +355 -355
- package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +106 -106
- package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.ts +36 -36
- package/src/lib/plugins/openapi/playground/serializeQueryParams.ts +125 -125
- package/src/lib/plugins/openapi/playground/useRememberSkipLoginDialog.tsx +23 -23
- package/src/lib/plugins/openapi/processors/injectApitogoGatewayServer.ts +36 -36
- package/src/lib/plugins/openapi/processors/removeExtensions.ts +29 -29
- package/src/lib/plugins/openapi/processors/removeParameters.ts +103 -103
- package/src/lib/plugins/openapi/processors/removePaths.ts +57 -57
- package/src/lib/plugins/openapi/processors/traverse.ts +1 -1
- package/src/lib/plugins/openapi/schema/SchemaExampleAndDefault.tsx +39 -39
- package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +189 -189
- package/src/lib/plugins/openapi/schema/SchemaView.tsx +299 -299
- package/src/lib/plugins/openapi/schema/UnionView.tsx +132 -132
- package/src/lib/plugins/openapi/schema/union-helpers.ts +123 -123
- package/src/lib/plugins/openapi/schema/utils.ts +49 -49
- package/src/lib/plugins/openapi/state.ts +36 -36
- package/src/lib/plugins/openapi/util/buildTagCategories.ts +54 -54
- package/src/lib/plugins/openapi/util/createHttpSnippet.ts +135 -135
- package/src/lib/plugins/openapi/util/createNavigationCategory.tsx +39 -39
- package/src/lib/plugins/openapi/util/generateSchemaExample.ts +191 -191
- package/src/lib/plugins/openapi/util/getRoutes.tsx +265 -265
- package/src/lib/plugins/openapi/util/methodColorMap.tsx +11 -11
- package/src/lib/plugins/openapi/util/methodToColor.ts +27 -27
- package/src/lib/plugins/openapi/util/sanitizeMarkdownForMetatag.tsx +32 -32
- package/src/lib/plugins/openapi/util/useWarmupSchema.ts +23 -23
- package/src/lib/plugins/search-inkeep/index.tsx +108 -108
- package/src/lib/plugins/search-inkeep/inkeep.ts +24 -24
- package/src/lib/plugins/search-pagefind/IndexingDialog.tsx +162 -162
- package/src/lib/plugins/search-pagefind/PagefindSearch.tsx +202 -202
- package/src/lib/plugins/search-pagefind/ResultList.tsx +122 -122
- package/src/lib/plugins/search-pagefind/get-results.tsx +74 -74
- package/src/lib/plugins/search-pagefind/index.tsx +21 -21
- package/src/lib/plugins/search-pagefind/types.ts +118 -118
- package/src/lib/shiki-constants.ts +24 -24
- package/src/lib/shiki.ts +179 -179
- package/src/lib/testing/index.tsx +147 -147
- package/src/lib/ui/Accordion.tsx +55 -55
- package/src/lib/ui/ActionButton.tsx +21 -21
- package/src/lib/ui/Alert.tsx +84 -84
- package/src/lib/ui/AlertDialog.tsx +195 -195
- package/src/lib/ui/AspectRatio.tsx +5 -5
- package/src/lib/ui/Badge.tsx +48 -48
- package/src/lib/ui/Breadcrumb.tsx +115 -115
- package/src/lib/ui/Button.tsx +65 -65
- package/src/lib/ui/ButtonGroup.tsx +80 -80
- package/src/lib/ui/Callout.tsx +113 -113
- package/src/lib/ui/Card.tsx +95 -95
- package/src/lib/ui/Carousel.tsx +259 -259
- package/src/lib/ui/Checkbox.tsx +28 -28
- package/src/lib/ui/CodeBlock.tsx +92 -92
- package/src/lib/ui/CodeTabPanel.tsx +13 -13
- package/src/lib/ui/CodeTabs.tsx +161 -161
- package/src/lib/ui/Collapsible.tsx +31 -31
- package/src/lib/ui/Command.tsx +191 -191
- package/src/lib/ui/Dialog.tsx +138 -138
- package/src/lib/ui/DismissibleAlert.tsx +74 -74
- package/src/lib/ui/Drawer.tsx +121 -121
- package/src/lib/ui/DropdownMenu.tsx +254 -254
- package/src/lib/ui/EmbeddedCodeBlock.tsx +99 -99
- package/src/lib/ui/Form.tsx +176 -176
- package/src/lib/ui/Frame.tsx +81 -81
- package/src/lib/ui/HoverCard.tsx +26 -26
- package/src/lib/ui/Input.tsx +23 -23
- package/src/lib/ui/InputGroup.tsx +168 -168
- package/src/lib/ui/Item.tsx +213 -213
- package/src/lib/ui/Kbd.tsx +28 -28
- package/src/lib/ui/Label.tsx +23 -23
- package/src/lib/ui/NativeSelect.tsx +48 -48
- package/src/lib/ui/NavigationMenu.tsx +169 -169
- package/src/lib/ui/Pagination.tsx +115 -115
- package/src/lib/ui/Popover.tsx +28 -28
- package/src/lib/ui/Progress.tsx +25 -25
- package/src/lib/ui/RadioGroup.tsx +41 -41
- package/src/lib/ui/ReactComponentDoc.tsx +68 -68
- package/src/lib/ui/ScrollArea.tsx +45 -45
- package/src/lib/ui/Secret.tsx +133 -133
- package/src/lib/ui/Select.tsx +184 -184
- package/src/lib/ui/Separator.tsx +25 -25
- package/src/lib/ui/Skeleton.tsx +15 -15
- package/src/lib/ui/Slider.tsx +25 -25
- package/src/lib/ui/Stepper.tsx +8 -8
- package/src/lib/ui/Switch.tsx +26 -26
- package/src/lib/ui/SyntaxHighlight.tsx +54 -54
- package/src/lib/ui/Tabs.tsx +52 -52
- package/src/lib/ui/Textarea.tsx +22 -22
- package/src/lib/ui/Toggle.tsx +42 -42
- package/src/lib/ui/ToggleGroup.tsx +58 -58
- package/src/lib/ui/Tooltip.tsx +65 -65
- package/src/lib/ui/Value.tsx +42 -42
- package/src/lib/ui/util.tsx +8 -8
- package/src/lib/util/MdxComponents.tsx +150 -150
- package/src/lib/util/cn.ts +6 -6
- package/src/lib/util/createVariantComponent.tsx +61 -61
- package/src/lib/util/ensureArray.ts +3 -3
- package/src/lib/util/flattenAllOf.ts +72 -72
- package/src/lib/util/flattenAllOfProcessor.ts +74 -74
- package/src/lib/util/hastToJsx.tsx +67 -67
- package/src/lib/util/humanFileSize.ts +15 -15
- package/src/lib/util/invariant.ts +52 -52
- package/src/lib/util/joinUrl.ts +60 -60
- package/src/lib/util/logInit.ts +9 -9
- package/src/lib/util/objectEntries.ts +5 -5
- package/src/lib/util/os.ts +18 -18
- package/src/lib/util/pastellize.ts +25 -25
- package/src/lib/util/problemJson.ts +63 -63
- package/src/lib/util/readFrontmatter.ts +14 -14
- package/src/lib/util/renderIf.ts +4 -4
- package/src/lib/util/scrollIntoViewIfNeeded.ts +18 -18
- package/src/lib/util/slugify.ts +21 -21
- package/src/lib/util/syncZustandState.ts +22 -22
- package/src/lib/util/traverse.ts +70 -70
- package/src/lib/util/types.ts +7 -7
- package/src/lib/util/url.ts +18 -18
- package/src/lib/util/useCopyToClipboard.ts +17 -17
- package/src/lib/util/useExposedProps.tsx +27 -27
- package/src/lib/util/useIsomorphicLayoutEffect.ts +6 -6
- package/src/lib/util/useLatest.ts +18 -18
- package/src/lib/util/useOnScreen.ts +34 -34
- package/src/lib/util/useScrollToAnchor.ts +75 -75
- package/src/lib/util/useScrollToTop.ts +18 -18
- package/src/types.d.ts +66 -66
- package/src/vite/api/SchemaManager.ts +371 -371
- package/src/vite/api/schema-codegen.ts +163 -163
- package/src/vite/build.ts +237 -237
- package/src/vite/config.ts +273 -273
- package/src/vite/css/collect.ts +42 -42
- package/src/vite/css/plugin.ts +105 -105
- package/src/vite/debug.ts +18 -18
- package/src/vite/dev-portal-env.ts +29 -29
- package/src/vite/dev-server.ts +294 -294
- package/src/vite/html.ts +52 -52
- package/src/vite/index.ts +2 -2
- package/src/vite/llms.ts +99 -99
- package/src/vite/mdx/rehype-extract-toc-with-jsx-export.ts +19 -19
- package/src/vite/mdx/rehype-extract-toc-with-jsx.ts +70 -70
- package/src/vite/mdx/remark-code-tabs.ts +47 -47
- package/src/vite/mdx/remark-inject-filepath.ts +13 -13
- package/src/vite/mdx/remark-last-modified.ts +103 -103
- package/src/vite/mdx/remark-link-rewrite.ts +23 -23
- package/src/vite/mdx/remark-normalize-image-url.ts +15 -15
- package/src/vite/mdx/remark-static-generation.ts +149 -149
- package/src/vite/mdx/utils.ts +32 -32
- package/src/vite/output.ts +261 -261
- package/src/vite/package-root.ts +12 -12
- package/src/vite/pagefind-dev-index.ts +100 -100
- package/src/vite/pagefind-dev-stub.ts +17 -17
- package/src/vite/plugin-api-keys.ts +55 -55
- package/src/vite/plugin-api.ts +328 -328
- package/src/vite/plugin-auth.ts +41 -41
- package/src/vite/plugin-component.ts +45 -45
- package/src/vite/plugin-config-reload.ts +47 -47
- package/src/vite/plugin-config.ts +131 -131
- package/src/vite/plugin-custom-pages.ts +36 -36
- package/src/vite/plugin-doc-metadata.ts +45 -45
- package/src/vite/plugin-docs.ts +205 -205
- package/src/vite/plugin-local-manifest.ts +100 -100
- package/src/vite/plugin-markdown-export.ts +214 -214
- package/src/vite/plugin-mdx.ts +149 -149
- package/src/vite/plugin-metadata.ts +30 -30
- package/src/vite/plugin-modules.ts +188 -188
- package/src/vite/plugin-navigation.ts +106 -106
- package/src/vite/plugin-offroot-resolve.ts +67 -67
- package/src/vite/plugin-search.ts +59 -59
- package/src/vite/plugin-shiki-register.ts +97 -97
- package/src/vite/plugin-theme.ts +458 -458
- package/src/vite/plugin.ts +48 -48
- package/src/vite/prerender/prerender.ts +242 -242
- package/src/vite/prerender/utils.ts +76 -76
- package/src/vite/prerender/worker.ts +118 -118
- package/src/vite/reporter.ts +34 -34
- package/src/vite/shadcn-registry.ts +48 -48
- package/src/vite/sitemap.ts +78 -78
- package/src/vite/ssr-templates/cloudflare.ts +19 -19
- package/src/vite/ssr-templates/node.ts +25 -25
- package/src/vite/ssr-templates/vercel.ts +22 -22
- package/src/vite/watch-ignore.ts +70 -70
- package/src/vite/zuplo.ts +30 -30
- package/src/vite-env.d.ts +6 -6
- package/src/zuplo/enrich-with-zuplo-mcp.ts +168 -168
- package/src/zuplo/enrich-with-zuplo.ts +256 -256
- package/src/zuplo/policy-types.ts +46 -46
- package/src/zuplo/with-zuplo-processors.ts +36 -36
- package/src/zuplo/with-zuplo.ts +14 -14
- package/dist/declarations/cli/platform/client/deploy-server.d.ts +0 -16
|
@@ -1,220 +1,220 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { parse } from "yaml";
|
|
3
|
-
import type { ResolvedGateway } from "./resolve.js";
|
|
4
|
-
|
|
5
|
-
/** What the gateway checks, in the terms the exported OpenAPI file uses. */
|
|
6
|
-
export type ReferenceOptions = {
|
|
7
|
-
/** The address callers use. Replaces every server of the spec. */
|
|
8
|
-
gatewayBaseUrl: string;
|
|
9
|
-
/** The customer's own API address. It must never appear in the result. */
|
|
10
|
-
originUrl?: string;
|
|
11
|
-
jwtRequired: boolean;
|
|
12
|
-
oidcMetadataUrl?: string;
|
|
13
|
-
apiKeyRequired: boolean;
|
|
14
|
-
apiKeyHeader: string;
|
|
15
|
-
/** Action keys such as `get:/orders`. */
|
|
16
|
-
publicOperations: ReadonlySet<string>;
|
|
17
|
-
deniedOperations: ReadonlySet<string>;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/** Header of the API key when the gateway does not say otherwise (same as the platform's OpenAPI export). */
|
|
21
|
-
export const DEFAULT_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
22
|
-
|
|
23
|
-
const METHODS = [
|
|
24
|
-
"get",
|
|
25
|
-
"put",
|
|
26
|
-
"post",
|
|
27
|
-
"delete",
|
|
28
|
-
"options",
|
|
29
|
-
"head",
|
|
30
|
-
"patch",
|
|
31
|
-
"trace",
|
|
32
|
-
] as const;
|
|
33
|
-
|
|
34
|
-
type Json = Record<string, unknown>;
|
|
35
|
-
|
|
36
|
-
const isObject = (value: unknown): value is Json =>
|
|
37
|
-
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38
|
-
|
|
39
|
-
/** `GET /orders/` becomes `get:/orders`, the key the platform uses for an operation. */
|
|
40
|
-
export function actionKey(method: string, path: string): string {
|
|
41
|
-
const trimmed = path.trim();
|
|
42
|
-
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
43
|
-
const normalized =
|
|
44
|
-
withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
45
|
-
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** A config entry like `GET /orders` as an action key, or undefined when it has no method and path. */
|
|
49
|
-
export function configActionKey(entry: string): string | undefined {
|
|
50
|
-
const match = /^\s*([A-Za-z]+)\s+(\S+)\s*$/.exec(entry);
|
|
51
|
-
return match?.[1] && match[2] ? actionKey(match[1], match[2]) : undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* What the platform's OpenAPI export is made with, from the config: a token is checked when `access.jwt` is on (the
|
|
56
|
-
* default when `auth` is set), a key unless `access.apiKey` is off.
|
|
57
|
-
*/
|
|
58
|
-
export function referenceOptions(
|
|
59
|
-
gateway: ResolvedGateway,
|
|
60
|
-
gatewayBaseUrl: string,
|
|
61
|
-
keyHeaderName?: string,
|
|
62
|
-
): ReferenceOptions {
|
|
63
|
-
const access = gateway.policies.access;
|
|
64
|
-
const jwt = access?.jwt ?? gateway.auth !== undefined;
|
|
65
|
-
const keys = (list?: string[]) =>
|
|
66
|
-
new Set(
|
|
67
|
-
(list ?? []).flatMap((entry) => {
|
|
68
|
-
const key = configActionKey(entry);
|
|
69
|
-
return key ? [key] : [];
|
|
70
|
-
}),
|
|
71
|
-
);
|
|
72
|
-
return {
|
|
73
|
-
gatewayBaseUrl,
|
|
74
|
-
originUrl: gateway.origin.url,
|
|
75
|
-
jwtRequired: jwt && gateway.auth !== undefined,
|
|
76
|
-
oidcMetadataUrl: jwt ? gateway.auth?.metadataUrl : undefined,
|
|
77
|
-
apiKeyRequired: access?.apiKey ?? true,
|
|
78
|
-
apiKeyHeader: keyHeaderName ?? access?.apiKeyHeader ?? DEFAULT_KEY_HEADER,
|
|
79
|
-
publicOperations: keys(gateway.policies.operations?.public),
|
|
80
|
-
deniedOperations: keys(gateway.policies.operations?.deny),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export class ReferenceSpecError extends Error {
|
|
85
|
-
constructor(message: string) {
|
|
86
|
-
super(message);
|
|
87
|
-
this.name = "ReferenceSpecError";
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function operationsOf(paths: Json): [string, Json, (typeof METHODS)[number]][] {
|
|
92
|
-
return Object.entries(paths).flatMap(([path, item]) =>
|
|
93
|
-
isObject(item)
|
|
94
|
-
? METHODS.filter((method) => isObject(item[method])).map(
|
|
95
|
-
(method) =>
|
|
96
|
-
[path, item, method] as [string, Json, (typeof METHODS)[number]],
|
|
97
|
-
)
|
|
98
|
-
: [],
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* The document the portal's API page shows. It follows what the platform exports for outside docs tools: servers
|
|
104
|
-
* point at the gateway, the security schemes say what the gateway really checks, denied operations are gone, public
|
|
105
|
-
* operations carry no security, and the origin address never shows (it is replaced by the gateway address).
|
|
106
|
-
*/
|
|
107
|
-
export function buildReferenceSpec(
|
|
108
|
-
specText: string,
|
|
109
|
-
options: ReferenceOptions,
|
|
110
|
-
): Json {
|
|
111
|
-
let root: unknown;
|
|
112
|
-
try {
|
|
113
|
-
root = parse(specText);
|
|
114
|
-
} catch {
|
|
115
|
-
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
116
|
-
}
|
|
117
|
-
if (!isObject(root) || typeof root.openapi !== "string")
|
|
118
|
-
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
119
|
-
|
|
120
|
-
const doc = structuredClone(root);
|
|
121
|
-
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
122
|
-
|
|
123
|
-
// Denied operations are removed; a path with nothing left goes too.
|
|
124
|
-
for (const [path, item, method] of operationsOf(paths))
|
|
125
|
-
if (options.deniedOperations.has(actionKey(method, path)))
|
|
126
|
-
delete item[method];
|
|
127
|
-
for (const [path, item] of Object.entries(paths))
|
|
128
|
-
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
129
|
-
delete paths[path];
|
|
130
|
-
|
|
131
|
-
// Public operations need neither token nor key.
|
|
132
|
-
for (const [path, item, method] of operationsOf(paths))
|
|
133
|
-
if (options.publicOperations.has(actionKey(method, path)))
|
|
134
|
-
(item[method] as Json).security = [];
|
|
135
|
-
|
|
136
|
-
// Servers on paths and operations would point somewhere else, often at the origin.
|
|
137
|
-
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
138
|
-
for (const item of Object.values(paths)) {
|
|
139
|
-
if (!isObject(item)) continue;
|
|
140
|
-
delete item.servers;
|
|
141
|
-
for (const method of METHODS) {
|
|
142
|
-
const operation = item[method];
|
|
143
|
-
if (isObject(operation)) delete operation.servers;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// The document describes the gateway, not the origin: the origin's own schemes are replaced.
|
|
148
|
-
const schemes: Json = {};
|
|
149
|
-
const requirement: Json = {};
|
|
150
|
-
if (options.jwtRequired) {
|
|
151
|
-
schemes.bearerAuth = {
|
|
152
|
-
type: "http",
|
|
153
|
-
scheme: "bearer",
|
|
154
|
-
bearerFormat: "JWT",
|
|
155
|
-
};
|
|
156
|
-
requirement.bearerAuth = [];
|
|
157
|
-
}
|
|
158
|
-
if (options.oidcMetadataUrl)
|
|
159
|
-
schemes.openIdAuth = {
|
|
160
|
-
type: "openIdConnect",
|
|
161
|
-
openIdConnectUrl: options.oidcMetadataUrl,
|
|
162
|
-
};
|
|
163
|
-
if (options.apiKeyRequired) {
|
|
164
|
-
schemes.apiKeyAuth = {
|
|
165
|
-
type: "apiKey",
|
|
166
|
-
in: "header",
|
|
167
|
-
name: options.apiKeyHeader,
|
|
168
|
-
};
|
|
169
|
-
requirement.apiKeyAuth = [];
|
|
170
|
-
}
|
|
171
|
-
const components = isObject(doc.components) ? doc.components : {};
|
|
172
|
-
if (Object.keys(schemes).length > 0) components.securitySchemes = schemes;
|
|
173
|
-
else delete components.securitySchemes;
|
|
174
|
-
if (Object.keys(components).length > 0) doc.components = components;
|
|
175
|
-
else delete doc.components;
|
|
176
|
-
// One requirement with both schemes means both are needed together.
|
|
177
|
-
doc.security = Object.keys(requirement).length > 0 ? [requirement] : [];
|
|
178
|
-
for (const [, item, method] of operationsOf(paths)) {
|
|
179
|
-
const operation = item[method] as Json;
|
|
180
|
-
if (Array.isArray(operation.security) && operation.security.length > 0)
|
|
181
|
-
delete operation.security;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return JSON.parse(hideOrigin(JSON.stringify(doc), options)) as Json;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/** The origin address must not show anywhere, not even in a description. */
|
|
188
|
-
function hideOrigin(text: string, options: ReferenceOptions): string {
|
|
189
|
-
const origin = options.originUrl?.trim().replace(/\/+$/, "");
|
|
190
|
-
if (!origin) return text;
|
|
191
|
-
const gateway = options.gatewayBaseUrl.trim().replace(/\/+$/, "");
|
|
192
|
-
// JSON.stringify leaves slashes as they are, so the plain address is what to look for.
|
|
193
|
-
const pattern = new RegExp(
|
|
194
|
-
origin.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&"),
|
|
195
|
-
"gi",
|
|
196
|
-
);
|
|
197
|
-
return text.replace(pattern, () => gateway);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/** Reads the gateway's OpenAPI file and builds the reference document. Returns JSON text, one key order per input. */
|
|
201
|
-
export async function renderReferenceSpec(
|
|
202
|
-
gateway: ResolvedGateway,
|
|
203
|
-
gatewayBaseUrl: string,
|
|
204
|
-
keyHeaderName?: string,
|
|
205
|
-
): Promise<string> {
|
|
206
|
-
const file = gateway.specs[0];
|
|
207
|
-
if (!file)
|
|
208
|
-
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
209
|
-
let text: string;
|
|
210
|
-
try {
|
|
211
|
-
text = await readFile(file, "utf8");
|
|
212
|
-
} catch {
|
|
213
|
-
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
214
|
-
}
|
|
215
|
-
const spec = buildReferenceSpec(
|
|
216
|
-
text,
|
|
217
|
-
referenceOptions(gateway, gatewayBaseUrl, keyHeaderName),
|
|
218
|
-
);
|
|
219
|
-
return `${JSON.stringify(spec, null, 2)}\n`;
|
|
220
|
-
}
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parse } from "yaml";
|
|
3
|
+
import type { ResolvedGateway } from "./resolve.js";
|
|
4
|
+
|
|
5
|
+
/** What the gateway checks, in the terms the exported OpenAPI file uses. */
|
|
6
|
+
export type ReferenceOptions = {
|
|
7
|
+
/** The address callers use. Replaces every server of the spec. */
|
|
8
|
+
gatewayBaseUrl: string;
|
|
9
|
+
/** The customer's own API address. It must never appear in the result. */
|
|
10
|
+
originUrl?: string;
|
|
11
|
+
jwtRequired: boolean;
|
|
12
|
+
oidcMetadataUrl?: string;
|
|
13
|
+
apiKeyRequired: boolean;
|
|
14
|
+
apiKeyHeader: string;
|
|
15
|
+
/** Action keys such as `get:/orders`. */
|
|
16
|
+
publicOperations: ReadonlySet<string>;
|
|
17
|
+
deniedOperations: ReadonlySet<string>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Header of the API key when the gateway does not say otherwise (same as the platform's OpenAPI export). */
|
|
21
|
+
export const DEFAULT_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
22
|
+
|
|
23
|
+
const METHODS = [
|
|
24
|
+
"get",
|
|
25
|
+
"put",
|
|
26
|
+
"post",
|
|
27
|
+
"delete",
|
|
28
|
+
"options",
|
|
29
|
+
"head",
|
|
30
|
+
"patch",
|
|
31
|
+
"trace",
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
type Json = Record<string, unknown>;
|
|
35
|
+
|
|
36
|
+
const isObject = (value: unknown): value is Json =>
|
|
37
|
+
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38
|
+
|
|
39
|
+
/** `GET /orders/` becomes `get:/orders`, the key the platform uses for an operation. */
|
|
40
|
+
export function actionKey(method: string, path: string): string {
|
|
41
|
+
const trimmed = path.trim();
|
|
42
|
+
const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
43
|
+
const normalized =
|
|
44
|
+
withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
|
|
45
|
+
return `${method.trim().toLowerCase()}:${normalized}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A config entry like `GET /orders` as an action key, or undefined when it has no method and path. */
|
|
49
|
+
export function configActionKey(entry: string): string | undefined {
|
|
50
|
+
const match = /^\s*([A-Za-z]+)\s+(\S+)\s*$/.exec(entry);
|
|
51
|
+
return match?.[1] && match[2] ? actionKey(match[1], match[2]) : undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What the platform's OpenAPI export is made with, from the config: a token is checked when `access.jwt` is on (the
|
|
56
|
+
* default when `auth` is set), a key unless `access.apiKey` is off.
|
|
57
|
+
*/
|
|
58
|
+
export function referenceOptions(
|
|
59
|
+
gateway: ResolvedGateway,
|
|
60
|
+
gatewayBaseUrl: string,
|
|
61
|
+
keyHeaderName?: string,
|
|
62
|
+
): ReferenceOptions {
|
|
63
|
+
const access = gateway.policies.access;
|
|
64
|
+
const jwt = access?.jwt ?? gateway.auth !== undefined;
|
|
65
|
+
const keys = (list?: string[]) =>
|
|
66
|
+
new Set(
|
|
67
|
+
(list ?? []).flatMap((entry) => {
|
|
68
|
+
const key = configActionKey(entry);
|
|
69
|
+
return key ? [key] : [];
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
|
+
return {
|
|
73
|
+
gatewayBaseUrl,
|
|
74
|
+
originUrl: gateway.origin.url,
|
|
75
|
+
jwtRequired: jwt && gateway.auth !== undefined,
|
|
76
|
+
oidcMetadataUrl: jwt ? gateway.auth?.metadataUrl : undefined,
|
|
77
|
+
apiKeyRequired: access?.apiKey ?? true,
|
|
78
|
+
apiKeyHeader: keyHeaderName ?? access?.apiKeyHeader ?? DEFAULT_KEY_HEADER,
|
|
79
|
+
publicOperations: keys(gateway.policies.operations?.public),
|
|
80
|
+
deniedOperations: keys(gateway.policies.operations?.deny),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class ReferenceSpecError extends Error {
|
|
85
|
+
constructor(message: string) {
|
|
86
|
+
super(message);
|
|
87
|
+
this.name = "ReferenceSpecError";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function operationsOf(paths: Json): [string, Json, (typeof METHODS)[number]][] {
|
|
92
|
+
return Object.entries(paths).flatMap(([path, item]) =>
|
|
93
|
+
isObject(item)
|
|
94
|
+
? METHODS.filter((method) => isObject(item[method])).map(
|
|
95
|
+
(method) =>
|
|
96
|
+
[path, item, method] as [string, Json, (typeof METHODS)[number]],
|
|
97
|
+
)
|
|
98
|
+
: [],
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The document the portal's API page shows. It follows what the platform exports for outside docs tools: servers
|
|
104
|
+
* point at the gateway, the security schemes say what the gateway really checks, denied operations are gone, public
|
|
105
|
+
* operations carry no security, and the origin address never shows (it is replaced by the gateway address).
|
|
106
|
+
*/
|
|
107
|
+
export function buildReferenceSpec(
|
|
108
|
+
specText: string,
|
|
109
|
+
options: ReferenceOptions,
|
|
110
|
+
): Json {
|
|
111
|
+
let root: unknown;
|
|
112
|
+
try {
|
|
113
|
+
root = parse(specText);
|
|
114
|
+
} catch {
|
|
115
|
+
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
116
|
+
}
|
|
117
|
+
if (!isObject(root) || typeof root.openapi !== "string")
|
|
118
|
+
throw new ReferenceSpecError("The OpenAPI file could not be read.");
|
|
119
|
+
|
|
120
|
+
const doc = structuredClone(root);
|
|
121
|
+
const paths = isObject(doc.paths) ? doc.paths : {};
|
|
122
|
+
|
|
123
|
+
// Denied operations are removed; a path with nothing left goes too.
|
|
124
|
+
for (const [path, item, method] of operationsOf(paths))
|
|
125
|
+
if (options.deniedOperations.has(actionKey(method, path)))
|
|
126
|
+
delete item[method];
|
|
127
|
+
for (const [path, item] of Object.entries(paths))
|
|
128
|
+
if (!isObject(item) || !METHODS.some((method) => method in item))
|
|
129
|
+
delete paths[path];
|
|
130
|
+
|
|
131
|
+
// Public operations need neither token nor key.
|
|
132
|
+
for (const [path, item, method] of operationsOf(paths))
|
|
133
|
+
if (options.publicOperations.has(actionKey(method, path)))
|
|
134
|
+
(item[method] as Json).security = [];
|
|
135
|
+
|
|
136
|
+
// Servers on paths and operations would point somewhere else, often at the origin.
|
|
137
|
+
doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
|
|
138
|
+
for (const item of Object.values(paths)) {
|
|
139
|
+
if (!isObject(item)) continue;
|
|
140
|
+
delete item.servers;
|
|
141
|
+
for (const method of METHODS) {
|
|
142
|
+
const operation = item[method];
|
|
143
|
+
if (isObject(operation)) delete operation.servers;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// The document describes the gateway, not the origin: the origin's own schemes are replaced.
|
|
148
|
+
const schemes: Json = {};
|
|
149
|
+
const requirement: Json = {};
|
|
150
|
+
if (options.jwtRequired) {
|
|
151
|
+
schemes.bearerAuth = {
|
|
152
|
+
type: "http",
|
|
153
|
+
scheme: "bearer",
|
|
154
|
+
bearerFormat: "JWT",
|
|
155
|
+
};
|
|
156
|
+
requirement.bearerAuth = [];
|
|
157
|
+
}
|
|
158
|
+
if (options.oidcMetadataUrl)
|
|
159
|
+
schemes.openIdAuth = {
|
|
160
|
+
type: "openIdConnect",
|
|
161
|
+
openIdConnectUrl: options.oidcMetadataUrl,
|
|
162
|
+
};
|
|
163
|
+
if (options.apiKeyRequired) {
|
|
164
|
+
schemes.apiKeyAuth = {
|
|
165
|
+
type: "apiKey",
|
|
166
|
+
in: "header",
|
|
167
|
+
name: options.apiKeyHeader,
|
|
168
|
+
};
|
|
169
|
+
requirement.apiKeyAuth = [];
|
|
170
|
+
}
|
|
171
|
+
const components = isObject(doc.components) ? doc.components : {};
|
|
172
|
+
if (Object.keys(schemes).length > 0) components.securitySchemes = schemes;
|
|
173
|
+
else delete components.securitySchemes;
|
|
174
|
+
if (Object.keys(components).length > 0) doc.components = components;
|
|
175
|
+
else delete doc.components;
|
|
176
|
+
// One requirement with both schemes means both are needed together.
|
|
177
|
+
doc.security = Object.keys(requirement).length > 0 ? [requirement] : [];
|
|
178
|
+
for (const [, item, method] of operationsOf(paths)) {
|
|
179
|
+
const operation = item[method] as Json;
|
|
180
|
+
if (Array.isArray(operation.security) && operation.security.length > 0)
|
|
181
|
+
delete operation.security;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return JSON.parse(hideOrigin(JSON.stringify(doc), options)) as Json;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** The origin address must not show anywhere, not even in a description. */
|
|
188
|
+
function hideOrigin(text: string, options: ReferenceOptions): string {
|
|
189
|
+
const origin = options.originUrl?.trim().replace(/\/+$/, "");
|
|
190
|
+
if (!origin) return text;
|
|
191
|
+
const gateway = options.gatewayBaseUrl.trim().replace(/\/+$/, "");
|
|
192
|
+
// JSON.stringify leaves slashes as they are, so the plain address is what to look for.
|
|
193
|
+
const pattern = new RegExp(
|
|
194
|
+
origin.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&"),
|
|
195
|
+
"gi",
|
|
196
|
+
);
|
|
197
|
+
return text.replace(pattern, () => gateway);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Reads the gateway's OpenAPI file and builds the reference document. Returns JSON text, one key order per input. */
|
|
201
|
+
export async function renderReferenceSpec(
|
|
202
|
+
gateway: ResolvedGateway,
|
|
203
|
+
gatewayBaseUrl: string,
|
|
204
|
+
keyHeaderName?: string,
|
|
205
|
+
): Promise<string> {
|
|
206
|
+
const file = gateway.specs[0];
|
|
207
|
+
if (!file)
|
|
208
|
+
throw new ReferenceSpecError("gateway.specs lists no OpenAPI file.");
|
|
209
|
+
let text: string;
|
|
210
|
+
try {
|
|
211
|
+
text = await readFile(file, "utf8");
|
|
212
|
+
} catch {
|
|
213
|
+
throw new ReferenceSpecError(`Cannot read the OpenAPI file ${file}.`);
|
|
214
|
+
}
|
|
215
|
+
const spec = buildReferenceSpec(
|
|
216
|
+
text,
|
|
217
|
+
referenceOptions(gateway, gatewayBaseUrl, keyHeaderName),
|
|
218
|
+
);
|
|
219
|
+
return `${JSON.stringify(spec, null, 2)}\n`;
|
|
220
|
+
}
|