@redocly/reef 0.140.0-next.1 → 0.140.0-next.13
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/CHANGELOG.md +419 -199
- package/dist/api-schemas/mcp-fetch-count.d.ts +2 -18
- package/dist/api-schemas/otel-traces.d.ts +7 -1345
- package/dist/api-schemas/otel-traces.js +1 -1
- package/dist/api-schemas/search-facets.d.ts +3 -31
- package/dist/api-schemas/search.d.ts +6 -52
- package/dist/cli/build/index.js +1 -1
- package/dist/cli/eject/resolveEjectParams.js +1 -1
- package/dist/cli/generate/get-schema-template.js +1 -1
- package/dist/client/app/hooks/markdown/useMarkdocRenderer.js +1 -1
- package/dist/client/app/hooks/markdown/useMarkdownText.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +2 -0
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.d.ts +1 -33
- package/dist/client/app/useGlobalData.d.ts +1 -1
- package/dist/client/providers/post-message/use-post-message.d.ts +1 -1
- package/dist/client/templates/api-docs/helpers.js +3 -3
- package/dist/compiled/@redocly/pii/index.mjs +1 -0
- package/dist/compiled/@redocly/pii/package.json +1 -0
- package/dist/compiled/svgo/svgo-node.js +1 -1
- package/dist/constants/l10n/langs/ar.js +1 -1
- package/dist/constants/l10n/langs/de.js +1 -1
- package/dist/constants/l10n/langs/en.js +1 -1
- package/dist/constants/l10n/langs/es.js +1 -1
- package/dist/constants/l10n/langs/fr.js +1 -1
- package/dist/constants/l10n/langs/hi.js +1 -1
- package/dist/constants/l10n/langs/it.js +1 -1
- package/dist/constants/l10n/langs/ja.js +1 -1
- package/dist/constants/l10n/langs/ko.js +1 -1
- package/dist/constants/l10n/langs/pl.js +1 -1
- package/dist/constants/l10n/langs/pt-BR.js +1 -1
- package/dist/constants/l10n/langs/pt.js +1 -1
- package/dist/constants/l10n/langs/ru.js +1 -1
- package/dist/constants/l10n/langs/uk.js +1 -1
- package/dist/constants/l10n/langs/zh.js +1 -1
- package/dist/markdoc/attributes/definition-path.d.ts +1 -1
- package/dist/markdoc/attributes/json-example-ref.d.ts +1 -1
- package/dist/markdoc/attributes/json-schema-ref.d.ts +1 -1
- package/dist/markdoc/attributes/parsed-yaml.d.ts +1 -1
- package/dist/markdoc/attributes/raw-content.d.ts +1 -1
- package/dist/markdoc/attributes/sample-from-json-schema.d.ts +1 -1
- package/dist/markdoc/helpers/extract-rbac-from-condition-node.d.ts +1 -1
- package/dist/markdoc/helpers/get-inner-text.d.ts +1 -1
- package/dist/markdoc/helpers/get-node-attribute.d.ts +1 -1
- package/dist/markdoc/helpers/get-variable.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-conditional-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-function.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-prompt-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-tag.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-variable.d.ts +1 -1
- package/dist/markdoc/helpers/parse-partials.d.ts +1 -1
- package/dist/markdoc/helpers/parse-partials.js +1 -1
- package/dist/markdoc/helpers/remove-markdoc-tags.js +1 -1
- package/dist/markdoc/helpers/set-node-attribute-value.d.ts +1 -1
- package/dist/markdoc/nodes/fence/index.d.ts +1 -1
- package/dist/markdoc/nodes/fence/index.js +1 -1
- package/dist/markdoc/nodes/gfm-list-item.d.ts +1 -1
- package/dist/markdoc/nodes/gfm-list-item.js +1 -1
- package/dist/markdoc/nodes/heading.d.ts +1 -1
- package/dist/markdoc/nodes/heading.js +1 -1
- package/dist/markdoc/nodes/index.d.ts +6 -165
- package/dist/markdoc/nodes/index.js +1 -1
- package/dist/markdoc/nodes/table.d.ts +1 -1
- package/dist/markdoc/nodes/table.js +1 -1
- package/dist/markdoc/nodes/text.d.ts +1 -1
- package/dist/markdoc/tags/json-example.js +1 -1
- package/dist/markdoc/tags/openapi-code-sample.js +1 -1
- package/dist/server/api-routes/execute-api-route.js +1 -1
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-config.d.ts +26 -24
- package/dist/server/config/env-schema.d.ts +87 -326
- package/dist/server/config/env-schemas/api-urls.d.ts +2 -14
- package/dist/server/config/env-schemas/auth.d.ts +10 -32
- package/dist/server/config/env-schemas/catalog.d.ts +6 -9
- package/dist/server/config/env-schemas/database.d.ts +2 -8
- package/dist/server/config/env-schemas/environment-detection.d.ts +20 -18
- package/dist/server/config/env-schemas/feature-flags.d.ts +29 -33
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/config/env-schemas/organization-project.d.ts +3 -21
- package/dist/server/config/env-schemas/scorecards.d.ts +2 -6
- package/dist/server/config/env-schemas/search.d.ts +9 -15
- package/dist/server/config/env-schemas/server-config.d.ts +6 -31
- package/dist/server/config/env-schemas/site.d.ts +1 -5
- package/dist/server/config/env-schemas/ssr.d.ts +7 -12
- package/dist/server/config/env-schemas/telemetry.d.ts +1 -7
- package/dist/server/constants/common.d.ts +3 -0
- package/dist/server/constants/common.js +1 -1
- package/dist/server/esbuild/plugins/dependency-resolver.js +1 -1
- package/dist/server/esbuild/plugins/styled-components-ssr.js +1 -1
- package/dist/server/esbuild/plugins/themes-resolver.js +3 -3
- package/dist/server/external-plugins/resolve-external-plugins.js +1 -1
- package/dist/server/node-bundle-entry.js +1 -1
- package/dist/server/plugins/analytics/amplitude/index.js +1 -1
- package/dist/server/plugins/analytics/ga/build-scripts.js +6 -6
- package/dist/server/plugins/api-docs/definition-access.d.ts +22 -0
- package/dist/server/plugins/api-docs/definition-access.js +1 -0
- package/dist/server/plugins/api-docs/index.js +1 -1
- package/dist/server/plugins/api-docs/loader.d.ts +1 -1
- package/dist/server/plugins/api-docs/options.js +1 -1
- package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +23 -23
- package/dist/server/plugins/api-docs/spec-download.api.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/filesets-resolver.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/index.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-code-snippet-from-file.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-diagram-from-file.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-href.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-source-attribute.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-gallery.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src-set.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-schema-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-native-md-link.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-nav-links.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-parsed-yaml.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-raw-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-or-cdn-icon.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-path.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-sample-from-json-schema.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-svg-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.js +2 -2
- package/dist/server/plugins/markdown/attribute-resolvers/utils.d.ts +1 -1
- package/dist/server/plugins/markdown/compiler.d.ts +1 -1
- package/dist/server/plugins/markdown/compiler.js +1 -1
- package/dist/server/plugins/markdown/errors.d.ts +1 -1
- package/dist/server/plugins/markdown/get-server-props.js +1 -1
- package/dist/server/plugins/markdown/html/normalize-html-headings.d.ts +1 -1
- package/dist/server/plugins/markdown/html/normalize-html-headings.js +1 -1
- package/dist/server/plugins/markdown/markdoc/functions/concat.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +5 -165
- package/dist/server/plugins/markdown/markdoc/markdoc-options.js +1 -1
- package/dist/server/plugins/markdown/markdoc/partials.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/headings.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/reparse-example-fences.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/reparse-example-fences.js +1 -1
- package/dist/server/plugins/markdown/runtime-transform.d.ts +2 -2
- package/dist/server/plugins/markdown/runtime-transform.js +1 -1
- package/dist/server/plugins/markdown/search/get-ai-search-documents.js +1 -1
- package/dist/server/plugins/markdown/search/nodes/section-node.d.ts +1 -1
- package/dist/server/plugins/markdown/search/search-resolver.js +1 -1
- package/dist/server/plugins/markdown/search/to-markdown.d.ts +1 -1
- package/dist/server/plugins/markdown/search/walk-sections.d.ts +1 -1
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/markdown/utils/stringify-tag-children-objects.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -3
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/list-graphql-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +4 -4
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/types.d.ts +2 -2
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.d.ts +0 -5
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/servers/mcp-server.js +2 -2
- package/dist/server/plugins/mcp/types.d.ts +10 -0
- package/dist/server/plugins/mcp/utils/available-tools.d.ts +5 -0
- package/dist/server/plugins/mcp/utils/available-tools.js +1 -0
- package/dist/server/plugins/mcp/workers/worker-context.d.ts +4 -0
- package/dist/server/plugins/mcp/workers/worker-context.js +1 -0
- package/dist/server/plugins/scorecard-classic/compute-scorecard.d.ts +2 -2
- package/dist/server/plugins/scorecard-classic/compute-scorecard.js +1 -1
- package/dist/server/plugins/scorecard-classic/index.js +1 -1
- package/dist/server/plugins/scorecard-classic/shared-utils.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/Grid/GridHeader.js +3 -3
- package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
- package/dist/server/plugins/search/engines/typesense/index.js +1 -1
- package/dist/server/store-config.d.ts +33 -0
- package/dist/server/store-config.js +1 -0
- package/dist/server/store.d.ts +14 -16
- package/dist/server/store.js +1 -1
- package/dist/server/tools/notifiers/formatter.js +3 -3
- package/dist/server/tools/notifiers/helpers/colors.d.ts +1 -1
- package/dist/server/tools/notifiers/logger.d.ts +4 -0
- package/dist/server/tools/notifiers/reporter.js +1 -1
- package/dist/server/types/plugins/api-routes.d.ts +4 -1
- package/dist/server/types/plugins/common.d.ts +2 -1
- package/dist/server/utils/codeframes/codeframes.d.ts +1 -1
- package/dist/server/utils/codeframes/yaml-ast.d.ts +1 -1
- package/dist/server/utils/decode-request-path.d.ts +2 -0
- package/dist/server/utils/decode-request-path.js +1 -0
- package/dist/server/utils/envs/env-boolean-string.d.ts +9 -3
- package/dist/server/utils/envs/get-api-route-allowed-env-variables.d.ts +2 -0
- package/dist/server/utils/envs/get-api-route-allowed-env-variables.js +1 -1
- package/dist/server/utils/envs/interpolate-env-variables.d.ts +5 -1
- package/dist/server/utils/envs/interpolate-env-variables.js +1 -1
- package/dist/server/utils/envs/load-env-variables.js +1 -1
- package/dist/server/utils/envs/replace-env-variables-deep.d.ts +17 -9
- package/dist/server/utils/envs/replace-env-variables-deep.js +1 -1
- package/dist/server/utils/errors.d.ts +3 -0
- package/dist/server/utils/errors.js +1 -1
- package/dist/server/utils/globs.d.ts +12 -0
- package/dist/server/utils/globs.js +1 -1
- package/dist/server/utils/llmstxt/resolve-llms-txt-md.js +1 -1
- package/dist/server/utils/rbac-expand.js +1 -1
- package/dist/server/utils/rbac.d.ts +5 -1
- package/dist/server/utils/rbac.js +1 -1
- package/dist/server/utils/report-all-errors.js +1 -1
- package/dist/server/web-server/auth.d.ts +2 -0
- package/dist/server/web-server/auth.js +2 -2
- package/dist/server/web-server/middleware/jsonValidatorMiddleware.d.ts +5 -325
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/catalog/helpers/create-entity-schema.d.ts +1756 -1756
- package/dist/server/web-server/routes/catalog/helpers/create-entity-update-schema.d.ts +295 -295
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/error.js +1 -1
- package/dist/server/web-server/routes/helpers/process-redirects.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.d.ts +2 -2
- package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.js +18 -18
- package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
- package/dist/server/web-server/utils/ssrf-safe-lookup.d.ts +2 -1
- package/dist/server/web-server/utils/ssrf-safe-lookup.js +1 -1
- package/dist/server/workers/mcp-tool-worker-methods.d.ts +7 -0
- package/dist/server/workers/mcp-tool-worker-methods.js +1 -0
- package/dist/server/workers/mcp-tool-worker-pool.d.ts +0 -1
- package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
- package/dist/server/workers/mcp-tool-worker.js +1 -1
- package/dist/server/workers/types.d.ts +4 -8
- package/dist/server/workers/worker-config.d.ts +33 -0
- package/dist/server/workers/worker-config.js +1 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/markdoc.d.ts +1 -1
- package/package.json +12 -12
- package/dist/server/plugins/markdown/html/html-jsx-attribute-mapping.d.ts +0 -6
- package/dist/server/plugins/markdown/html/html-jsx-attribute-mapping.js +0 -1
- package/dist/server/plugins/markdown/html/process-html-tokens.d.ts +0 -2
- package/dist/server/plugins/markdown/html/process-html-tokens.js +0 -1
- package/dist/server/plugins/markdown/source.d.ts +0 -4
- package/dist/server/plugins/markdown/source.js +0 -1
- package/dist/server/plugins/mcp/utils/available-sandbox-tools.d.ts +0 -4
- package/dist/server/plugins/mcp/utils/available-sandbox-tools.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/mask-email.d.ts +0 -25
- package/dist/server/tools/notifiers/helpers/privacy/mask-email.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/mask-subject.d.ts +0 -13
- package/dist/server/tools/notifiers/helpers/privacy/mask-subject.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii-from-url.d.ts +0 -25
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii-from-url.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii.d.ts +0 -36
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{secretStore as d}from"../gateway-mcp/secret-store.js";import{rejectCredential as _}from"../gateway-mcp/credential-validation.js";import{buildAllowedHostMatchers as
|
|
1
|
+
import{readRequestBody as C}from"@modelcontextprotocol/server";import{secretStore as d}from"../gateway-mcp/secret-store.js";import{rejectCredential as _}from"../gateway-mcp/credential-validation.js";import{buildAllowedHostMatchers as T}from"../gateway-mcp/fetch/allowed-hosts.js";import{assertUrlAllowed as A}from"../gateway-mcp/fetch/ssrf-guard.js";import{readCappedBody as R,getDefaultAgent as P}from"../gateway-mcp/fetch/fetch-bridge.js";import{logger as x}from"../../../tools/notifiers/logger.js";import{FORM_ACTIONS as k}from"./credentials-page/constants.js";import{credentialSchemesOf as w,schemeFieldName as f}from"./credentials-page/form-contract.js";import{formPage as O}from"./credentials-page/form-page.js";import{htmlDocument as N}from"./credentials-page/layout.js";import{declinedPage as I,expiredPage as j,outcomePage as D}from"./credentials-page/outcome-pages.js";const $={"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store","X-Frame-Options":"DENY","Referrer-Policy":"no-referrer","Content-Security-Policy":"default-src 'none'; style-src 'unsafe-inline'; img-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'"},M=3e4,B=64*1024,F=64*1024,U=/^bearer\s+/i,X=/^\d+$/,H=async(e,t,o)=>{const n=await t.getKv(),r=J(e,t.baseUrl,o);if(e.method==="GET"){const i=new URL(e.url).searchParams.get("token")??"",a=await d.peekElicitation(n,i);return a?E({kv:n,site:r,token:i,target:a},{},200):p(r)}if(e.method==="POST"){const i=await C(e,F);if(i.tooLarge)return new Response("Payload Too Large",{status:413});const a=await new Response(i.text,{headers:{"Content-Type":e.headers.get("content-type")??""}}).formData(),c=u(a,"token"),s=await d.peekElicitation(n,c);if(!s)return p(r);const l={kv:n,site:r,token:c,target:s,form:a};switch(u(a,"action")){case k.remove:return b(l,K(s,u(a,"scheme")));case k.removeAll:return b(l,w(s));case k.decline:return Y(l);default:return L(l)}}return new Response("Method Not Allowed",{status:405,headers:{Allow:"GET, POST"}})};async function L(e){const{target:t,form:o}=e,n=w(t),r=n.map((s,l)=>u(o,f("client_id",l)).trim()),i=s=>E(e,{error:s,clientIds:r},400),a=G(n,o);if("error"in a)return i(a.error);if(a.writes.length===0)return i(z(n));const c=[];for(const s of a.writes){if(s.kind!=="exchange"){c.push(s);continue}const l=await W(s.auth,s.clientId,s.clientSecret);if(!l.ok)return x.warn(`gateway oauth2 client_credentials exchange failed for ${t.api}: ${l.reason}`),i(y(n,s.schemeIndex,"client_id","We could not exchange those client credentials for a token. Check the client ID and secret, then try again."));c.push({kind:"set",scheme:s.scheme,secret:l.secret})}return v(e,c)}function G(e,t){const o=[];for(const[n,r]of e.entries()){const i=u(t,f("secret",n)).trim();if(i){const s=_(r.auth,i);if(s)return{error:y(e,n,"secret",s)};o.push({kind:"set",scheme:r.name,secret:Q(r.auth,i)});continue}if(r.auth.kind!=="oauth2ClientCredentials")continue;const a=u(t,f("client_id",n)).trim(),c=u(t,f("client_secret",n)).trim();if(a&&c)o.push({kind:"exchange",scheme:r.name,schemeIndex:n,auth:r.auth,clientId:a,clientSecret:c});else if(a||c)return{error:y(e,n,a?"client_secret":"client_id","Enter both the client ID and the client secret, or leave both blank.")}}return{writes:o}}function z(e){return e.length>1?{message:"Fill in at least one credential before saving."}:{message:e[0].auth.kind==="oauth2ClientCredentials"?"Enter an access token, or the client ID and the client secret, before saving.":"Enter a value before saving.",schemeIndex:0,field:"secret"}}function y(e,t,o,n){return{message:e.length>1?`${e[t].name}: ${n}`:n,schemeIndex:t,field:o}}async function b(e,t){const{kv:o,target:n}=e,r=await d.getStoredSchemes(o,n.subject,n.api),i=t.filter(a=>r[a.name]).map(a=>({kind:"remove",scheme:a.name}));return i.length===0?E(e,{error:{message:"No credential is stored there, so there is nothing to remove."}},400):v(e,i)}function K(e,t){const o=X.test(t)?w(e)[Number(t)]:void 0;return o?[o]:[]}async function Y({kv:e,site:t,token:o}){return await d.consumeElicitation(e,o)?h(t,I(),200):p(t)}async function v({kv:e,site:t,token:o},n){const r=await d.consumeElicitation(e,o);if(!r)return p(t);for(const c of n)c.kind==="remove"?await d.deleteSecret(e,r.subject,r.api,c.scheme):await d.setSecret(e,r.subject,r.api,c.scheme,c.secret);const i=await d.getStoredSchemes(e,r.subject,r.api),a={action:n.some(c=>c.kind==="set")?"saved":"removed",schemes:n.map(c=>c.scheme),stored:Object.keys(i).sort()};return h(t,D(r,a),200)}async function E({kv:e,site:t,token:o,target:n},r,i){const a=await d.getStoredSchemes(e,n.subject,n.api);return h(t,O({site:t,target:n,token:o,stored:a,...r}),i)}function J(e,t,o){const n=o?.props?.branding??{},r=t&&URL.canParse(t)?t:e.url;return{...n,host:new URL(r).host}}async function W(e,t,o){try{const n=T([{url:e.tokenUrl}]),r=A(e.tokenUrl,n),i=new AbortController,a=setTimeout(()=>i.abort(),M);let c;try{c=await fetch(r,{method:"POST",headers:{"content-type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:t,client_secret:o}),redirect:"manual",signal:i.signal,dispatcher:P()})}finally{clearTimeout(a)}if(!c.ok)return m(`token endpoint returned ${c.status}`);let s;try{s=await R(c,B)}catch{return m("token response exceeded the size cap")}let l;try{l=JSON.parse(s)}catch{return m("token response was not valid JSON")}const S=typeof l=="object"&&l!==null&&"access_token"in l?l.access_token:void 0,g=typeof S=="string"?S.trim():"";return g?_(e,g)?m("token response had an access_token that cannot be sent in a header"):{ok:!0,secret:{header:"Authorization",value:`Bearer ${g}`}}:m("token response had no access_token")}catch(n){return m(n instanceof Error?n.message:String(n))}}function m(e){return{ok:!1,reason:e}}function u(e,t){const o=e.get(t);return typeof o=="string"?o:""}function h(e,t,o){return new Response(N(t,e.colorScheme),{status:o,headers:$})}function p(e){return h(e,j(),404)}function Q(e,t){return e.kind==="apiKey"?{header:e.header,value:t}:e.kind==="cookie"?{header:"Cookie",value:`${e.name}=${t}`}:e.kind==="bearer"||e.kind==="oauth2ClientCredentials"?{header:"Authorization",value:V(t)}:{header:"Authorization",value:t}}function V(e){return`Bearer ${e.replace(U,"")}`}var de=H;export{de as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as C,MANAGE_API_CREDENTIALS_TOOL_NAME as k,SUBMIT_FEEDBACK_TOOL_NAME as S}from"../constants.js";import{isAnonymousSessionToolAvailable as U}from"../docs-mcp/tools/core/create-anonymous-session.js";import{isManageApiCredentialsToolAvailable as w,manageApiCredentials as y,manageApiCredentialsSchema as H}from"../codemode/tools/manage-credentials.js";import{EXECUTE_TOOL_SCHEMA as h,executeToolTitle as I}from"../codemode/tools/execute-schema.js";import{EXECUTE_TOOL_NAME as R,CODE_MODE_TOOL_NAMES as M,FETCH_TOOL_NAME as B}from"../codemode/constants.js";import{buildCodeModeInstructions as F,buildExecuteDescription as x}from"../codemode/prompts.js";import{toToolListEntries as z}from"../codemode/build-tool-list.js";import{composeExecuteAnnotations as X,getActiveCapabilities as Y}from"../codemode/capabilities/index.js";import{describeToolsSchema as j,describeTools as G}from"../codemode/tools/describe-tools.js";import{availableTools as g}from"../utils/available-tools.js";import{resolveDocsSiteUrl as K}from"../utils/docs-site-url.js";import{isToolDisabledByCaller as b}from"../utils/disabled-tools.js";import{toRegisterToolConfig as N}from"../utils/tool-registration.js";import{createMcpServer as P,createToolDispatch as W,extractSerializableContext as q}from"./mcp-server.js";const J=new Set([...M].filter(s=>s!==S));function D(s,t){const e=t.schema;if(s)return e;const{sessionHandle:u,...T}=e.properties;return{...e,properties:T}}function Q(s){return Object.fromEntries(s.map(t=>[t.name,t.schema]))}async function pe({name:s,tools:t,context:e,skills:u=[],getKv:T}){const l=q(e),n=e.mcpMode==="code",c=n?Y(e):[],O=c.some(o=>o.id===B),m=n?await g(t.filter(o=>!M.has(o.name)),l):[],_=z(m,c),E=U(e)&&!b(C,e.metadata),v=n&&w(e)&&!b(k,e.metadata),p=P(s,n?F(O,_):void 0),A={getClientCapabilities:()=>p.server.getClientCapabilities(),getKv:T},f=W(n?{...l,sandboxToolSchemas:Q(m)}:l,A);if(n){const o=X(m,c,e.config?.mcp),r=[{tool:{...h,title:I(o),description:x(O,_,K(e.config?.seo?.siteUrl,e.baseUrl)),schema:D(E,h),annotations:o},callback:f(R)},{tool:j(m,c),callback:G(m,c,e)}],i=t.find(a=>a.name===S);i&&!b(i.name,e.metadata)&&r.push({tool:i,callback:f(i.name)});const d=t.find(a=>a.name===C);if(d&&E&&r.push({tool:d,callback:f(d.name)}),v){const a=H(e);r.push({tool:{...a,schema:D(E,a)},callback:y(l,A)})}for(const{tool:a,callback:L}of r)p.registerTool(a.name,N(a),L)}else{const o=t.filter(i=>!J.has(i.name)),r=new Set((await g(o,l)).map(i=>i.name));for(const i of o){const d=p.registerTool(i.name,N({...i,outputSchema:void 0}),f(i.name));r.has(i.name)||d.disable()}}for(const o of u)p.registerResource(o.slug,o.uri,{title:o.name,description:o.description,mimeType:"text/markdown"},async()=>({contents:[{uri:o.uri,mimeType:"text/markdown",text:o.content}]}));return p}export{pe as createDocsMcpServer};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{McpServer as
|
|
1
|
+
import{McpServer as C}from"@modelcontextprotocol/server";import{logger as S}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as U,MCP_TOOL_WORKER_KEY as O}from"../../../workers/mcp-tool-worker-pool.js";import{secretStore as L}from"../gateway-mcp/secret-store.js";import{readAuthRequiredMeta as F,stripAuthRequiredMeta as k,upstreamAuthKey as b}from"../gateway-mcp/upstream-auth.js";import{acceptedCredentialsLink as D,buildCredentialsAcceptedHint as K,buildCredentialsToolHint as N,buildUpstreamCredentialFallback as q,buildUpstreamCredentialInputRequired as j,credentialElicitationAnswer as P,dedupeElicitation as v,isStatelessRequest as H,schemeLabelOf as $,supportsUrlElicitation as B}from"../gateway-mcp/elicitation.js";import{DEFAULT_SCHEME_NAME as y,resolveUpstreamApiAuth as W}from"../gateway-mcp/upstream-auth-scheme.js";import{MISSING_SESSION_HANDLE_MESSAGE as G,resolveSecretSubject as V}from"../gateway-mcp/subject.js";import{toWorkerContext as X}from"../workers/worker-context.js";const Y=6e4,J=1e4;function de(e,t){return new C({name:e,version:new Date().toISOString().slice(0,10)},{capabilities:{logging:{}},maxToolInputElements:J,...t?{instructions:t}:{}})}function me(e,t){return r=>async(n,s)=>{S.info(`MCP tool called: ${r}`);const i=e.elicitationEnabled??!1,u=H(s.mcpReq),a=i?V(e.user,n.sessionHandle):{kind:"anonymous"},o=a.kind==="resolved"?a.subject:void 0;if(a.kind==="invalid")return{content:[{type:"text",text:a.message}],isError:!0};const c=async()=>{if(!(!i||!o||!t?.getKv))try{const m=await t.getKv();return await L.getSecretsForSubject(m,o)}catch(m){S.warn(`gateway mcp secret store error, continuing unauthenticated: ${String(m)}`);return}};let l;const p=async()=>{l=await c();const m={toolName:r,args:n,context:X({...e,upstreamSecrets:l}),extra:re(s)};return await U.exec(O,[m],{timeout:Y})};let d=await p();const f=F(d);if(f.length>0&&i&&!o)return k(T(d,[{type:"text",text:G}]));if(f.length>0&&i&&o&&t?.getKv){S.info(`gateway mcp credentials prompt: era=${u?"2026-07-28":"2025"} clientElicitation=${Q(t)}`);const m=await t.getKv(),h=await Z(e,f),w=f.map(_=>x(_,h)),E=z(l),g=u?await ee(e,s,w,o,m,E,h,t):await te(e,w,o,m,E,h);switch(g.kind){case"inputRequired":return g.result;case"retry":d=await p();break;case"prependText":d=T(d,[{type:"text",text:g.text},...d.content]);break;case"none":break}}return k(d)}}function T(e,t){const{structuredContent:r,...n}=e;return{...n,content:t,isError:!0}}function Q(e){const t=e?.getClientCapabilities()?.elicitation;if(!t)return"none";const r=[t.form?"form":void 0,t.url?"url":void 0].filter(Boolean);return r.length>0?r.join("+"):"none"}async function Z(e,t){const r=new Map;for(const n of new Set(t.map(s=>s.api)))r.set(n,await W(e,n));return r}function x(e,t){const r=t.get(e.api);if(!r)return{...e,scheme:e.scheme??y};const n=e.scheme&&r.schemes[e.scheme]?e.scheme:r.defaultScheme;return{...e,scheme:n}}function z(e){const t=new Set;for(const[r,n]of Object.entries(e??{}))for(const s of Object.keys(n))t.add(b({api:r,scheme:s}));return t}function I(e,t){return e.status===401&&!t.has(b(e))}function R(e,t){const r=t.get(e.api),n=e.sentScheme??e.scheme;return r&&n?$(r.schemes,n):void 0}function M(e,t){return e.map(r=>N(r,R(r,t))).join(`
|
|
2
2
|
|
|
3
|
-
`)}function A(e,t,r,n,
|
|
3
|
+
`)}function A(e,t,r,n,s){const[i,...u]=t,a=s.get(i.api),o=i.scheme??a?.defaultScheme??y,c=i.schemes&&i.schemes.length>1?i.schemes:void 0,l=c?void 0:R(i,s);return{subject:r,baseUrl:e.baseUrl??"",target:{api:i.api,name:i.name,scheme:o,...l?{schemeLabel:l}:{},...c?{acceptedSchemes:c}:{}},auth:a?.schemes[o]??{kind:"raw"},...a?{apiAuth:a}:{},kv:n,hasExistingSecret:!1,reason:{kind:"authFailure",status:i.status,...i.detail?{detail:i.detail}:{},otherApiNames:u.map(p=>p.name)}}}async function ee(e,t,r,n,s,i,u,a){const o=P(t.mcpReq.inputResponses);if(o==="declined")return{kind:"none"};const c=r.filter(p=>I(p,i));if(c.length===0)return{kind:"prependText",text:M(r,u)};if(o==="accepted"){const p=await D(t.mcpReq.requestState(),{kv:s,subject:n,baseUrl:e.baseUrl??"",apis:c.map(f=>f.api)}),d=p?.apiName??c[0].name;return{kind:"prependText",text:K(d,p?.url)}}const l=A(e,c,n,s,u);return B(a?.getClientCapabilities())?{kind:"inputRequired",result:await j(l)}:{kind:"prependText",text:await q(l)}}async function te(e,t,r,n,s,i){const u=t.filter(c=>I(c,s));if(u.length===0)return{kind:"prependText",text:M(t,i)};const a=A(e,u,r,n,i);return{kind:"prependText",text:await v(`${r}:${b(u[0])}`,()=>q(a))}}function re(e){return{sessionId:e.sessionId,authInfo:e.http?.authInfo,requestId:e.mcpReq.id,_meta:e.mcpReq._meta}}function fe(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata,upstreamAuthorization:e.upstreamAuthorization,mcpMode:e.mcpMode,elicitationEnabled:e.elicitationEnabled,gatewayFetchBudgetPerExec:e.gatewayFetchBudgetPerExec,fetchCountRequest:e.fetchCountRequest,clientIp:e.clientIp,client:e.client,clientVersion:e.clientVersion,requestId:e.requestId,messageId:e.messageId,upstreamSecrets:e.upstreamSecrets,searchIgnoredRoutes:e.searchIgnoredRoutes,internalBaseUrl:e.internalBaseUrl,sandboxToolSchemas:e.sandboxToolSchemas,configFile:e.configFile,fs:void 0}}export{de as createMcpServer,me as createToolDispatch,fe as extractSerializableContext};
|
|
@@ -6,6 +6,7 @@ import type { McpToolSchema } from '../../types';
|
|
|
6
6
|
import type { Skill } from '../../types/plugins/skills.js';
|
|
7
7
|
import type { UpstreamSecrets } from './gateway-mcp/secret-store.js';
|
|
8
8
|
import type { SiteBranding } from './handlers/credentials-page/types.js';
|
|
9
|
+
import type { StoreConfigFile, WorkerConfig } from '../../workers/worker-config.js';
|
|
9
10
|
type ObjectValues<T> = T[keyof T];
|
|
10
11
|
export type McpServerType = ObjectValues<typeof McpServerType>;
|
|
11
12
|
export type McpErrorCodeTypes = ObjectValues<typeof McpErrorCodes>;
|
|
@@ -40,6 +41,7 @@ export type McpDocsStaticData = PageStaticData & {
|
|
|
40
41
|
tools?: McpToolSchema[];
|
|
41
42
|
skills?: Skill[];
|
|
42
43
|
skillsBaseUrl?: string;
|
|
44
|
+
configFile?: StoreConfigFile;
|
|
43
45
|
};
|
|
44
46
|
};
|
|
45
47
|
export type CredentialsPageStaticData = PageStaticData & {
|
|
@@ -117,6 +119,11 @@ export type McpToolContext = Omit<ApiFunctionsContext, 'telemetry' | 'getKv' | k
|
|
|
117
119
|
internalBaseUrl?: string;
|
|
118
120
|
sandboxToolSchemas?: Record<string, Record<string, unknown>>;
|
|
119
121
|
fs?: McpToolFileSystem;
|
|
122
|
+
configFile?: StoreConfigFile;
|
|
123
|
+
};
|
|
124
|
+
/** `McpToolContext` as it crosses to a worker. */
|
|
125
|
+
export type McpToolWorkerContext = Omit<McpToolContext, 'config' | 'fs' | 'configFile'> & {
|
|
126
|
+
config: WorkerConfig;
|
|
120
127
|
};
|
|
121
128
|
export type McpToolHandler<TArgs extends ToolArgs = ToolArgs> = (args: TArgs, context: McpToolContext, extra: McpToolExtra) => Promise<McpToolWorkerResponse | McpToolJsonValue>;
|
|
122
129
|
export type McpToolIsAvailable = (context: McpToolContext) => boolean | Promise<boolean>;
|
|
@@ -130,6 +137,9 @@ export type McpToolExecutionParams = {
|
|
|
130
137
|
context: McpToolContext;
|
|
131
138
|
extra: McpToolExtra;
|
|
132
139
|
};
|
|
140
|
+
export type McpToolWorkerParams = Omit<McpToolExecutionParams, 'context'> & {
|
|
141
|
+
context: McpToolWorkerContext;
|
|
142
|
+
};
|
|
133
143
|
export type CustomMcpToolsState = {
|
|
134
144
|
registeredToolNames: string[];
|
|
135
145
|
warnedNoOutputSchemaTools: Set<string>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpToolSchema } from '../../../types';
|
|
2
|
+
import type { McpToolContext } from '../types.js';
|
|
3
|
+
/** The candidates this request may use. Asks the worker pool only when a candidate is gated. */
|
|
4
|
+
export declare function availableTools(candidates: McpToolSchema[], context: McpToolContext): Promise<McpToolSchema[]>;
|
|
5
|
+
//# sourceMappingURL=available-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{logger as n}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as m,MCP_TOOL_AVAILABILITY_KEY as s}from"../../../workers/mcp-tool-worker-pool.js";import{toWorkerContext as f}from"../workers/worker-context.js";import{isToolDisabledByCaller as p}from"./disabled-tools.js";async function d(o,r){const a=o.filter(t=>!p(t.name,r.metadata)),e=a.filter(t=>t.hasAvailabilityGate).map(t=>t.name);if(e.length===0)return a;let i;try{i=await m.exec(s,[{toolNames:e,context:f(r)}],{timeout:1e4})}catch(t){return l(a,t instanceof Error?t.message:String(t))}return!i||typeof i!="object"?l(a,"the worker returned no availability map"):a.filter(t=>i[t.name]!==!1)}function l(o,r){const a=o.filter(e=>e.hasAvailabilityGate);return n.warn(`MCP tool availability is unknown (${r}); the tool list drops the gated tools: ${a.map(e=>e.name).join(", ")}.`),o.filter(e=>!e.hasAvailabilityGate)}export{d as availableTools};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpToolContext, McpToolWorkerContext } from '../types.js';
|
|
2
|
+
export declare function toWorkerContext({ config, configFile, fs: _fs, ...context }: McpToolContext): McpToolWorkerContext;
|
|
3
|
+
export declare function fromWorkerContext(context: McpToolWorkerContext): McpToolContext;
|
|
4
|
+
//# sourceMappingURL=worker-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readWorkerConfig as f,toWorkerConfig as t}from"../../../workers/worker-config.js";function g({config:o,configFile:r,fs:e,...n}){return{...n,config:t(o,r)}}function c(o){return{...o,config:f(o.config)}}export{c as fromWorkerContext,g as toWorkerContext};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { LifecycleContext, ProcessContentActions } from '../../types';
|
|
2
2
|
import type { DetailedScorecardData } from './types.js';
|
|
3
3
|
import { type ScorecardConfig, type RedoclyConfig } from '@redocly/theme/config';
|
|
4
|
-
export declare function computeScorecard({ actions, context, scorecardConfig,
|
|
4
|
+
export declare function computeScorecard({ actions, context, scorecardConfig, platformConfig, }: {
|
|
5
5
|
actions: ProcessContentActions;
|
|
6
6
|
context: LifecycleContext;
|
|
7
7
|
scorecardConfig: ScorecardConfig;
|
|
8
|
-
|
|
8
|
+
platformConfig: RedoclyConfig['platform'];
|
|
9
9
|
}): Promise<Record<string, DetailedScorecardData>>;
|
|
10
10
|
//# sourceMappingURL=compute-scorecard.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import w from"node:path";import S from"picomatch";import{removeLeadingSlash as O}from"@redocly/theme/core/utils";import{parsePathVersions as D}from"../../../utils/path/parse-path-versions.js";import{logger as c}from"../../tools/notifiers/logger.js";import{ScorecardStatus as d}from"./types.js";import{getTarget as M}from"./loaders/scorecard.js";const R=15;async function $({actions:t,context:i,scorecardConfig:e,
|
|
1
|
+
import w from"node:path";import S from"picomatch";import{removeLeadingSlash as O}from"@redocly/theme/core/utils";import{parsePathVersions as D}from"../../../utils/path/parse-path-versions.js";import{logger as c}from"../../tools/notifiers/logger.js";import{ScorecardStatus as d}from"./types.js";import{getTarget as M}from"./loaders/scorecard.js";const R=15;async function $({actions:t,context:i,scorecardConfig:e,platformConfig:o}){c.info("Computing scorecard...");const a=e.levels||[],n=a[0],u=await t.loadApiDocuments(i),r=B(u),h=e.ignore||[],v=S(h),m=new Set,f=c.startTiming(),p={},l={};for(const s of r){if(!L(s,v,m))continue;const g=s.customOutputRelativeFile||s.realRelativePath;m.add(g);const P=await N(s,i,e,a,n);p[s.realRelativePath]=P,l[P.relativePath]=P}return c.infoTime(f,"Scorecard processed"),T(p,o,e),l}function L(t,i,e){if(t.isVirtual||!t.definition)return!1;const o=t.customOutputRelativeFile||t.realRelativePath,a=O(t.realRelativePath);return i(a)?(c.info(`Skipping scorecard calculation for ignored file: ${t.realRelativePath}`),!1):!e.has(o)}function F(t,i,e){return t-1<i?d.BelowMinimum:i<e-1?d.Minimum:d.Highest}async function N(t,i,e,o,a){let n=a.name;if(e.targets?.length){const l=await i.getConfig(w.posix.dirname(t.realRelativePath)),s=t.definition.info?.["x-metadata"]||{},g={title:t.definition.info?.title,version:t.definition.info?.version,...s,...l.metadata};n=(await M(e.targets,g))?.minimumLevel||a.name}const{data:{levels:u,scorecardLevelIdx:r,scorecardLevel:h}}=await i.cache.load(t.realRelativePath,"scorecard"),v=o.findIndex(l=>l.name===n),m=F(r,v,o.length),f=t.customOutputRelativeFile||t.realRelativePath,p=D(f)?.versionName;return{levels:u,status:m,targetLevel:n,scorecardLevel:h,scorecardLevelIdx:r,relativePath:f,title:t.definition.info?.title,version:p}}function T(t,i,e){const o=Object.values(t).filter(r=>r.status===d.BelowMinimum);if(o.length===0)return;const a=o.map(r=>r.relativePath);let n=`Detected OpenAPI definitions with score below minimum level:
|
|
2
2
|
- ${a.slice(0,R).map(()=>"%rp").join(`
|
|
3
3
|
- `)}`;a.length>R&&(n+=`
|
|
4
4
|
... and ${a.length-R} more`),i?.ignoreLint??e.ignoreNonCompliant?c.warn(n,...a):c.error(n,...a)}function B(t){const i=[];for(const e of t){if(e.type!=="openapi")continue;const o=e.document;i.push({realRelativePath:e.realRelativePath,customOutputRelativeFile:e.customOutputRelativeFile,isVirtual:e.isVirtual,definition:{info:o.info}})}return i}export{$ as computeScorecard};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{writeFileSync as R}from"node:fs";import
|
|
1
|
+
import{writeFileSync as R}from"node:fs";import L from"path";import{SCORECARD_CLASSIC_FOLDER as A,SCORECARD_OUTPUT_FILE_NAME as w}from"../../constants/common.js";import{mapObject as E}from"../../../utils/object/map-object.js";import{envConfig as j}from"../../config/env-config.js";import{removeLeadingSlash as _}from"../../../utils/url/remove-leading-slash.js";import{combineUrls as O}from"@redocly/theme/core/utils";import{logger as F}from"../../tools/notifiers/logger.js";import{getRouteSlugToCatalogSlugMap as N}from"../../utils/catalog-classic/get-route-slug-to-catalog-slug-map.js";import{getCatalogSharedDataId as q}from"../../utils/catalog-classic/get-catalog-shared-data-id.js";import{deepEqual as I}from"../../../utils/object/deep-equal.js";import{ensureDir as U}from"../../utils/index.js";import{getTemplatePath as k}from"./get-template-path.js";import{getAllRuleNames as M}from"./lint.js";import{getScorecardConfig as P}from"./get-scorecard-config.js";import{getScorecardSlug as W}from"./shared-utils.js";import{scorecardConfigLoader as B}from"./loaders/scorecard-config.js";import{scorecardLoader as J}from"./loaders/scorecard.js";import{computeScorecard as $}from"./compute-scorecard.js";import{telemetryTraceStep as x}from"../../../cli/telemetry/helpers/trace-step.js";const G="scorecardClassic";let g={},D={};async function ue({id:T,requiredEntitlements:b,loadersPrefix:v=""}){let p=null,y=null,h=!1;return{id:T??"scorecardClassic",requiredEntitlements:b??["scorecard"],loaders:{[`${v}scorecard-config`]:B,[`${v}scorecard`]:J},async processContent(r,l){await x("com.redocly.build.plugin.scorecardClassic",async C=>{const a=r.createTemplate(G,k("./template/index.js")),u=await l.getConfig(),m=P(u),f=u?.platform??{},i=[()=>p===null,()=>!I(g,m),()=>!I(D,f)].some(e=>e());g=m,C?.setAttribute("config",JSON.stringify(g||{})),D=f;const n=u.catalogClassic??{},c=g.levels||[];if(c.length<1)throw Error("Invalid configuration of levels config");i&&(p=await $({actions:r,context:l,scorecardConfig:g,platformConfig:D}));const{data:{configs:o}}=await l.cache.load("",`${v}scorecard-config`),{perLevel:d,all:s}=M(o);y={levelNames:c.map(e=>e.name),rules:s,rulesPerLevel:d};for(const[e,t]of Object.entries(n)){const S=O(t.slug,"scorecard/");r.addRoute({duplicateInAllLocales:!0,slug:S,fsPath:O(t.slug,"scorecard/"),templateId:a,hasClientRoutes:!0,excludeFromSidebar:!0,serverPropsGetterIds:[],sharedData:[{id:"scorecard",key:"scorecard"},{key:"catalog",id:q(e)}],getNavText:()=>Promise.resolve(t.title||"API design scorecard"),getStaticData:async()=>({props:{catalogId:e,catalogConfig:{...t,items:void 0},scorecardConfig:g,scorecardInfo:y}})})}})},afterRoutesCreated:async(r,l)=>{const C=await l.getConfig(),a=C.catalogClassic??{},u=P(C);if(Object.keys(a).length){const i=Object.keys(a).length>1?await N(r,l,a):null,n={};for(const[c,o]of Object.entries(p||{})){const d=r.getRouteByFsPath(c),s=d?.slug;if(s){if(d&&!u.ignoreMetadata){const e=i?i.get(s)??Object.values(a)[0].slug:Object.values(a)[0].slug,t=O(e,"scorecard/");d.metadata={...d.metadata,scorecardStatus:o.status,scorecardLevel:o.scorecardLevel,scorecardLevelIdx:o.scorecardLevelIdx,scorecardLevels:E(o.levels,S=>({uniqueErrors:S.uniqueErrors,uniqueWarnings:S.uniqueWarnings})),scoreCardSlug:t+"apis/"+encodeURIComponent(_(s))}}if(n[s]={...o,levels:E(o.levels,e=>({...e,problems:e.problems.map(t=>({ruleId:t.ruleId,severity:t.severity}))}))},!h){const e=L.resolve(r.outdir,A,W(s));R(U(e),JSON.stringify(o))}}}await r.createSharedData("scorecard",n)}const m={};for(const[i,n]of Object.entries(p||{})){const c=r.getRouteByFsPath(i)?.slug;c&&(m[c]=n)}const f=j.REDOCLY_METADATA_OUTPUT_FOLDER;!h&&f&&(F.info("Writing scorecard data..."),R(L.join(f,w),JSON.stringify({scorecardData:m,...y}))),h=!0}}}export{ue as scorecardClassicPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
import{removeTrailingSlash as o}from"../../../utils/url/remove-trailing-slash.js";function s(r){const e={error:new Set,warn:new Set};for(const n of r)e[n.severity]?.add(n.ruleId);return{errors:e.error.size,warnings:e.warn.size}}function i(r){return r==="/"?"index.json":o(r).substring(1)+".json"}export{i as getScorecardSlug,s as getUniqueProblemsCount};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import r from"react";import t from"styled-components";import{flexRender as g}from"@tanstack/react-table";const w=({headerGroups:e,gridTemplateColumns:i,groupHeaderTitle:
|
|
1
|
+
import r from"react";import t from"styled-components";import{flexRender as g}from"@tanstack/react-table";const w=({headerGroups:e,gridTemplateColumns:i,groupHeaderTitle:d})=>r.createElement(p,null,d&&r.createElement(u,{gridTemplateColumns:i,role:"row"},r.createElement(c,{gridColumn:"1",role:"columnheader"}),r.createElement(c,{gridColumn:"2 / -1",role:"columnheader"},r.createElement("span",null,d))),e.map((a,m)=>r.createElement(b,{key:`header-group-${m}`,gridTemplateColumns:i,role:"row"},a.headers.map((o,s)=>{const l=g(o.column.columnDef.header,o.getContext()),n=o.column.getIsSorted();return r.createElement(x,{key:o.id,gridColumn:s+1,$sortable:o.column.getCanSort(),role:"columnheader","aria-sort":n==="asc"?"ascending":n==="desc"?"descending":void 0},o.column.getCanSort()?r.createElement(h,{type:"button",onClick:o.column.getToggleSortingHandler()},l,r.createElement(f,{"aria-hidden":"true"},n?n==="desc"?"\u25BE":"\u25B4":"\u21D5")):l)})))),p=t.div`
|
|
2
2
|
border: 1px solid var(--border-color-primary);
|
|
3
3
|
min-width: 775px;
|
|
4
4
|
`,u=t.div`
|
|
@@ -37,7 +37,7 @@ import r from"react";import t from"styled-components";import{flexRender as g}fro
|
|
|
37
37
|
&:first-child {
|
|
38
38
|
justify-content: flex-start;
|
|
39
39
|
}
|
|
40
|
-
`,
|
|
40
|
+
`,h=t.button`
|
|
41
41
|
display: block;
|
|
42
42
|
width: 100%;
|
|
43
43
|
height: 100%;
|
|
@@ -50,6 +50,6 @@ import r from"react";import t from"styled-components";import{flexRender as g}fro
|
|
|
50
50
|
color: inherit;
|
|
51
51
|
text-align: inherit;
|
|
52
52
|
cursor: pointer;
|
|
53
|
-
`,
|
|
53
|
+
`,f=t.span`
|
|
54
54
|
font-family: monospace;
|
|
55
55
|
`;export{w as GridHeader};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as e from"react";import{useCallback as H,useMemo as b,useState as G,useEffect as _}from"react";import{useLocation as T}from"react-router";import{Flex as U}from"@redocly/portal-legacy-ui";import{Button as x}from"@redocly/theme/components/Button/Button";import{AddIcon as I}from"@redocly/theme/icons/AddIcon/AddIcon";import{SubtractIcon as K}from"@redocly/theme/icons/SubtractIcon/SubtractIcon";import{ArrowLeftIcon as D}from"@redocly/theme/icons/ArrowLeftIcon/ArrowLeftIcon";import{getScorecardColorVariable as z,withoutPathPrefix as O}from"@redocly/theme/core/utils";import{Link as w}from"../../../../client/app/Link";import J from"../../../../client/app/CircularProgress";import{isDefined as R}from"../../../../utils/guards/is-defined.js";import{removeLeadingSlash as N}from"../../../../utils/url/remove-leading-slash.js";import{StatusByLevelWidget as Q}from"./StatusByLevelWidget";import{OTHER_TEAMS_LABEL as X,NON_CONFORMANT as Y}from"./utils";import{LevelIndicator as Z}from"./LevelIndicator";import{AppPageWrapper as V,CardValue as v,CardsWrapper as j,CatalogDescription as ee,ModeSwitcherTab as te,ModeSwitcherTabs as re,CardRow as B,ProblemsByStatusCardBody as W,ScoreCardStatusCardBody as F,TableWrap as ne,LevelComplianceCardTitle as le,ContentWithDotWrap as C,ScorecardCard as A,ScorecardCardTitle as L,LinkButton as ae}from"./index.styles";import{ApiLevel as M,InstanceStatus as k,LevelStatus as
|
|
1
|
+
import*as e from"react";import{useCallback as H,useMemo as b,useState as G,useEffect as _}from"react";import{useLocation as T}from"react-router";import{Flex as U}from"@redocly/portal-legacy-ui";import{Button as x}from"@redocly/theme/components/Button/Button";import{AddIcon as I}from"@redocly/theme/icons/AddIcon/AddIcon";import{SubtractIcon as K}from"@redocly/theme/icons/SubtractIcon/SubtractIcon";import{ArrowLeftIcon as D}from"@redocly/theme/icons/ArrowLeftIcon/ArrowLeftIcon";import{getScorecardColorVariable as z,withoutPathPrefix as O}from"@redocly/theme/core/utils";import{Link as w}from"../../../../client/app/Link";import J from"../../../../client/app/CircularProgress";import{isDefined as R}from"../../../../utils/guards/is-defined.js";import{removeLeadingSlash as N}from"../../../../utils/url/remove-leading-slash.js";import{StatusByLevelWidget as Q}from"./StatusByLevelWidget";import{OTHER_TEAMS_LABEL as X,NON_CONFORMANT as Y}from"./utils";import{LevelIndicator as Z}from"./LevelIndicator";import{AppPageWrapper as V,CardValue as v,CardsWrapper as j,CatalogDescription as ee,ModeSwitcherTab as te,ModeSwitcherTabs as re,CardRow as B,ProblemsByStatusCardBody as W,ScoreCardStatusCardBody as F,TableWrap as ne,LevelComplianceCardTitle as le,ContentWithDotWrap as C,ScorecardCard as A,ScorecardCardTitle as L,LinkButton as ae}from"./index.styles";import{ApiLevel as M,InstanceStatus as k,LevelStatus as q,RuleStatus as $}from"./components";import{Grid as S}from"./Grid/Grid";import{useDetailedScorecard as se}from"./useDetailedScorecard";import{Gauge as ce,GaugeValue as oe}from"./Gauge";function Ie(p){const u=T(),{data:d,levelNames:i,hasPublishedAt:n,hasTeam:s,teamLabel:l}=p,f=H((a,o,E)=>{const g=a.getValue(E)?new Date(a.getValue(E)).getTime():0,t=o.getValue(E)?new Date(o.getValue(E)).getTime():0;return g>t?1:-1},[]),m=b(()=>[{id:"title",header:"API",accessorKey:"api.title",size:200,cell:({getValue:a,row:o})=>e.createElement(w,{to:O(u.pathname)+"/apis/"+encodeURIComponent(N(o.original.api.link))},a())},n?{header:"Published at",accessorKey:"api.publishedAt",sortingFn:f,cell:({getValue:a})=>{const o=a();return o?new Date(o).toLocaleDateString():"-"}}:void 0,s?{header:l,accessorKey:"api.team"}:void 0,{id:"level",header:"Level",accessorKey:"scorecard.scorecardLevel",cell:({getValue:a,row:o})=>e.createElement(M,{level:a(),colorVariable:z(o.original?.scorecard.scorecardLevelIdx,i.length+1)})},...i.map(a=>({id:a,header:`${a}`,accessorKey:"scorecard.levels",cell:({getValue:o,row:E})=>{const g=o(),t=E.original.api.link;return g?.[a]?e.createElement(Z,{key:t,uniqueErrors:g[a].uniqueErrors,uniqueWarnings:g[a].uniqueWarnings,id:t}):null}}))].filter(R),[f,i,u.pathname,n,s,l]);return e.createElement(S,{columns:m,data:d,sortBy:[{id:"title",desc:!1}]})}function Ke(p){const u=T(),{data:d}=p,i=b(()=>[{header:"Rules",accessorKey:"ruleId",cell:({getValue:n})=>e.createElement(w,{to:O(u.pathname)+"/rules/"+encodeURIComponent(n())},n())},{id:"status",header:"Status",accessorKey:"status",size:200,cell:({row:n})=>e.createElement($,{errors:n.original.errorApisCount,warnings:n.original.warningApisCount})},{header:"Problem APIs",size:200,accessorKey:"apis",cell:({getValue:n})=>n().length,sortDescFirst:!0},{header:"Problem count",size:200,accessorKey:"count",sortDescFirst:!0}],[u.pathname]);return e.createElement(S,{columns:i,data:d,sortBy:[{id:"status",desc:!0}]})}function De(p){const{data:u,levelNames:d,filters:i,setActiveTab:n,teamLabel:s,teamProperty:l}=p,f=b(()=>[{id:"team",header:`API ${s}`,accessorKey:"team",size:200,cell:({getValue:m})=>e.createElement(ae,{onClick:()=>{n("apis"),i.find(a=>a.property===l)?.selectOption(m())}},m())},...[Y,...d].map(m=>({id:m,header:`${m}`,accessorFn:a=>a.levels[m]?.apis}))],[i,d,n,s,l]);return e.createElement(S,{columns:f,data:u,sortBy:[{id:"team",desc:!1}],groupHeaderTitle:"APIs by level"})}function ie(p){const{data:u,title:d}=p,i=b(()=>[{id:"expand",maxSize:40,size:40,header:()=>null,enableSorting:!1,cell:({row:n})=>n.getCanExpand()?e.createElement(x,{onClick:n.getToggleExpandedHandler(),variant:"text",size:"medium",icon:n.getIsExpanded()?e.createElement(K,null):e.createElement(I,null)}):null},{header:"Rules",accessorKey:"ruleId",cell:({getValue:n,row:s})=>s.getCanExpand()?e.createElement("span",{onClick:s.getToggleExpandedHandler()},n()):null},{header:"Status",accessorKey:"status",size:200,cell:({getValue:n})=>{const s=n();return e.createElement($,{errors:s?.errorsCount,warnings:s?.warningsCount})},enableSorting:!1},{header:"Problem count",accessorKey:"problemsCount",size:200,sortDescFirst:!0}],[]);return e.createElement(S,{columns:i,data:u,sortBy:[{id:"ruleId",desc:!1}],empty:e.createElement(e.Fragment,null,"\u2705 This API is compliant with ",e.createElement("strong",null,d)," level rules"),subRowKey:"problems"})}function ze(p){const{catalogSlug:u,slug:d,data:i,hasTeam:n,hasPublishedAt:s,teamLabel:l}=p,{apis:f,apisCount:m,warningApisCount:a,errorApisCount:o,levels:E,count:g}=i,t=f.length===0,h=t?void 0:{id:"expand",maxSize:40,size:40,header:()=>null,enableSorting:!1,cell:({row:r})=>r.getCanExpand()?e.createElement(x,{onClick:r.getToggleExpandedHandler(),variant:"text",size:"medium",icon:r.getIsExpanded()?e.createElement(K,null):e.createElement(I,null)}):null},P=b(()=>[h,{header:"API",accessorKey:"title"},s?{header:"Published at",accessorKey:"publishedAt",cell:({getValue:r})=>{const c=r();return c?new Date(c).toLocaleDateString():"-"}}:void 0,n?{header:l,accessorKey:"team",cell:({getValue:r})=>r()||X}:void 0,{header:"Problem count",size:200,accessorKey:"count",cell:({getValue:r})=>r()||0,sortDescFirst:!0}].filter(R),[n,s,l,t]),y=b(()=>Object.entries(i.teams).sort((r,c)=>c[1]-r[1]),[i.teams]);return e.createElement(V,null,e.createElement(x,{icon:e.createElement(D,null),iconPosition:"left",variant:"ghost",size:"large",to:`${u}scorecard`},"Back to dashboard"),e.createElement("h1",null,"Rule ",d),e.createElement(j,null,e.createElement(A,null,e.createElement(L,null,"Rule status"),e.createElement(F,null,e.createElement("div",null,e.createElement(v,null,m),e.createElement("br",null),"APIs"),e.createElement("div",null,e.createElement(C,null,e.createElement(v,{style:{textAlign:"right"}},m-a-o),e.createElement(k,{severity:"Pass"})),e.createElement(C,null,e.createElement(v,{style:{textAlign:"right"}},a),e.createElement(k,{severity:"Warn"})),e.createElement(C,null,e.createElement(v,{style:{textAlign:"right"}},o),e.createElement(k,{severity:"Error"}))))),e.createElement(A,null,e.createElement(L,null,"Problems by level"),e.createElement(W,null,Object.entries(E).map(([r,c])=>e.createElement(B,{key:r},e.createElement("span",null,r),e.createElement(ce,{chunks:[{share:c.errors/g*100,colorVariable:"--scorecard-color-error"},{share:c.warnings/g*100,colorVariable:"--scorecard-color-warning"}]}),e.createElement(oe,null,c.errors+c.warnings))))),e.createElement(A,null,e.createElement(L,null,`Problems by ${l}`),e.createElement(W,null,y.slice(0,4).map(([r,c])=>e.createElement(B,{key:r},e.createElement("span",{style:{flex:1,textAlign:"left"}},r),e.createElement(v,null,c)))))),e.createElement(S,{columns:P,data:f,sortBy:[{id:"title",desc:!1}],subRowKey:"problems",slug:d}))}function Oe(p){const{slug:u,api:d,teamLabel:i,catalogSlug:n}=p,{api:s}=d||{},{scorecard:l,isLoading:f}=se(u),m=l?.levels||{},[a,o]=G(Object.keys(m)[0]),E=b(()=>s?.publishedAt instanceof Date?s?.publishedAt.toLocaleDateString():s?.publishedAt,[s]);_(()=>{if(l){const t=l.levels||{};o(Object.keys(t)[0])}},[l]);const g=b(()=>{if(!l?.levels)return{};const t={};for(const h of Object.keys(l.levels)){const P=l.levels[h].problems.reduce((y,r)=>(y[r.ruleId]||(y[r.ruleId]=[]),y[r.ruleId].push(r),y),{});t[h]=Object.entries(P).map(([y,r])=>({ruleId:y,problems:[...r.filter(c=>c.severity==="error"),...r.filter(c=>c.severity==="warn")],problemsCount:r.length,status:{errorsCount:r.filter(c=>c.severity==="error").length,warningsCount:r.filter(c=>c.severity==="warn").length}}))}return t},[l?.levels]);return f?e.createElement(U,{justifyContent:"center",mt:"2em"},e.createElement(J,null)):l?e.createElement(V,null,e.createElement(x,{icon:e.createElement(D,null),iconPosition:"left",variant:"ghost",size:"large",to:`${n}scorecard`},"Back to dashboard"),e.createElement("h1",null,s?.title||u),e.createElement(ee,null,E&&e.createElement(e.Fragment,null,"Published at: ",E,e.createElement("br",null)),e.createElement(w,{to:u,external:!0},"Documentation")),e.createElement(j,null,e.createElement(A,null,e.createElement(le,null,e.createElement("span",null,"Scorecard level"),e.createElement(M,{level:l.scorecardLevel,colorVariable:z(l.scorecardLevelIdx,Object.keys(m).length)})),e.createElement(F,null,e.createElement("div",null,"Compliance by level"),e.createElement("div",null,Object.entries(l.levels).map(([t,h])=>e.createElement(C,{key:t},e.createElement(v,{style:{width:"100px",textAlign:"right"}},t),e.createElement(q,{errors:h.errors,warnings:h.warnings})))))),e.createElement(Q,{title:"Rules compliance",levels:Object.entries(l.levels).map(([t,h])=>({errors:h.uniqueErrors,warnings:h.uniqueWarnings,total:p.rulesPerLevel[t].length,name:t}))}),e.createElement(A,null,e.createElement(L,null,i),e.createElement(v,{style:{fontWeight:"normal"}},s?.team))),e.createElement(re,{style:{justifyContent:"flex-start"},"data-component-name":"Scorecard/ModeSwitcherTabs"},Object.keys(l.levels).map(t=>e.createElement(te,{"data-component-name":"Scorecard/ModeSwitcherTab",key:t,isActive:a===t,onClick:()=>o(t)},e.createElement(C,null,e.createElement("span",null,t)," ",e.createElement(q,{errors:l.levels[t].errors,warnings:l.levels[t].warnings}))))),Object.keys(m).map(t=>e.createElement(ne,{key:t,isActive:a===t},e.createElement(ie,{title:t,data:g[t]})))):e.createElement("div",null,"Scorecard not found")}export{Ie as ApiListView,Oe as ApiPage,ie as ApiView,ze as RuleView,Ke as RulesView,De as TeamsView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{appendFile as T}from"node:fs/promises";import{existsSync as P}from"node:fs";import b from"node:path";import{Client as q}from"typesense";import{SEARCH_GROUP_FACET_FIELD as F,SEARCH_PRODUCT_FIELD as L,SEARCH_RBAC_FIELD as d,SEARCH_VERSION_FIELD as h}from"../../../../../constants/common.js";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as v,HIGHLIGHTED_TEXT_MAX_LENGTH as C,SEARCH_DATA_EXPORT_FOLDER as R,SEARCH_DOCUMENT_METADATA_KEY as j,SEARCH_GROUP_LIMIT as O,SEARCH_MAX_FACET_VALUES as y,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as k}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as N}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as _}from"../../../../config/env-config.js";import{logger as I}from"../../../../tools/notifiers/logger.js";import{ensureDir as E}from"../../../../utils/index.js";class X{#e=null;#i="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"deprecated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:"parameters.name",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.description",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.place",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.path",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:L,type:"string",facet:!0,optional:!0},{name:h,type:"object",facet:!0,optional:!0},{name:d,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#r={ORGANIZATION_ID:_.ORGANIZATION_ID??"",PROJECT_ID:_.PROJECT_ID??"",TYPESENSE_API_URL:_.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:_.TYPESENSE_API_KEY??""};constructor(){if(!_.isBuildMode){for(const[e,t]of Object.entries(this.#r))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#i=`${this.#r.ORGANIZATION_ID}_${this.#r.PROJECT_ID}_`,this.#e=new q({nodes:[{url:this.#r.TYPESENSE_API_URL}],apiKey:this.#r.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#b(e)}async addDocuments(e,t){const{locale:s,outDir:a}=t,n=e.map(r=>{const i={...r},c=r[j];return c&&(c.curated&&(i.metadata_curated=c.curated),c.excludes&&(i.metadata_keywords_excludes=c.excludes),c.includes&&(i.metadata_keywords_includes=c.includes)),i}),o=this.#s.get(s)??[];this.#s.set(s,o.concat(n)),o.length+e.length>=k&&await this.exportDocuments(a)}async search(e,t){return await N("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:a,locale:n,filter:o,loadMore:r}=e,i=this.#f(n),c={collection:i,q:a||"*",query_by:this.#h(),max_facet_values:y};if(s?.setAttribute("collectionName",i),s?.setAttribute("locale",n),this.#e)if(r){const{groupKey:l,offset:u}=r,f={offset:u,filter_by:this.#n(t,o),facet_by:"*",per_page:O};return s?.setAttribute("isLoadMore",!0),s?.setAttribute("filter",f.filter_by),this.#d(await this.#e.collections(i).documents().search({...c,...f}),l)}else{const l=this.#n(t,o);s?.setAttribute("filter",l);const u=await this.#e.multiSearch.perform({searches:this.#F(t,o)},c),f=this.#c(u,this.#o());f&&I.warn("Search facet requests failed: %s",f);const p=this.#y(u),m=(p[F]??[]).map(A=>A.value);s?.setAttribute("groups",m.join(",")),m.length===y&&I.warn("Search category facet list reached the limit of %s; results for some categories may be missing",y);const D=[...new Set(this.#m(o))].slice(0,y),g=D.length?D:m;if(!g.length)return{facets:p,documents:{},groupCounts:{}};const S=await this.#e.multiSearch.perform({searches:g.map(A=>({filter_by:`${l} && (${F}:=${this.#a(A)})`,per_page:O}))},c),$=this.#c(S,g);return $&&I.warn("Search category requests failed: %s",$),this.#_(S,g,p,o)}else return{facets:{},documents:{}}})}#d(e,t){const s={facets:{},documents:{[t]:[]},groupCounts:typeof e.found=="number"?{[t]:e.found}:{}};if(e.hits&&e.hits.length)for(const a of e.hits)s.documents[t].push({document:this.#l(a),highlight:this.#u(a)});return s}#y(e){const t={};if("results"in e){for(const s of e.results)if(s.facet_counts&&s.facet_counts.length)for(const a of s.facet_counts)t[a.field_name]=a.counts.map(n=>({value:n.value,count:n.count}))}return t}#c(e,t){return"results"in e?e.results.map((s,a)=>({result:s,label:t[a]})).filter(({result:s})=>"error"in s).map(({result:s,label:a})=>`${a}: ${s.error}`).join("; "):""}#_(e,t,s,a){const n={},o={facets:s,documents:{},groupCounts:n};for(const r of this.#m(a))o.documents[r]=[];return"results"in e&&e.results.forEach((r,i)=>{const c=t[i];typeof r.found=="number"&&(n[c]=r.found);const l=r.hits??[];l.length&&(o.documents[c]=l.map(u=>({document:this.#l(u),highlight:this.#u(u)})))}),o}#l(e){return this.#g(e)}#u(e){const t={},s=[];for(const[a,n]of Object.entries(e.highlight??{}))if(Array.isArray(n)){if(a==="path"){const o=n,r=[];for(const i of o)r.push(i.snippet);t.path=r}else if(a==="parameters"){const o=n;for(const r of o){let i=!1;for(const[c,l]of Object.entries(r))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(i=!0);else l.matched_tokens?.length&&(i=!0);if(i){const c={name:r.name?.snippet||"",description:r.description?.snippet||"",place:r.place?.snippet||"",path:r.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[a]=n.snippet,s.push(a);for(const[a,n]of Object.entries(e.document))!s.includes(a)&&typeof n=="string"&&(t[a]=n.length>C?`${n.substring(0,C)}...`:n);return t.parameters||(t.parameters=[]),t}#g(e){let t;const s=Object.keys(e.highlight??{});for(const n of v)if(s.some(o=>o===n))return e.document;const a=e.highlight?.parameters;if(a){for(const n of a)for(const[o,r]of Object.entries(n))if(o!=="deepLink"){if(Array.isArray(r)){for(const i of r)if(i.matched_tokens?.length){t=n.deepLink?.snippet??t;break}}else if(r.matched_tokens?.length){t=n.deepLink?.snippet??t;break}}}if(t){const n=t.split("#")[1];return{...e.document,url:`${e.document.url}#${n}`}}return e.document}async exportDocuments(e){const t='{"documents":[',s=E(b.join(e,R));for(const[a,n]of this.#s){if(n.length===0)continue;const o=E(b.join(s,`${a}.json`)),r=!P(o),i=JSON.stringify(n).substring(1).slice(0,-1),c=r?t+i:","+i;await T(o,c,{encoding:"utf8"}),this.#s.set(a,[])}}async exportIndexes(e){const t=E(b.join(e,R));for(const s of this.#s.keys()){const a=E(b.join(t,`${s}.json`)),n=`],"schemaFields":${JSON.stringify(this.#t)}}`;await T(a,n,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await N("com.redocly.search.facets",async s=>{s?.setAttribute("id","searchFacetsId"),s?.setAttribute("object","searchFacets"),s?.setAttribute("uri","urn:redocly:realm:api:searchFacets:searchFacetsId");const{locale:a,query:n,facetQuery:o,filter:r,field:i}=e,c=this.#f(a),l={q:n||"*",query_by:this.#h(),facet_by:"*",facet_query:this.#A(o,i),filter_by:this.#n(t,r,i),max_facet_values:y};if(s?.setAttribute("collectionName",c),s?.setAttribute("query",l.q),s?.setAttribute("facetQuery",l.facet_query),s?.setAttribute("filter",l.filter_by),this.#e){const u={},f=await this.#e.collections(c).documents().search(l);if(f.facet_counts&&f.facet_counts.length)for(const p of f.facet_counts)u[p.field_name]=p.counts.map(m=>({value:m.value,count:m.count,isCounterVisible:!!n||(r?.length||0)>0}));return u}else return{}})}#f(e){return`${this.#i}${e}`}#b(e){for(const[t,{queryable:s}]of e)this.#t.find(a=>a.name===t)||this.#t.push({queryable:s,name:t,type:"string",facet:!0,optional:!0})}#h(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#a(e){return`\`${e.replaceAll("`","")}\``}#n(e,t,s){const a=e.teams.filter(r=>!r.includes("`")&&!r.includes("*")).map(r=>this.#a(r)),n=a.length?`${d}:=[${a.join(", ")}]`:`${d}:=[\`anonymous\`] && ${d}:!=[\`anonymous\`]`,o=(t??[]).filter(r=>r.field!==s&&r.field!==h&&r.values.length&&this.#p(r.field)).map(r=>{const i=r.values.map(c=>this.#a(c));return`${r.field}:=[${i.join(", ")}]`});return[n,...o,this.#E(t)].map(r=>`(${r})`).join(" && ")}#p(e){return this.#o().includes(e)}#o(){return this.#t.filter(e=>e.facet&&e.name!==d&&e.name===e.name.trim()).map(e=>e.name)}#E(e){const t=e?.find(r=>r.field===h);if(t?.values.length!==2)return`${h}.isDefault:true`;const[s,a]=t.values.map(r=>this.#a(r)),n=`(${h}.folderId:! ${s} && ${h}.isDefault:true)`,o=`(${h}.folderId: ${s} && ${h}.version:=${a})`;return`${n} || ${o}`}#A(e,t){return e&&t&&this.#p(t)?`${t}:${e}`:""}#m(e){const t=[];if(e&&e.length)for(const s of e)s.field===F&&t.push(...s.values);return t}#F(e,t){const s=[];for(const a of this.#o()){const n={facet_by:a,filter_by:this.#n(e,t,a)};s.push(n)}return s}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(s=>{s.values=[]}),e.setSearchFacets(t)}}export{X as Typesense};
|
|
1
|
+
import{appendFile as T}from"node:fs/promises";import{existsSync as P}from"node:fs";import b from"node:path";import{Client as q}from"typesense";import{SEARCH_GROUP_FACET_FIELD as F,SEARCH_PRODUCT_FIELD as L,SEARCH_RBAC_FIELD as d,SEARCH_VERSION_FIELD as h}from"../../../../../constants/common.js";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as v,HIGHLIGHTED_TEXT_MAX_LENGTH as C,SEARCH_DATA_EXPORT_FOLDER as R,SEARCH_DOCUMENT_METADATA_KEY as j,SEARCH_GROUP_LIMIT as O,SEARCH_MAX_FACET_VALUES as y,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as k}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as N}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as _}from"../../../../config/env-config.js";import{logger as I}from"../../../../tools/notifiers/logger.js";import{ensureDir as E}from"../../../../utils/index.js";class X{#e=null;#i="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"deprecated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:"parameters.name",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.description",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.place",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.path",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:L,type:"string",facet:!0,optional:!0},{name:h,type:"object",facet:!0,optional:!0},{name:d,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#r={ORGANIZATION_ID:_.ORGANIZATION_ID??"",PROJECT_ID:_.PROJECT_ID??"",TYPESENSE_API_URL:_.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:_.TYPESENSE_API_KEY??""};constructor(){if(!_.isBuildMode){for(const[e,t]of Object.entries(this.#r))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#i=`${this.#r.ORGANIZATION_ID}_${this.#r.PROJECT_ID}_`,this.#e=new q({nodes:[{url:this.#r.TYPESENSE_API_URL}],apiKey:this.#r.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#b(e)}async addDocuments(e,t){const{locale:s,outDir:a}=t,n=e.map(r=>{const i={...r},c=r[j];return c&&(c.curated&&(i.metadata_curated=c.curated),c.excludes&&(i.metadata_keywords_excludes=c.excludes),c.includes&&(i.metadata_keywords_includes=c.includes)),i}),o=this.#s.get(s)??[];this.#s.set(s,o.concat(n)),o.length+e.length>=k&&await this.exportDocuments(a)}async search(e,t){return await N("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:a,locale:n,filter:o,loadMore:r}=e,i=this.#f(n),c={collection:i,q:a||"*",query_by:this.#h(),max_facet_values:y};if(s?.setAttribute("collectionName",i),s?.setAttribute("locale",n),this.#e)if(r){const{groupKey:l,offset:u}=r,f={offset:u,filter_by:this.#n(t,o),facet_by:"*",per_page:O};return s?.setAttribute("isLoadMore",!0),s?.setAttribute("filter",f.filter_by),this.#d(await this.#e.collections(i).documents().search({...c,...f}),l)}else{const l=this.#n(t,o);s?.setAttribute("filter",l);const u=await this.#e.multiSearch.perform({searches:this.#F(t,o)},c),f=this.#c(u,this.#o());f&&I.warn("Search facet requests failed: %s",f);const p=this.#y(u),m=(p[F]??[]).map(A=>A.value);s?.setAttribute("groups",m.join(",")),m.length===y&&I.warn("Search category facet list reached the limit of %s; results for some categories may be missing",y);const D=[...new Set(this.#m(o))].slice(0,y),g=D.length?D:m;if(!g.length)return{facets:p,documents:{},groupCounts:{}};const S=await this.#e.multiSearch.perform({searches:g.map(A=>({filter_by:`${l} && (${F}:=${this.#a(A)})`,per_page:O}))},c),$=this.#c(S,g);return $&&I.warn("Search category requests failed: %s",$),this.#_(S,g,p,o)}else return{facets:{},documents:{}}})}#d(e,t){const s={facets:{},documents:{[t]:[]},groupCounts:typeof e.found=="number"?{[t]:e.found}:{}};if(e.hits&&e.hits.length)for(const a of e.hits)s.documents[t].push({document:this.#l(a),highlight:this.#u(a)});return s}#y(e){const t={};if("results"in e){for(const s of e.results)if(s.facet_counts&&s.facet_counts.length)for(const a of s.facet_counts)t[a.field_name]=a.counts.map(n=>({value:n.value,count:n.count}))}return t}#c(e,t){return"results"in e?e.results.map((s,a)=>({result:s,label:t[a]})).filter(({result:s})=>"error"in s).map(({result:s,label:a})=>`${a}: ${s.error}`).join("; "):""}#_(e,t,s,a){const n={},o={facets:s,documents:{},groupCounts:n};for(const r of this.#m(a))o.documents[r]=[];return"results"in e&&e.results.forEach((r,i)=>{const c=t[i];typeof r.found=="number"&&(n[c]=r.found);const l=r.hits??[];l.length&&(o.documents[c]=l.map(u=>({document:this.#l(u),highlight:this.#u(u)})))}),o}#l(e){return this.#g(e)}#u(e){const t={},s=[];for(const[a,n]of Object.entries(e.highlight??{}))if(Array.isArray(n)){if(a==="path"){const o=n,r=[];for(const i of o)r.push(i.snippet);t.path=r}else if(a==="parameters"){const o=n;for(const r of o){let i=!1;for(const[c,l]of Object.entries(r))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(i=!0);else l.matched_tokens?.length&&(i=!0);if(i){const c={name:r.name?.snippet||"",description:r.description?.snippet||"",place:r.place?.snippet||"",path:r.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[a]=n.snippet,s.push(a);for(const[a,n]of Object.entries(e.document))!s.includes(a)&&typeof n=="string"&&(t[a]=n.length>C?`${n.substring(0,C)}...`:n);return t.parameters||(t.parameters=[]),t}#g(e){let t;const s=Object.keys(e.highlight??{});for(const n of v)if(s.some(o=>o===n))return e.document;const a=e.highlight?.parameters;if(a){for(const n of a)for(const[o,r]of Object.entries(n))if(o!=="deepLink"){if(Array.isArray(r)){for(const i of r)if(i.matched_tokens?.length){t=n.deepLink?.snippet??t;break}}else if(r.matched_tokens?.length){t=n.deepLink?.snippet??t;break}}}if(t){const n=t.split("#")[1];return{...e.document,url:`${e.document.url}#${n}`}}return e.document}async exportDocuments(e){const t='{"documents":[',s=E(b.join(e,R));for(const[a,n]of this.#s){if(n.length===0)continue;const o=E(b.join(s,`${a}.json`)),r=!P(o),i=JSON.stringify(n).substring(1).slice(0,-1),c=r?t+i:","+i;await T(o,c,{encoding:"utf8"}),this.#s.set(a,[])}}async exportIndexes(e){const t=E(b.join(e,R));for(const s of this.#s.keys()){const a=E(b.join(t,`${s}.json`)),n=`],"schemaFields":${JSON.stringify(this.#t)}}`;await T(a,n,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await N("com.redocly.search.facets",async s=>{s?.setAttribute("id","searchFacetsId"),s?.setAttribute("object","searchFacets"),s?.setAttribute("uri","urn:redocly:realm:api:searchFacets:searchFacetsId");const{locale:a,query:n,facetQuery:o,filter:r,field:i}=e,c=this.#f(a),l={q:n||"*",query_by:this.#h(),facet_by:"*",facet_query:this.#A(o,i),filter_by:this.#n(t,r,i),max_facet_values:y,per_page:0};if(s?.setAttribute("collectionName",c),s?.setAttribute("query",l.q),s?.setAttribute("facetQuery",l.facet_query),s?.setAttribute("filter",l.filter_by),this.#e){const u={},f=await this.#e.collections(c).documents().search(l);if(f.facet_counts&&f.facet_counts.length)for(const p of f.facet_counts)u[p.field_name]=p.counts.map(m=>({value:m.value,count:m.count,isCounterVisible:!!n||(r?.length||0)>0}));return u}else return{}})}#f(e){return`${this.#i}${e}`}#b(e){for(const[t,{queryable:s}]of e)this.#t.find(a=>a.name===t)||this.#t.push({queryable:s,name:t,type:"string",facet:!0,optional:!0})}#h(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#a(e){return`\`${e.replaceAll("`","")}\``}#n(e,t,s){const a=e.teams.filter(r=>!r.includes("`")&&!r.includes("*")).map(r=>this.#a(r)),n=a.length?`${d}:=[${a.join(", ")}]`:`${d}:=[\`anonymous\`] && ${d}:!=[\`anonymous\`]`,o=(t??[]).filter(r=>r.field!==s&&r.field!==h&&r.values.length&&this.#p(r.field)).map(r=>{const i=r.values.map(c=>this.#a(c));return`${r.field}:=[${i.join(", ")}]`});return[n,...o,this.#E(t)].map(r=>`(${r})`).join(" && ")}#p(e){return this.#o().includes(e)}#o(){return this.#t.filter(e=>e.facet&&e.name!==d&&e.name===e.name.trim()).map(e=>e.name)}#E(e){const t=e?.find(r=>r.field===h);if(t?.values.length!==2)return`${h}.isDefault:true`;const[s,a]=t.values.map(r=>this.#a(r)),n=`(${h}.folderId:! ${s} && ${h}.isDefault:true)`,o=`(${h}.folderId: ${s} && ${h}.version:=${a})`;return`${n} || ${o}`}#A(e,t){return e&&t&&this.#p(t)?`${t}:${e}`:""}#m(e){const t=[];if(e&&e.length)for(const s of e)s.field===F&&t.push(...s.values);return t}#F(e,t){const s=[];for(const a of this.#o()){const n={facet_by:a,filter_by:this.#n(e,t,a),per_page:0};s.push(n)}return s}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(s=>{s.values=[]}),e.setSearchFacets(t)}}export{X as Typesense};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RedoclyConfig } from '@redocly/config';
|
|
2
|
+
import type { WildcardRedirectsTree } from './types';
|
|
3
|
+
import { readEnvVariable } from './utils/envs/read-env-variable.js';
|
|
4
|
+
export type ComputedRedoclyConfig = {
|
|
5
|
+
configFilePath: string;
|
|
6
|
+
linkTags?: string;
|
|
7
|
+
headScriptTags?: string;
|
|
8
|
+
postBodyScriptTags?: string;
|
|
9
|
+
preBodyScriptTags?: string;
|
|
10
|
+
wildcardRedirectsTree: WildcardRedirectsTree;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
};
|
|
13
|
+
export type StoreConfig = WithRequired<RedoclyConfig, 'redirects'> & ComputedRedoclyConfig;
|
|
14
|
+
export declare function createDefaultStoreConfig(): StoreConfig;
|
|
15
|
+
/** Resolves the env placeholders in a copy of `entries` and normalizes `seo.siteUrl`. */
|
|
16
|
+
export declare function resolveConfigEntries(entries: Partial<RedoclyConfig>): {
|
|
17
|
+
config: Partial<RedoclyConfig>;
|
|
18
|
+
unsetEnvVars: string[];
|
|
19
|
+
replacedValues: Record<string, {
|
|
20
|
+
original: string;
|
|
21
|
+
replaced: string;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The store config of a build output: the defaults, overridden by the parsed JSON of its config
|
|
26
|
+
* file, which this changes in place. `env` holds each value that `readEnv` returned: a reader of
|
|
27
|
+
* only these values gives the same config. The partials stay JSON, never `undefined`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveStoreConfig(fileEntries: Partial<RedoclyConfig>, readEnv?: typeof readEnvVariable): {
|
|
30
|
+
config: StoreConfig;
|
|
31
|
+
env: Record<string, string>;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=store-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{removeTrailingSlash as a}from"../utils/url/remove-trailing-slash.js";import{MARKDOC_PARTIALS_DATA_KEY as c}from"./constants/common.js";import{readEnvVariable as l}from"./utils/envs/read-env-variable.js";import{replaceEnvVariablesDeep as f,replaceEnvVariablesInPlace as u}from"./utils/envs/replace-env-variables-deep.js";function d(){return{configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}}}function S(e){const{resolvedObj:r,unsetEnvVars:o,replacedValues:i}=f(e);return s(r),{config:r,unsetEnvVars:o,replacedValues:i}}function U(e,r=l){const o={};u(e,t=>{const n=r(t);return n!==void 0&&(o[t]=n),n}),s(e);const i={...d(),...e};return i[c]||={},{config:i,env:o}}function s(e){const r=e.seo?.siteUrl?.trim();r&&(e.seo={...e.seo,siteUrl:URL.canParse(r)?new URL(r).origin:a(r)})}export{d as createDefaultStoreConfig,S as resolveConfigEntries,U as resolveStoreConfig};
|
package/dist/server/store.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { type Node } from '@
|
|
1
|
+
import { type Node } from '@redocly/markdoc';
|
|
2
2
|
import type { JSX } from 'react';
|
|
3
3
|
import type { CommonError, GlobalData } from '../types/index.js';
|
|
4
|
-
import type { MiddlewareDetails, PageRouteInit, PageRouteDetails, RouteDetails, LifecycleContext, ApiRoute, ParseMarkdocOpts,
|
|
4
|
+
import type { MiddlewareDetails, PageRouteInit, PageRouteDetails, RouteDetails, LifecycleContext, ApiRoute, ParseMarkdocOpts, StaticFilePaths, RedirectOptions, McpToolRegistration, McpToolSchema, MarkdocOptions } from './types';
|
|
5
5
|
import type { Skill } from './types/plugins/skills.js';
|
|
6
6
|
import type { RedoclyConfig, RedirectConfig, CompilationError, PageStaticData } from '@redocly/config';
|
|
7
7
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
8
8
|
import type { BundledApiDefinition } from './plugins/api-docs/loader.js';
|
|
9
9
|
import type { SearchEngine } from './plugins/search/engines/search-engine.js';
|
|
10
|
+
import type { StoreConfig } from './store-config.js';
|
|
11
|
+
import type { StoreConfigFile } from './workers/worker-config.js';
|
|
10
12
|
import { KvService } from './persistence/kv/services/kv-service.js';
|
|
11
13
|
export declare const USER_DEFINED_API_FUNCTIONS_COUNTER_KEY = "userDefinedApiFunctions";
|
|
12
14
|
type LifecycleEventType = 'global-data-updated' | 'shared-data-updated' | 'routes-updated' | 'build-updated' | 'build-started' | 'errors-updated' | 'pages-updated';
|
|
@@ -16,18 +18,10 @@ export type StoreOptions = {
|
|
|
16
18
|
serverOutDir: string;
|
|
17
19
|
serverMode?: boolean;
|
|
18
20
|
};
|
|
19
|
-
export type ComputedRedoclyConfig = {
|
|
20
|
-
configFilePath: string;
|
|
21
|
-
linkTags?: string;
|
|
22
|
-
headScriptTags?: string;
|
|
23
|
-
postBodyScriptTags?: string;
|
|
24
|
-
preBodyScriptTags?: string;
|
|
25
|
-
wildcardRedirectsTree: WildcardRedirectsTree;
|
|
26
|
-
[key: string]: unknown;
|
|
27
|
-
};
|
|
28
21
|
export declare class Store {
|
|
29
22
|
#private;
|
|
30
23
|
routesBySlug: Map<string, PageRouteDetails>;
|
|
24
|
+
routeAliases: Map<string, string>;
|
|
31
25
|
staticFilePaths: StaticFilePaths;
|
|
32
26
|
replacedEnvVars: Record<string, {
|
|
33
27
|
original: string;
|
|
@@ -62,7 +56,9 @@ export declare class Store {
|
|
|
62
56
|
globalData: GlobalData;
|
|
63
57
|
/** Whether `POST /authorize` mints dev sessions: set by `realm develop` (unless `--no-dev-login`) and `realm build --devLogin`. */
|
|
64
58
|
devLogin: boolean;
|
|
65
|
-
config:
|
|
59
|
+
config: StoreConfig;
|
|
60
|
+
/** Set when the store loads from a build output: the workers then read the config from this file. */
|
|
61
|
+
configFile?: StoreConfigFile;
|
|
66
62
|
serverMode: boolean;
|
|
67
63
|
serverOutDir: string;
|
|
68
64
|
outdir: string;
|
|
@@ -139,6 +135,8 @@ export declare class Store {
|
|
|
139
135
|
getRouteBySlug: (slug: string, opts?: {
|
|
140
136
|
followRedirect?: boolean;
|
|
141
137
|
}) => PageRouteDetails | undefined;
|
|
138
|
+
/** Makes `from` resolve to the route at `to` wherever a redirect would be followed (link resolution, the link checker), without an HTTP redirect; unlike `addRedirect` it needs no entitlement. */
|
|
139
|
+
addRouteAlias: (from: string, to: string) => void;
|
|
142
140
|
hasRouteOrRedirectBySlug: (slug: string) => boolean;
|
|
143
141
|
getRoutesByTemplateId: (templateId: string) => PageRouteInit[];
|
|
144
142
|
getAllRoutesForLocale: (locale?: string) => PageRouteDetails[];
|
|
@@ -157,10 +155,10 @@ export declare class Store {
|
|
|
157
155
|
resolveRouteStaticData(route: RouteDetails, _context?: LifecycleContext, skipLastModified?: boolean): Promise<PageStaticData>;
|
|
158
156
|
addSsrComponents(components: JSX.Element[] | string[], position: 'head' | 'preBody' | 'postBody'): void;
|
|
159
157
|
clear: () => void;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
static
|
|
158
|
+
/** Writes the files that `fromServerFiles` reads. The config file keeps the env placeholders. */
|
|
159
|
+
writeServerFiles(): Promise<void>;
|
|
160
|
+
/** Loads the store from the files of a build output. The config resolves from the current env. */
|
|
161
|
+
static fromServerFiles(options: StoreOptions): Promise<Store>;
|
|
164
162
|
getConfigWithEnvPlaceholders(): Promise<RedoclyConfig>;
|
|
165
163
|
reportUnsetEnvVars(): Promise<void>;
|
|
166
164
|
}
|
package/dist/server/store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import A from"@markdoc/markdoc";import{parseAndResolveMarkdoc as T}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as M}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as O,MARKDOC_PARTIALS_DATA_KEY as m,MARKDOC_PARTIALS_DEPS_KEY as k}from"./constants/common.js";import{GATED_MARKDOC_TAGS as R}from"./constants/entitlements.js";import{isObject as L}from"../utils/guards/is-object.js";import{mapObject as H}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as D}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as u}from"../utils/path/normalize-route-slug.js";import{isLocalLink as S}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as h}from"./tools/notifiers/logger.js";import{sha1 as F}from"./utils/crypto/sha1.js";import{envConfig as G,setEnv as _}from"./config/env-config.js";import{KvService as B}from"./persistence/kv/services/kv-service.js";import{SandboxContext as I}from"./utils/sandbox-context.js";import{writeSharedData as N}from"./utils/index.js";import{renderComponents as V}from"./ssr/render.js";import{readStaticData as q,writeStaticData as j}from"./utils/static-data.js";import{getMarkdocOptions as U}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as v}from"./entitlements/entitlements-provider.js";import{isRouteReserved as x}from"./plugins/get-reserved-routes.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as W}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as $}from"./utils/redirects/find-redirect.js";import{followRedirectChain as z}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as Y}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as Z}from"../cli/telemetry/helpers/trace-step.js";const E={routesBySlug:"map",staticFilePaths:"object",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},P="PLAN_GATES",Q=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],ke="userDefinedApiFunctions";class b{routesBySlug=new Map;staticFilePaths={};replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#o=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#h=Promise.resolve();#u;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:s,serverMode:t=!1,serverOutDir:r}){this.#i=s,this.outdir=e,this.serverMode=t,this.serverOutDir=r,I.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(a=>{this.#n=a})}on(e,s){const t=this.listeners.get(e);t?t.add(s):this.listeners.set(e,new Set([s]))}queueEvent=(e,s,...t)=>{this.#a.set(e+String(s),[e,s,...t])};runListeners=(e,s,...t)=>{for(const r of this.listeners.get(e)||new Set)s?r(s,...t):r(...t)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#h=new Promise(e=>{this.#u=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#u?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await Z("com.redocly.build.reloadMarkdocOptions",async()=>{const e=v.instance(),s=await U(this.serverOutDir),t=Object.fromEntries(Object.entries(s.tags).filter(([r])=>R[r]!=null?e.canAccessFeature(R[r]):!0));this.#o={...s,tags:t}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=e=>{const s=this.globalData,t={...this.globalData,...e};this.globalData=t,JSON.stringify(t)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,t)};getGlobalData=()=>this.globalData;getKv=async()=>B.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:s,deps:t,resource:r})=>{const{data:{info:a,ast:i},compoundHash:l}=await T(e,this.markdocOptions,{actions:this,context:s},r);for(const o of a.sharedDataDeps||[]){for(const n of t?.routeSlugs||[])this.addRouteSharedData(n,o,o);for(const n of t?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(o),this.sharedDataDeps.set(n,c)}}for(const o of a.dynamicMarkdocComponents||[]){for(const n of t?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(o),this.routesDynamicComponents.set(n,c)}for(const n of t?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(o),this.sharedDataMarkdocComponents.set(n,c)}}if(t?.routeSlugs&&a.partials?.length)for(const o of t.routeSlugs){const n=this.routesPartials.get(o)||[];for(const c of a.partials)n.includes(c)||n.push(c);this.routesPartials.set(o,n)}return{info:a,ast:i,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setStaticFilePaths=e=>{this.staticFilePaths=e};setGlobalConfig=e=>{const s=Object.keys(e);for(const l of s)for(const o in this.replacedEnvVars)if(o===l||o.startsWith(`${l}:`)){const n=o.split(":"),{error:c,value:d}=y(e,n);(c||d!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:t,unsetEnvVars:r,replacedValues:a}=W(e);for(const l of r)this.unsetEnvVars.add(l);Object.assign(this.replacedEnvVars,a);const i=t.seo?.siteUrl?.trim();i&&(t.seo={...t.seo,siteUrl:URL.canParse(i)?new URL(i).origin:D(i)}),Object.assign(this.config,t)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,s,t={})=>{if(!v.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const i=u(e).toLowerCase();this.config.redirects[i]=s;const{trackOriginalSource:l=!0}=t,o=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(o)&&!o.includes(i)&&o.push(i),i.endsWith("*")&&Y(this.config.wildcardRedirectsTree,i)};getRedirect=e=>{const s=u(e).toLowerCase(),t=$(s,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!t)return null;if(S(t.to)){const r=u(t.to).toLowerCase();if(!r.endsWith("*")&&z(r,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:t.to,type:t.type}};createSharedData=async(e,s,t)=>{if(t&&this.#t[e]===t)return e;const r=JSON.stringify(s),a=t??F(r);return this.#t[e]===a||(this.#t[e]=a,await N(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,s,t)=>{const r=D(e),a=this.routesSharedData.get(r)||{};a[s]=t,this.routesSharedData.set(r,a),h.verbose(`Adding shared data to ${e}, ${s}, ${t}`)};getRouteSharedDataByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=e=>{const s=this.getGlobalConfig(m)||{},t=this.routesPartials.get(e);if(!t||t.length===0)return{};const r=this.getGlobalConfig(k)||{},a=new Set(t),i=Array.from(t);for(let o=0;o<i.length;o++){const n=i[o],c=r[n]?.partials??[];for(const d of c)a.has(d)||(a.add(d),i.push(d))}const l={};for(const o of a)s[o]&&(l[o]=s[o]);return l};addRoute=e=>{const t={...J(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:t}),h.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,s,t)=>{const r=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const i=M(e,g,a.code,r);this.addRouteSharedData(i,s,t)}};addApiRoute=e=>{this.apiRoutes.push(e),h.verbose("Created API route %s",e.slug)};addMcpTools=(e,s)=>{for(const t of s){const r=this.mcpToolHandlers.get(t.name);r&&r.importPath!==e&&h.warn('MCP tool "%s" from %s overwrites the tool registered from %s',t.name,e,r.importPath),this.mcpToolHandlers.set(t.name,{...t,importPath:e}),h.verbose("Created MCP tool %s",t.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const s of e){const t=this.mcpToolHandlers.get(s);t&&this.mcpToolHandlers.set(s,{...t,hasAvailabilityGate:!0})}};addSkills=e=>{for(const s of e)this.skills.set(s.slug,s),h.verbose("Discovered skill %s",s.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const s of e)this.mcpToolHandlers.delete(s)};addMiddleware=e=>{this.middleware.push(e),h.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,s)=>{this.config.responseHeaders||(this.config.responseHeaders={});const t=new Set(s.map(i=>i.name.toLowerCase())),a=[...(this.config.responseHeaders[e]??[]).filter(i=>!t.has(i.name.toLowerCase())),...s];this.config.responseHeaders[e]=a};getRouteByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(e,s={})=>{const{followRedirect:t=!0}=s,r=this.getRedirect(e);return t&&r?this.routesBySlug.get(u(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||x(e,this.getConfig()))return!0;const s=this.getRedirect(e);if(!s)return!1;if(!S(s.to))return!0;const t=u(s.to);return this.routesBySlug.has(t)};getRoutesByTemplateId=e=>this.newRoutes.filter(s=>s.templateId===e);getAllRoutesForLocale=(e=g)=>{const s=Array.from(this.routesBySlug.values()),t=e.toLowerCase();return s.filter(r=>e===g?!K(r.fsPath):r.slug.startsWith(`/${t}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,s)=>(this.templates.set(e,s),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,s)=>(this.apiRoutesRequestHandlers.set(e,s),e);clearRequestHandlersByPrefix=e=>{for(const s of this.apiRoutesRequestHandlers.keys())s.startsWith(e)&&this.apiRoutesRequestHandlers.delete(s)};registerServerPropsGetter=(e,s)=>(this.serverPropsGetters.set(e,s),e);registerPagePropsGetter=(e,s)=>{this.pagePropsGetters.set(e,s)};async writeRouteStaticData(e,s){const t=await this.resolveRouteStaticData(e,s,!1);t&&j(e.slug,t,this.outdir)}async resolveRouteStaticData(e,s,t){if(this.serverMode)return q(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[e.slug]},resource:f})},a=await e.getStaticData?.(e,r)||{},i=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>i.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const o=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(i),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:O,...o,...a.props?.seo,siteUrl:o?.siteUrl},compilationErrors:this.compilationErrors},lastModified:t||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,s){if(!e?.length)return;const t=typeof e[0]=="string"?e.join(""):V(e);t&&(s==="head"?this.ssr.headTags.push(t):s==="preBody"?this.ssr.preBodyTags.push(t):this.ssr.postBodyTags.push(t))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[t,r]of Object.entries(E))switch(r){case"map":{const a=Array.from(this[t].entries());e.push([t,a]);break}case"object":if(t==="config"){e.push([t,await this.getConfigWithEnvPlaceholders()]);break}e.push([t,this[t]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(e);return s[P]=G.PLAN_GATES,s}static fromJson(e,s){const t=new b(s);for(const[a,i]of Object.entries(E))switch(i){case"map":t[a]=new Map(e[a]);break;case"object":if(a==="config"){t.setGlobalConfig(e[a]);break}t[a]=e[a];break;default:throw new Error("Invalid format")}t.config[m]=X(t.config[m]||{});const r=e[P];return r&&_("PLAN_GATES",r),t}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:t}=this.replacedEnvVars[s],r=s.split(":"),a=r.pop(),{error:i,value:l}=y(e,r);if(i||!L(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[a]=t}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(t=>!Q.includes(t));if(e.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await w.panicOnBuildContentError(s)}}function X(C){return H(C,e=>A.Ast.fromJSON(JSON.stringify(e)))}export{b as Store,ke as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
1
|
+
import k from"@redocly/markdoc";import{writeFileSync as S}from"node:fs";import{readFile as D}from"node:fs/promises";import{join as g}from"node:path";import{parseAndResolveMarkdoc as F}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as L}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as m}from"../constants/common.js";import{DEFAULT_TITLE as H,MARKDOC_PARTIALS_DATA_KEY as y,MARKDOC_PARTIALS_DEPS_KEY as G}from"./constants/common.js";import{GATED_MARKDOC_TAGS as v}from"./constants/entitlements.js";import{isObject as _}from"../utils/guards/is-object.js";import{mapObject as N}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as B}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as d}from"../utils/path/normalize-route-slug.js";import{isLocalLink as E}from"../utils/path/is-local-link.js";import{reporter as P}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as I}from"./utils/crypto/sha1.js";import{envConfig as j,setEnv as V}from"./config/env-config.js";import{KvService as q}from"./persistence/kv/services/kv-service.js";import{SandboxContext as J}from"./utils/sandbox-context.js";import{isAllowedEnv as U}from"./utils/envs/get-api-route-allowed-env-variables.js";import{ensureDir as x,writeSharedData as K}from"./utils/index.js";import{renderComponents as W}from"./ssr/render.js";import{readStaticData as $,writeStaticData as z}from"./utils/static-data.js";import{getMarkdocOptions as Y}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as C}from"./entitlements/entitlements-provider.js";import{isRouteReserved as Z}from"./plugins/get-reserved-routes.js";import{isL10nPath as Q}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as X}from"./utils/globs.js";import{createDefaultStoreConfig as ee,resolveConfigEntries as te,resolveStoreConfig as se}from"./store-config.js";import{findRedirect as re}from"./utils/redirects/find-redirect.js";import{followRedirectChain as ae}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as oe}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as ie}from"../cli/telemetry/helpers/trace-step.js";const A={routesBySlug:"map",staticFilePaths:"object",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},b="store.json",O="store-config.json",T="PLAN_GATES",ne=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Ue="userDefinedApiFunctions";class R{routesBySlug=new Map;routeAliases=new Map;staticFilePaths={};replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#o=void 0;config=ee();configFile;#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#l;#c=Promise.resolve();#d;#h=Promise.resolve();#u;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:r}){this.#i=t,this.outdir=e,this.serverMode=s,this.serverOutDir=r,J.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(a=>{this.#n=a})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#a.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const r of this.listeners.get(e)||new Set)t?r(t,...s):r(...s)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#l=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#c,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#l?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#c=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#h=new Promise(e=>{this.#u=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#u?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await ie("com.redocly.build.reloadMarkdocOptions",async()=>{const e=C.instance(),t=await Y(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([r])=>v[r]!=null?e.canAccessFeature(v[r]):!0));this.#o={...t,tags:s}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(y),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>q.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:t,deps:s,resource:r})=>{const{data:{info:a,ast:o},compoundHash:l}=await F(e,this.markdocOptions,{actions:this,context:t},r);for(const i of a.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of a.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(s?.routeSlugs&&a.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of a.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:a,ast:o,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setStaticFilePaths=e=>{this.staticFilePaths=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const o of t)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=w(e,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{config:s,unsetEnvVars:r,replacedValues:a}=te(e);for(const o of r)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t,s={})=>{if(!C.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const o=d(e).toLowerCase();this.config.redirects[o]=t;const{trackOriginalSource:l=!0}=s,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&oe(this.config.wildcardRedirectsTree,o)};getRedirect=e=>{const t=d(e).toLowerCase(),s=re(t,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!s)return null;if(E(s.to)){const r=d(s.to).toLowerCase();if(!r.endsWith("*")&&ae(r,[t],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:s.to,type:s.type}};createSharedData=async(e,t,s)=>{if(s&&this.#t[e]===s)return e;const r=JSON.stringify(t),a=s??I(r);return this.#t[e]===a||(this.#t[e]=a,await K(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=B(e),a=this.routesSharedData.get(r)||{};a[t]=s,this.routesSharedData.set(r,a),u.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};getPartialsForRoute=e=>{const t=this.getGlobalConfig(y)||{},s=this.routesPartials.get(e);if(!s||s.length===0)return{};const r=this.getGlobalConfig(G)||{},a=new Set(s),o=Array.from(s);for(let i=0;i<o.length;i++){const n=o[i],c=r[n]?.partials??[];for(const h of c)a.has(h)||(a.add(h),o.push(h))}const l={};for(const i of a)t[i]&&(l[i]=t[i]);return l};addRoute=e=>{const s={...X(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),u.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[m,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const o=L(e,m,a.code,r);this.addRouteSharedData(o,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),u.verbose("Created API route %s",e.slug)};addMcpTools=(e,t)=>{for(const s of t){const r=this.mcpToolHandlers.get(s.name);r&&r.importPath!==e&&u.warn('MCP tool "%s" from %s overwrites the tool registered from %s',s.name,e,r.importPath);const a=s.hasAvailabilityGate??(r?.importPath===e?r.hasAvailabilityGate:void 0);this.mcpToolHandlers.set(s.name,{...s,importPath:e,hasAvailabilityGate:a}),u.verbose("Created MCP tool %s",s.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const t of e){const s=this.mcpToolHandlers.get(t);s&&this.mcpToolHandlers.set(t,{...s,hasAvailabilityGate:!0})}};addSkills=e=>{for(const t of e)this.skills.set(t.slug,t),u.verbose("Discovered skill %s",t.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const t of e)this.mcpToolHandlers.delete(t)};addMiddleware=e=>{this.middleware.push(e),u.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(o=>o.name.toLowerCase())),a=[...(this.config.responseHeaders[e]??[]).filter(o=>!s.has(o.name.toLowerCase())),...t];this.config.responseHeaders[e]=a};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,r=this.getRedirect(e);if(s&&r)return this.routesBySlug.get(d(r.to));const a=s?this.routeAliases.get(d(e).toLowerCase()):void 0;return this.routesBySlug.get(a??e)};addRouteAlias=(e,t)=>{this.routeAliases.set(d(e).toLowerCase(),d(t))};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||this.routeAliases.has(d(e).toLowerCase())||Z(e,this.getConfig()))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!E(t.to))return!0;const s=d(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=m)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(r=>e===m?!Q(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);clearRequestHandlersByPrefix=e=>{for(const t of this.apiRoutesRequestHandlers.keys())t.startsWith(e)&&this.apiRoutesRequestHandlers.delete(t)};registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&z(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return $(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:h,resource:f})=>this.parseMarkdoc({input:c,context:h,deps:{routeSlugs:[e.slug]},resource:f})},a=await e.getStaticData?.(e,r)||{},o=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const h=this.sharedDataMarkdocComponents.get(c);h&&h.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(o),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:H,...i,...a.props?.seo,siteUrl:i?.siteUrl},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):W(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.routeAliases.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};#p(){const e=[];for(const[s,r]of Object.entries(A))switch(r){case"map":{const a=Array.from(this[s].entries());e.push([s,a]);break}case"object":e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[T]=j.PLAN_GATES,t}static#g(e,t){const s=new R(t);for(const[a,o]of Object.entries(A))switch(o){case"map":s[a]=new Map(e[a]);break;case"object":s[a]=e[a];break;default:throw new Error("Invalid format")}const r=e[T];return r&&V("PLAN_GATES",r),s}async writeServerFiles(){x(this.serverOutDir),S(g(this.serverOutDir,b),JSON.stringify(this.#p())),S(g(this.serverOutDir,O),JSON.stringify(await this.getConfigWithEnvPlaceholders()))}static async fromServerFiles(e){const t=g(e.serverOutDir,O),{config:s,env:r}=se(JSON.parse(await D(t,"utf8")));s[y]=le(s[y]);const a=JSON.parse(await D(g(e.serverOutDir,b),"utf8")),o=R.#g(a,e);o.config=s;const l=Object.fromEntries(Object.entries(r).filter(([i])=>U(i)));return o.configFile={path:t,env:l,config:{...s}},o}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],r=t.split(":"),a=r.pop(),{error:o,value:l}=w(e,r);if(o||!_(l)&&!Array.isArray(l)){await P.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}l[a]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!ne.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await P.panicOnBuildContentError(t)}}function le(M){return N(M,e=>k.Ast.fromJSON(JSON.stringify(e)))}export{R as Store,Ue as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import*as E from"node:path";import{envConfig as R}from"../../config/env-config.js";import{maskEmail as T
|
|
2
|
-
`},y=({context:e,message:
|
|
3
|
-
`},D=e=>(e%500<100?x:e%400<100?b:A)(`status="${e}"`),j=()=>{const e=new Date().getTimezoneOffset()*6e4;return new Date(Date.now()-e).toISOString().slice(0,-1)},V=e=>
|
|
1
|
+
import*as E from"node:path";import{envConfig as R}from"../../config/env-config.js";import{maskEmail as T,maskSubject as C,removePii as w,removePiiFromUrl as $}from"../../../compiled/@redocly/pii/index.mjs";import{red as x,green as A,bold as F,blue as l,gray as r,yellow as b,cyan as v}from"./helpers/colors.js";function P(e,s){return s?e:w(e)}var n;(function(e){e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.SUCCESS="SUCCESS",e.VERBOSE="VERBOSE",e.HTTP="HTTP"})(n||(n={}));const I={[n.VERBOSE]:0,[n.HTTP]:1,[n.INFO]:2,[n.SUCCESS]:2,[n.WARN]:3,[n.ERROR]:4};function J(e,s){return I[e]>=I[s]}function W(e){if(!e)return;const s=e.toUpperCase();if(s in n)return s}const H={[n.INFO]:l,[n.SUCCESS]:A,[n.WARN]:b,[n.ERROR]:x,[n.HTTP]:v,[n.VERBOSE]:r},N={"%ap":e=>l(E.resolve(e)),"%rp":e=>l(E.relative(process.cwd(),e)),"%s":e=>e?.toString(),"%c":e=>l(e)},M={format(e){return R.REDOCLY_LOG_FORMAT==="JSON"?y(e):U(e)},interpolate(e,...s){const u=Object.keys(N).map(a=>`(${a})`).join("|"),o=new RegExp(u,"g");let i,c=e;for(;(i=o.exec(e))!==null;){i.index===o.lastIndex&&o.lastIndex++;const a=s.shift();if(a===void 0)break;const t=i[0];c=c.replace(t,N[t](a))}return c}};var z=M;const U=e=>{const{level:s,message:u,duration:o,context:i,preSanitized:c}=e,a=R.isRuntimeMode,t=[H[s](F(`[${s.toLowerCase()}]`))];if(a&&t.push(r(`time="${j()}"`)),i){const{email:m,ipAddress:f,subject:d,method:S,pathname:p,statusCode:h,teams:g,apiFunction:O}=i;O&&t.push(l(`fn="${O}"`)),h&&t.push(D(h)),e.level===n.HTTP&&(S&&t.push(r(`method="${S}"`)),p&&t.push(r(`path="${$(p)}"`))),f&&t.push(r(`ip="${f}"`)),m&&t.push(r(`email="${T(m)}"`)),d&&t.push(r(`sub="${C(d)}"`)),g?.length&&t.push(r(`teams="${g.join(", ")}"`))}if(u){const m=a?`msg="${String(P(u,c)).replaceAll?.('"','\\"')}"`:String(u);t.push(m)}return e.level===n.HTTP&&i?.userAgent&&t.push(r(`agent="${i.userAgent}"`)),o&&t.push(V(o)),t.join(" ")+`
|
|
2
|
+
`},y=({context:e,message:s,preSanitized:u,...o})=>{const{method:i,pathname:c,statusCode:a,userAgent:t,subject:m,email:f,teams:d,apiFunction:S}=e||{},p={...o,email:f&&T(f),subject:m&&C(m),teams:d,apiFunction:S,...o.level===n.HTTP?{method:i,pathname:String($(c)),statusCode:a,userAgent:t}:{message:String(P(String(s??""),u))}};return R.isRuntimeMode&&(p.time=j()),JSON.stringify(p,["time","level","scope","message","duration","method","pathname","statusCode","userAgent","subject","ipAddress","email","apiFunction"])+`
|
|
3
|
+
`},D=e=>(e%500<100?x:e%400<100?b:A)(`status="${e}"`),j=()=>{const e=new Date().getTimezoneOffset()*6e4;return new Date(Date.now()-e).toISOString().slice(0,-1)},V=e=>r(`dur="${Math.round(e)}ms"`);export{n as LogLevel,z as default,W as parseLogLevel,J as shouldLog};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
declare const colorsAreEnabled: boolean;
|
|
2
|
-
declare const red
|
|
2
|
+
declare const { red, green, bold, blue, gray, yellow, cyan }: import("colorette").Colorette;
|
|
3
3
|
declare const stripColors: (input: string) => string;
|
|
4
4
|
export { red, gray, green, blue, bold, yellow, cyan, colorsAreEnabled, stripColors };
|
|
5
5
|
//# sourceMappingURL=colors.d.ts.map
|