@lukoweb/apitogo 0.2.23 → 0.2.25
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 +318 -20
- 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 +3 -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
package/src/config/v2/parse.ts
CHANGED
|
@@ -1,214 +1,214 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { ConfigError, type ConfigIssue } from "./errors.js";
|
|
3
|
-
import { CONFIG_VERSION, type ConfigV2, ConfigV2Schema } from "./schema.js";
|
|
4
|
-
|
|
5
|
-
/** Keys that existed in an earlier design and were removed on purpose, with the reason to show the tenant. */
|
|
6
|
-
const REMOVED_KEYS: Readonly<Record<string, string>> = {
|
|
7
|
-
"plans.provider":
|
|
8
|
-
"plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable.",
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type PathSegment = PropertyKey;
|
|
12
|
-
|
|
13
|
-
function pathToString(path: readonly PathSegment[]): string {
|
|
14
|
-
return path.reduce<string>(
|
|
15
|
-
(acc, segment) =>
|
|
16
|
-
typeof segment === "number"
|
|
17
|
-
? `${acc}[${segment}]`
|
|
18
|
-
: acc === ""
|
|
19
|
-
? String(segment)
|
|
20
|
-
: `${acc}.${String(segment)}`,
|
|
21
|
-
"",
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function unwrapOptional(schema: z.core.$ZodType): z.core.$ZodType {
|
|
26
|
-
let current = schema;
|
|
27
|
-
while (current instanceof z.ZodOptional) current = current.unwrap();
|
|
28
|
-
return current;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function step(
|
|
32
|
-
schema: z.core.$ZodType,
|
|
33
|
-
segment: PathSegment,
|
|
34
|
-
): z.core.$ZodType | undefined {
|
|
35
|
-
const current = unwrapOptional(schema);
|
|
36
|
-
if (current instanceof z.ZodObject && typeof segment === "string") {
|
|
37
|
-
return current.shape[segment];
|
|
38
|
-
}
|
|
39
|
-
if (current instanceof z.ZodArray && typeof segment === "number") {
|
|
40
|
-
return current.element;
|
|
41
|
-
}
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** The keys the schema accepts at `path`, used for "did you mean" hints. Empty when the path cannot be resolved. */
|
|
46
|
-
function knownKeysAt(path: readonly PathSegment[]): string[] {
|
|
47
|
-
let current: z.core.$ZodType | undefined = ConfigV2Schema;
|
|
48
|
-
for (const segment of path) {
|
|
49
|
-
if (!current) return [];
|
|
50
|
-
current = step(current, segment);
|
|
51
|
-
}
|
|
52
|
-
if (!current) return [];
|
|
53
|
-
const resolved = unwrapOptional(current);
|
|
54
|
-
return resolved instanceof z.ZodObject ? Object.keys(resolved.shape) : [];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function editDistance(a: string, b: string): number {
|
|
58
|
-
const row = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
59
|
-
for (let i = 1; i <= a.length; i++) {
|
|
60
|
-
let previous = row[0] ?? 0;
|
|
61
|
-
row[0] = i;
|
|
62
|
-
for (let j = 1; j <= b.length; j++) {
|
|
63
|
-
const current = row[j] ?? 0;
|
|
64
|
-
row[j] = Math.min(
|
|
65
|
-
(row[j] ?? 0) + 1,
|
|
66
|
-
(row[j - 1] ?? 0) + 1,
|
|
67
|
-
previous + (a[i - 1] === b[j - 1] ? 0 : 1),
|
|
68
|
-
);
|
|
69
|
-
previous = current;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return row[b.length] ?? 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function unknownKeyHint(
|
|
76
|
-
fullPath: string,
|
|
77
|
-
key: string,
|
|
78
|
-
known: readonly string[],
|
|
79
|
-
): string | undefined {
|
|
80
|
-
const removed = REMOVED_KEYS[fullPath];
|
|
81
|
-
if (removed) return removed;
|
|
82
|
-
|
|
83
|
-
const closest = known
|
|
84
|
-
.map((candidate) => ({
|
|
85
|
-
candidate,
|
|
86
|
-
distance: editDistance(key.toLowerCase(), candidate.toLowerCase()),
|
|
87
|
-
}))
|
|
88
|
-
.filter(({ distance }) => distance <= 2)
|
|
89
|
-
.sort((a, b) => a.distance - b.distance)[0];
|
|
90
|
-
if (closest) return `Did you mean "${closest.candidate}"?`;
|
|
91
|
-
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : undefined;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function mapIssue(issue: z.core.$ZodIssue): ConfigIssue[] {
|
|
95
|
-
const path = pathToString(issue.path);
|
|
96
|
-
|
|
97
|
-
switch (issue.code) {
|
|
98
|
-
case "unrecognized_keys":
|
|
99
|
-
return issue.keys.map((key) => {
|
|
100
|
-
const fullPath = pathToString([...issue.path, key]);
|
|
101
|
-
return {
|
|
102
|
-
code: "CONFIG_UNKNOWN_KEY",
|
|
103
|
-
path: fullPath,
|
|
104
|
-
message: `Unknown key "${key}".`,
|
|
105
|
-
hint: unknownKeyHint(fullPath, key, knownKeysAt(issue.path)),
|
|
106
|
-
};
|
|
107
|
-
});
|
|
108
|
-
case "invalid_value":
|
|
109
|
-
return [
|
|
110
|
-
{
|
|
111
|
-
code: "CONFIG_INVALID_VALUE",
|
|
112
|
-
path,
|
|
113
|
-
message: `must be one of: ${issue.values.map((v) => JSON.stringify(v)).join(", ")}.`,
|
|
114
|
-
},
|
|
115
|
-
];
|
|
116
|
-
case "custom": {
|
|
117
|
-
const code =
|
|
118
|
-
typeof issue.params?.code === "string"
|
|
119
|
-
? issue.params.code
|
|
120
|
-
: "CONFIG_INVALID_VALUE";
|
|
121
|
-
return [{ code, path, message: issue.message ?? "is invalid." }];
|
|
122
|
-
}
|
|
123
|
-
case "invalid_type":
|
|
124
|
-
return [
|
|
125
|
-
/received undefined/.test(issue.message)
|
|
126
|
-
? { code: "CONFIG_MISSING_FIELD", path, message: "is required." }
|
|
127
|
-
: { code: "CONFIG_INVALID_VALUE", path, message: issue.message },
|
|
128
|
-
];
|
|
129
|
-
default:
|
|
130
|
-
return [{ code: "CONFIG_INVALID_VALUE", path, message: issue.message }];
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
135
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Checks that must run before the schema because the schema cannot express them well: the version gate and the
|
|
140
|
-
* one legacy shape that deserves its own message. Returns the issues, the value to validate, and whether to stop.
|
|
141
|
-
*/
|
|
142
|
-
function preflight(raw: unknown): {
|
|
143
|
-
issues: ConfigIssue[];
|
|
144
|
-
value: unknown;
|
|
145
|
-
stop: boolean;
|
|
146
|
-
} {
|
|
147
|
-
if (!isRecord(raw)) {
|
|
148
|
-
return {
|
|
149
|
-
issues: [
|
|
150
|
-
{
|
|
151
|
-
code: "CONFIG_INVALID_VALUE",
|
|
152
|
-
path: "",
|
|
153
|
-
message: "The config must be a JSON object.",
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
value: raw,
|
|
157
|
-
stop: true,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (raw.version !== CONFIG_VERSION) {
|
|
162
|
-
const found =
|
|
163
|
-
raw.version === undefined
|
|
164
|
-
? '"version" is missing.'
|
|
165
|
-
: `"version" is ${JSON.stringify(raw.version)}.`;
|
|
166
|
-
return {
|
|
167
|
-
issues: [
|
|
168
|
-
{
|
|
169
|
-
code: "CONFIG_VERSION_UNSUPPORTED",
|
|
170
|
-
path: "version",
|
|
171
|
-
message: `${found} This CLI reads config version ${CONFIG_VERSION}.`,
|
|
172
|
-
hint: `Set "version": ${CONFIG_VERSION}. Earlier flat configs are not supported; see the Tenant Service Model for the new shape.`,
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
value: raw,
|
|
176
|
-
stop: true,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const issues: ConfigIssue[] = [];
|
|
181
|
-
const value = structuredClone(raw);
|
|
182
|
-
const portal = value.portal;
|
|
183
|
-
if (isRecord(portal) && Array.isArray(portal.docs)) {
|
|
184
|
-
issues.push({
|
|
185
|
-
code: "PORTAL_CONFIG_INVALID",
|
|
186
|
-
path: "portal.docs",
|
|
187
|
-
message:
|
|
188
|
-
"portal.docs is now an object. Rename the globs array to portal.docs.content.",
|
|
189
|
-
hint: 'For example: "docs": { "content": ["docs/**/*.md"] }',
|
|
190
|
-
});
|
|
191
|
-
// Reported above; keep the schema from reporting the same value again as a type error.
|
|
192
|
-
delete portal.docs;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return { issues, value, stop: false };
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** Validates a parsed config. Throws a {@link ConfigError} listing every problem found. */
|
|
199
|
-
export function parseConfigV2(
|
|
200
|
-
raw: unknown,
|
|
201
|
-
file = "apitogo.config.json",
|
|
202
|
-
): ConfigV2 {
|
|
203
|
-
const pre = preflight(raw);
|
|
204
|
-
if (pre.stop) throw new ConfigError(file, pre.issues);
|
|
205
|
-
|
|
206
|
-
const result = ConfigV2Schema.safeParse(pre.value);
|
|
207
|
-
const issues = [
|
|
208
|
-
...pre.issues,
|
|
209
|
-
...(result.success ? [] : result.error.issues.flatMap(mapIssue)),
|
|
210
|
-
];
|
|
211
|
-
|
|
212
|
-
if (issues.length > 0 || !result.success) throw new ConfigError(file, issues);
|
|
213
|
-
return result.data;
|
|
214
|
-
}
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ConfigError, type ConfigIssue } from "./errors.js";
|
|
3
|
+
import { CONFIG_VERSION, type ConfigV2, ConfigV2Schema } from "./schema.js";
|
|
4
|
+
|
|
5
|
+
/** Keys that existed in an earlier design and were removed on purpose, with the reason to show the tenant. */
|
|
6
|
+
const REMOVED_KEYS: Readonly<Record<string, string>> = {
|
|
7
|
+
"plans.provider":
|
|
8
|
+
"plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type PathSegment = PropertyKey;
|
|
12
|
+
|
|
13
|
+
function pathToString(path: readonly PathSegment[]): string {
|
|
14
|
+
return path.reduce<string>(
|
|
15
|
+
(acc, segment) =>
|
|
16
|
+
typeof segment === "number"
|
|
17
|
+
? `${acc}[${segment}]`
|
|
18
|
+
: acc === ""
|
|
19
|
+
? String(segment)
|
|
20
|
+
: `${acc}.${String(segment)}`,
|
|
21
|
+
"",
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function unwrapOptional(schema: z.core.$ZodType): z.core.$ZodType {
|
|
26
|
+
let current = schema;
|
|
27
|
+
while (current instanceof z.ZodOptional) current = current.unwrap();
|
|
28
|
+
return current;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function step(
|
|
32
|
+
schema: z.core.$ZodType,
|
|
33
|
+
segment: PathSegment,
|
|
34
|
+
): z.core.$ZodType | undefined {
|
|
35
|
+
const current = unwrapOptional(schema);
|
|
36
|
+
if (current instanceof z.ZodObject && typeof segment === "string") {
|
|
37
|
+
return current.shape[segment];
|
|
38
|
+
}
|
|
39
|
+
if (current instanceof z.ZodArray && typeof segment === "number") {
|
|
40
|
+
return current.element;
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The keys the schema accepts at `path`, used for "did you mean" hints. Empty when the path cannot be resolved. */
|
|
46
|
+
function knownKeysAt(path: readonly PathSegment[]): string[] {
|
|
47
|
+
let current: z.core.$ZodType | undefined = ConfigV2Schema;
|
|
48
|
+
for (const segment of path) {
|
|
49
|
+
if (!current) return [];
|
|
50
|
+
current = step(current, segment);
|
|
51
|
+
}
|
|
52
|
+
if (!current) return [];
|
|
53
|
+
const resolved = unwrapOptional(current);
|
|
54
|
+
return resolved instanceof z.ZodObject ? Object.keys(resolved.shape) : [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function editDistance(a: string, b: string): number {
|
|
58
|
+
const row = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
59
|
+
for (let i = 1; i <= a.length; i++) {
|
|
60
|
+
let previous = row[0] ?? 0;
|
|
61
|
+
row[0] = i;
|
|
62
|
+
for (let j = 1; j <= b.length; j++) {
|
|
63
|
+
const current = row[j] ?? 0;
|
|
64
|
+
row[j] = Math.min(
|
|
65
|
+
(row[j] ?? 0) + 1,
|
|
66
|
+
(row[j - 1] ?? 0) + 1,
|
|
67
|
+
previous + (a[i - 1] === b[j - 1] ? 0 : 1),
|
|
68
|
+
);
|
|
69
|
+
previous = current;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return row[b.length] ?? 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function unknownKeyHint(
|
|
76
|
+
fullPath: string,
|
|
77
|
+
key: string,
|
|
78
|
+
known: readonly string[],
|
|
79
|
+
): string | undefined {
|
|
80
|
+
const removed = REMOVED_KEYS[fullPath];
|
|
81
|
+
if (removed) return removed;
|
|
82
|
+
|
|
83
|
+
const closest = known
|
|
84
|
+
.map((candidate) => ({
|
|
85
|
+
candidate,
|
|
86
|
+
distance: editDistance(key.toLowerCase(), candidate.toLowerCase()),
|
|
87
|
+
}))
|
|
88
|
+
.filter(({ distance }) => distance <= 2)
|
|
89
|
+
.sort((a, b) => a.distance - b.distance)[0];
|
|
90
|
+
if (closest) return `Did you mean "${closest.candidate}"?`;
|
|
91
|
+
return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function mapIssue(issue: z.core.$ZodIssue): ConfigIssue[] {
|
|
95
|
+
const path = pathToString(issue.path);
|
|
96
|
+
|
|
97
|
+
switch (issue.code) {
|
|
98
|
+
case "unrecognized_keys":
|
|
99
|
+
return issue.keys.map((key) => {
|
|
100
|
+
const fullPath = pathToString([...issue.path, key]);
|
|
101
|
+
return {
|
|
102
|
+
code: "CONFIG_UNKNOWN_KEY",
|
|
103
|
+
path: fullPath,
|
|
104
|
+
message: `Unknown key "${key}".`,
|
|
105
|
+
hint: unknownKeyHint(fullPath, key, knownKeysAt(issue.path)),
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
case "invalid_value":
|
|
109
|
+
return [
|
|
110
|
+
{
|
|
111
|
+
code: "CONFIG_INVALID_VALUE",
|
|
112
|
+
path,
|
|
113
|
+
message: `must be one of: ${issue.values.map((v) => JSON.stringify(v)).join(", ")}.`,
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
case "custom": {
|
|
117
|
+
const code =
|
|
118
|
+
typeof issue.params?.code === "string"
|
|
119
|
+
? issue.params.code
|
|
120
|
+
: "CONFIG_INVALID_VALUE";
|
|
121
|
+
return [{ code, path, message: issue.message ?? "is invalid." }];
|
|
122
|
+
}
|
|
123
|
+
case "invalid_type":
|
|
124
|
+
return [
|
|
125
|
+
/received undefined/.test(issue.message)
|
|
126
|
+
? { code: "CONFIG_MISSING_FIELD", path, message: "is required." }
|
|
127
|
+
: { code: "CONFIG_INVALID_VALUE", path, message: issue.message },
|
|
128
|
+
];
|
|
129
|
+
default:
|
|
130
|
+
return [{ code: "CONFIG_INVALID_VALUE", path, message: issue.message }];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
135
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Checks that must run before the schema because the schema cannot express them well: the version gate and the
|
|
140
|
+
* one legacy shape that deserves its own message. Returns the issues, the value to validate, and whether to stop.
|
|
141
|
+
*/
|
|
142
|
+
function preflight(raw: unknown): {
|
|
143
|
+
issues: ConfigIssue[];
|
|
144
|
+
value: unknown;
|
|
145
|
+
stop: boolean;
|
|
146
|
+
} {
|
|
147
|
+
if (!isRecord(raw)) {
|
|
148
|
+
return {
|
|
149
|
+
issues: [
|
|
150
|
+
{
|
|
151
|
+
code: "CONFIG_INVALID_VALUE",
|
|
152
|
+
path: "",
|
|
153
|
+
message: "The config must be a JSON object.",
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
value: raw,
|
|
157
|
+
stop: true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (raw.version !== CONFIG_VERSION) {
|
|
162
|
+
const found =
|
|
163
|
+
raw.version === undefined
|
|
164
|
+
? '"version" is missing.'
|
|
165
|
+
: `"version" is ${JSON.stringify(raw.version)}.`;
|
|
166
|
+
return {
|
|
167
|
+
issues: [
|
|
168
|
+
{
|
|
169
|
+
code: "CONFIG_VERSION_UNSUPPORTED",
|
|
170
|
+
path: "version",
|
|
171
|
+
message: `${found} This CLI reads config version ${CONFIG_VERSION}.`,
|
|
172
|
+
hint: `Set "version": ${CONFIG_VERSION}. Earlier flat configs are not supported; see the Tenant Service Model for the new shape.`,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
value: raw,
|
|
176
|
+
stop: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const issues: ConfigIssue[] = [];
|
|
181
|
+
const value = structuredClone(raw);
|
|
182
|
+
const portal = value.portal;
|
|
183
|
+
if (isRecord(portal) && Array.isArray(portal.docs)) {
|
|
184
|
+
issues.push({
|
|
185
|
+
code: "PORTAL_CONFIG_INVALID",
|
|
186
|
+
path: "portal.docs",
|
|
187
|
+
message:
|
|
188
|
+
"portal.docs is now an object. Rename the globs array to portal.docs.content.",
|
|
189
|
+
hint: 'For example: "docs": { "content": ["docs/**/*.md"] }',
|
|
190
|
+
});
|
|
191
|
+
// Reported above; keep the schema from reporting the same value again as a type error.
|
|
192
|
+
delete portal.docs;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return { issues, value, stop: false };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Validates a parsed config. Throws a {@link ConfigError} listing every problem found. */
|
|
199
|
+
export function parseConfigV2(
|
|
200
|
+
raw: unknown,
|
|
201
|
+
file = "apitogo.config.json",
|
|
202
|
+
): ConfigV2 {
|
|
203
|
+
const pre = preflight(raw);
|
|
204
|
+
if (pre.stop) throw new ConfigError(file, pre.issues);
|
|
205
|
+
|
|
206
|
+
const result = ConfigV2Schema.safeParse(pre.value);
|
|
207
|
+
const issues = [
|
|
208
|
+
...pre.issues,
|
|
209
|
+
...(result.success ? [] : result.error.issues.flatMap(mapIssue)),
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
if (issues.length > 0 || !result.success) throw new ConfigError(file, issues);
|
|
213
|
+
return result.data;
|
|
214
|
+
}
|
package/src/config/v2/paths.ts
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import type { Layout } from "./schema.js";
|
|
3
|
-
|
|
4
|
-
/** Names inside the generated-state directory (Tenant Service Model, section 4). All of it is regenerable. */
|
|
5
|
-
export const STATE_FILE = "state.json";
|
|
6
|
-
/** Service manifest written by `deploy` (Reference, section 4). Public values only. */
|
|
7
|
-
export const MANIFEST_FILE = "services.json";
|
|
8
|
-
export const GENERATED_DIR = "generated";
|
|
9
|
-
export const BUILD_DIR = "build";
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Directory that holds the tenant-authored content for a layout: the config's own directory for `standalone`,
|
|
13
|
-
* an `apitogo/` folder next to it for `embedded`.
|
|
14
|
-
*/
|
|
15
|
-
export function layoutRoot(configDir: string, layout: Layout): string {
|
|
16
|
-
return layout === "embedded" ? path.join(configDir, "apitogo") : configDir;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Directory for generated and observed state. It carries its own `.gitignore` containing `*`, so the tenant's root
|
|
21
|
-
* `.gitignore` never needs to change.
|
|
22
|
-
*/
|
|
23
|
-
export function stateDirFor(configDir: string, layout: Layout): string {
|
|
24
|
-
return layout === "embedded"
|
|
25
|
-
? path.join(configDir, "apitogo", ".state")
|
|
26
|
-
: path.join(configDir, ".apitogo");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** Path of the service manifest inside a state directory. */
|
|
30
|
-
export const manifestPathFor = (state: { dir: string }): string =>
|
|
31
|
-
path.join(state.dir, MANIFEST_FILE);
|
|
32
|
-
|
|
33
|
-
export type StatePaths = {
|
|
34
|
-
dir: string;
|
|
35
|
-
/** Per-service ledger and artifact hashes. */
|
|
36
|
-
file: string;
|
|
37
|
-
/** Generated portal wrapper, resolved config snapshot, processed OpenAPI schemas. */
|
|
38
|
-
generatedDir: string;
|
|
39
|
-
/** Build output; replaces the old root `dist/`. */
|
|
40
|
-
buildDir: string;
|
|
41
|
-
/** The state directory's own ignore file. */
|
|
42
|
-
gitignore: string;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export function statePathsFor(configDir: string, layout: Layout): StatePaths {
|
|
46
|
-
const dir = stateDirFor(configDir, layout);
|
|
47
|
-
return {
|
|
48
|
-
dir,
|
|
49
|
-
file: path.join(dir, STATE_FILE),
|
|
50
|
-
generatedDir: path.join(dir, GENERATED_DIR),
|
|
51
|
-
buildDir: path.join(dir, BUILD_DIR),
|
|
52
|
-
gitignore: path.join(dir, ".gitignore"),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import type { Layout } from "./schema.js";
|
|
3
|
+
|
|
4
|
+
/** Names inside the generated-state directory (Tenant Service Model, section 4). All of it is regenerable. */
|
|
5
|
+
export const STATE_FILE = "state.json";
|
|
6
|
+
/** Service manifest written by `deploy` (Reference, section 4). Public values only. */
|
|
7
|
+
export const MANIFEST_FILE = "services.json";
|
|
8
|
+
export const GENERATED_DIR = "generated";
|
|
9
|
+
export const BUILD_DIR = "build";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Directory that holds the tenant-authored content for a layout: the config's own directory for `standalone`,
|
|
13
|
+
* an `apitogo/` folder next to it for `embedded`.
|
|
14
|
+
*/
|
|
15
|
+
export function layoutRoot(configDir: string, layout: Layout): string {
|
|
16
|
+
return layout === "embedded" ? path.join(configDir, "apitogo") : configDir;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Directory for generated and observed state. It carries its own `.gitignore` containing `*`, so the tenant's root
|
|
21
|
+
* `.gitignore` never needs to change.
|
|
22
|
+
*/
|
|
23
|
+
export function stateDirFor(configDir: string, layout: Layout): string {
|
|
24
|
+
return layout === "embedded"
|
|
25
|
+
? path.join(configDir, "apitogo", ".state")
|
|
26
|
+
: path.join(configDir, ".apitogo");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Path of the service manifest inside a state directory. */
|
|
30
|
+
export const manifestPathFor = (state: { dir: string }): string =>
|
|
31
|
+
path.join(state.dir, MANIFEST_FILE);
|
|
32
|
+
|
|
33
|
+
export type StatePaths = {
|
|
34
|
+
dir: string;
|
|
35
|
+
/** Per-service ledger and artifact hashes. */
|
|
36
|
+
file: string;
|
|
37
|
+
/** Generated portal wrapper, resolved config snapshot, processed OpenAPI schemas. */
|
|
38
|
+
generatedDir: string;
|
|
39
|
+
/** Build output; replaces the old root `dist/`. */
|
|
40
|
+
buildDir: string;
|
|
41
|
+
/** The state directory's own ignore file. */
|
|
42
|
+
gitignore: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export function statePathsFor(configDir: string, layout: Layout): StatePaths {
|
|
46
|
+
const dir = stateDirFor(configDir, layout);
|
|
47
|
+
return {
|
|
48
|
+
dir,
|
|
49
|
+
file: path.join(dir, STATE_FILE),
|
|
50
|
+
generatedDir: path.join(dir, GENERATED_DIR),
|
|
51
|
+
buildDir: path.join(dir, BUILD_DIR),
|
|
52
|
+
gitignore: path.join(dir, ".gitignore"),
|
|
53
|
+
};
|
|
54
|
+
}
|