@redocly/redoc 0.140.0-next.1 → 0.140.0-next.10
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 +409 -201
- 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/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/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/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/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 +11 -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/types/plugins/api-routes.d.ts +4 -1
- package/dist/server/types/plugins/common.d.ts +1 -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/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/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 +11 -11
- 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,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,15 +18,6 @@ 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>;
|
|
@@ -62,7 +55,9 @@ export declare class Store {
|
|
|
62
55
|
globalData: GlobalData;
|
|
63
56
|
/** Whether `POST /authorize` mints dev sessions: set by `realm develop` (unless `--no-dev-login`) and `realm build --devLogin`. */
|
|
64
57
|
devLogin: boolean;
|
|
65
|
-
config:
|
|
58
|
+
config: StoreConfig;
|
|
59
|
+
/** Set when the store loads from a build output: the workers then read the config from this file. */
|
|
60
|
+
configFile?: StoreConfigFile;
|
|
66
61
|
serverMode: boolean;
|
|
67
62
|
serverOutDir: string;
|
|
68
63
|
outdir: string;
|
|
@@ -157,10 +152,10 @@ export declare class Store {
|
|
|
157
152
|
resolveRouteStaticData(route: RouteDetails, _context?: LifecycleContext, skipLastModified?: boolean): Promise<PageStaticData>;
|
|
158
153
|
addSsrComponents(components: JSX.Element[] | string[], position: 'head' | 'preBody' | 'postBody'): void;
|
|
159
154
|
clear: () => void;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
static
|
|
155
|
+
/** Writes the files that `fromServerFiles` reads. The config file keeps the env placeholders. */
|
|
156
|
+
writeServerFiles(): Promise<void>;
|
|
157
|
+
/** Loads the store from the files of a build output. The config resolves from the current env. */
|
|
158
|
+
static fromServerFiles(options: StoreOptions): Promise<Store>;
|
|
164
159
|
getConfigWithEnvPlaceholders(): Promise<RedoclyConfig>;
|
|
165
160
|
reportUnsetEnvVars(): Promise<void>;
|
|
166
161
|
}
|
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 D}from"node:fs";import{readFile as R}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 u}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 h}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 oe}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as ae}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as ie}from"../cli/telemetry/helpers/trace-step.js";const b={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"},O="store.json",A="store-config.json",T="PLAN_GATES",ne=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Ue="userDefinedApiFunctions";class S{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;#a=void 0;config=ee();configFile;#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;#o=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(o=>{this.#n=o})}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.#o.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.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#o.values())this.runListeners(...e);this.#o.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 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.#a={...t,tags:s}})}get markdocOptions(){return{...this.#a,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:o,ast:a},compoundHash:c}=await F(e,this.markdocOptions,{actions:this,context:t},r);for(const i of o.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const l=this.sharedDataDeps.get(n)||new Set;l.add(i),this.sharedDataDeps.set(n,l)}}for(const i of o.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const l=this.routesDynamicComponents.get(n)||new Set;l.add(i),this.routesDynamicComponents.set(n,l)}for(const n of s?.sharedDataIds||[]){const l=this.sharedDataMarkdocComponents.get(n)||new Set;l.add(i),this.sharedDataMarkdocComponents.set(n,l)}}if(s?.routeSlugs&&o.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const l of o.partials)n.includes(l)||n.push(l);this.routesPartials.set(i,n)}return{info:o,ast:a,compoundHash:c}};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 a of t)for(const c in this.replacedEnvVars)if(c===a||c.startsWith(`${a}:`)){const i=c.split(":"),{error:n,value:l}=w(e,i);(n||l!==this.replacedEnvVars[c].replaced)&&delete this.replacedEnvVars[c]}const{config:s,unsetEnvVars:r,replacedValues:o}=te(e);for(const a of r)this.unsetEnvVars.add(a);Object.assign(this.replacedEnvVars,o),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 a=u(e).toLowerCase();this.config.redirects[a]=t;const{trackOriginalSource:c=!0}=s,i=this.getGlobalConfig("originalRedirectSources");c&&Array.isArray(i)&&!i.includes(a)&&i.push(a),a.endsWith("*")&&ae(this.config.wildcardRedirectsTree,a)};getRedirect=e=>{const t=u(e).toLowerCase(),s=re(t,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!s)return null;if(E(s.to)){const r=u(s.to).toLowerCase();if(!r.endsWith("*")&&oe(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),o=s??I(r);return this.#t[e]===o||(this.#t[e]=o,await K(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=B(e),o=this.routesSharedData.get(r)||{};o[t]=s,this.routesSharedData.set(r,o),h.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)||{},o=new Set(s),a=Array.from(s);for(let i=0;i<a.length;i++){const n=a[i],l=r[n]?.partials??[];for(const d of l)o.has(d)||(o.add(d),a.push(d))}const c={};for(const i of o)t[i]&&(c[i]=t[i]);return c};addRoute=e=>{const s={...X(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),h.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[m,...this.lifecycleContext?.fs.localeFolders||[]].map(o=>({code:o,name:o}));for(const o of r){const a=L(e,m,o.code,r);this.addRouteSharedData(a,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),h.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&&h.warn('MCP tool "%s" from %s overwrites the tool registered from %s',s.name,e,r.importPath);const o=s.hasAvailabilityGate??(r?.importPath===e?r.hasAvailabilityGate:void 0);this.mcpToolHandlers.set(s.name,{...s,importPath:e,hasAvailabilityGate:o}),h.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),h.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),h.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(a=>a.name.toLowerCase())),o=[...(this.config.responseHeaders[e]??[]).filter(a=>!s.has(a.name.toLowerCase())),...t];this.config.responseHeaders[e]=o};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);return s&&r?this.routesBySlug.get(u(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||Z(e,this.getConfig()))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!E(t.to))return!0;const s=u(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:l,context:d,resource:f})=>this.parseMarkdoc({input:l,context:d,deps:{routeSlugs:[e.slug]},resource:f})},o=await e.getStaticData?.(e,r)||{},a=new Set(this.routesDynamicComponents.get(e.slug)),c=this.routesSharedData.get(e.slug)||{};for(const l of Object.values(c)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(p=>a.add(p));const f=this.sharedDataDeps.get(l);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=o?.frontmatter||{};return{...o,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...o.props,dynamicMarkdocComponents:Array.from(a),metadata:{...o?.props?.metadata,...e.metadata},seo:{title:H,...i,...o.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.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(b))switch(r){case"map":{const o=Array.from(this[s].entries());e.push([s,o]);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 S(t);for(const[o,a]of Object.entries(b))switch(a){case"map":s[o]=new Map(e[o]);break;case"object":s[o]=e[o];break;default:throw new Error("Invalid format")}const r=e[T];return r&&V("PLAN_GATES",r),s}async writeServerFiles(){x(this.serverOutDir),D(g(this.serverOutDir,O),JSON.stringify(this.#p())),D(g(this.serverOutDir,A),JSON.stringify(await this.getConfigWithEnvPlaceholders()))}static async fromServerFiles(e){const t=g(e.serverOutDir,A),{config:s,env:r}=se(JSON.parse(await R(t,"utf8")));s[y]=ce(s[y]);const o=JSON.parse(await R(g(e.serverOutDir,O),"utf8")),a=S.#g(o,e);a.config=s;const c=Object.fromEntries(Object.entries(r).filter(([i])=>U(i)));return a.configFile={path:t,env:c,config:{...s}},a}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(":"),o=r.pop(),{error:a,value:c}=w(e,r);if(a||!_(c)&&!Array.isArray(c)){await P.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}c[o]=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 ce(M){return N(M,e=>k.Ast.fromJSON(JSON.stringify(e)))}export{S 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
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { ApiFunctionsBasicContext } from '../../types';
|
|
2
|
+
import type { WorkerConfig } from '../../workers/worker-config.js';
|
|
2
3
|
export type ApiRoutesWorkerParams = {
|
|
3
4
|
maxResponseSizeMB?: number;
|
|
4
5
|
slug: string;
|
|
5
6
|
requestHandlerId: string;
|
|
6
|
-
ctxData: ApiFunctionsBasicContext
|
|
7
|
+
ctxData: Omit<ApiFunctionsBasicContext, 'config'> & {
|
|
8
|
+
config: WorkerConfig;
|
|
9
|
+
};
|
|
7
10
|
staticData: Record<string, unknown>;
|
|
8
11
|
serverOutDir: string;
|
|
9
12
|
req: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { REDOCLY_ROUTE_RBAC, REDOCLY_TEAMS_RBAC, RbacScopeItems, RedirectConfig, RedoclyConfig, ServerPropsContext, ServerPropsRequest, PageProps, PageStaticData, NavItem, ResolvedNavItem, Version, MdOptions, KvService } from '@redocly/config';
|
|
2
2
|
import type { JSX } from 'react';
|
|
3
3
|
import type { JSONSchemaType } from '@redocly/ajv';
|
|
4
|
-
import type { Node } from '@
|
|
4
|
+
import type { Node } from '@redocly/markdoc';
|
|
5
5
|
import type { ProductConfig } from '@redocly/theme/config';
|
|
6
6
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
7
7
|
import type { GlobalData, Feature } from '../../../types/index.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LocationEdge } from '@
|
|
1
|
+
import type { LocationEdge } from '@redocly/markdoc';
|
|
2
2
|
import type { NormalizedLocation } from '../../plugins/markdown/errors';
|
|
3
3
|
export declare function getCodeframe(location: NormalizedLocation, color: boolean, indent?: string): {
|
|
4
4
|
frame: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LocationEdge } from '@
|
|
1
|
+
import type { LocationEdge } from '@redocly/markdoc';
|
|
2
2
|
export declare function getYamlLocationByPointer(source: string, pointer: (string | number)[], reportOnKey?: boolean): {
|
|
3
3
|
start: Required<LocationEdge>;
|
|
4
4
|
end: Required<LocationEdge>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(d){let e;try{e=decodeURIComponent(d)}catch{return}return/[\\\0]/.test(e)||e.replace(/\/$/,"").split("/").slice(1).some(t=>t===""||t==="."||t==="..")?void 0:e}export{c as decodeRequestPath};
|
|
@@ -3,10 +3,16 @@ import { z } from 'zod';
|
|
|
3
3
|
* Env vars that are set as the strings `"true"` or `"false"`, parsed to booleans.
|
|
4
4
|
* Any other value fails validation.
|
|
5
5
|
*/
|
|
6
|
-
export declare function envBooleanStringOptional(): z.
|
|
7
|
-
|
|
6
|
+
export declare function envBooleanStringOptional(): z.ZodPipe<z.ZodOptional<z.ZodEnum<{
|
|
7
|
+
false: "false";
|
|
8
|
+
true: "true";
|
|
9
|
+
}>>, z.ZodTransform<boolean | undefined, "false" | "true" | undefined>>;
|
|
10
|
+
export declare function envBooleanStringDefaultFalse(): z.ZodPipe<z.ZodDefault<z.ZodEnum<{
|
|
11
|
+
false: "false";
|
|
12
|
+
true: "true";
|
|
13
|
+
}>>, z.ZodTransform<boolean, "false" | "true">>;
|
|
8
14
|
/**
|
|
9
15
|
* Like {@link envBooleanStringOptional}, but also accepts `"1"` as true (common for `CI`).
|
|
10
16
|
*/
|
|
11
|
-
export declare function envCiBooleanOptional(): z.
|
|
17
|
+
export declare function envCiBooleanOptional(): z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"true">, z.ZodLiteral<"false">, z.ZodLiteral<"1">]>>, z.ZodTransform<boolean | undefined, "1" | "false" | "true" | undefined>>;
|
|
12
18
|
//# sourceMappingURL=env-boolean-string.d.ts.map
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare const EXCLUDED_ENV_VARS: string[];
|
|
2
|
+
/** Whether a worker may see the env variable `name`. */
|
|
3
|
+
export declare function isAllowedEnv(name: string): boolean;
|
|
2
4
|
export declare function getAllowedEnvs(): Record<string, string | undefined>;
|
|
3
5
|
//# sourceMappingURL=get-api-route-allowed-env-variables.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=["AUTH_URL","BH_API_URL","HOME","HOSTNAME","INSPECT_MODE","INTERNAL_API_USERNAME","JWT_SECRET_KEY","METRICS_API_PORT","NODE","NODE_OPTIONS","NODE_VERSION","OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","PATH","PLAN_GATES","PORTAL_ID","PWD","SERVER_EDITOR_APP_URL","SHLVL","SUBSCRIPTION_IN_TRIAL","TERM","TYPESENSE_API_URL","UV_USE_IO_URING","VAULT_TOKEN","WEB_SERVER_IDLE_TIMEOUT","YARN_VERSION","npm_config_cache","npm_config_local_prefix","npm_config_user_agent","npm_execpath","npm_node_execpath","npm_package_json","npm_package_name","npm_package_version"],n=["NOMAD_"];function T(){return Object.fromEntries(Object.entries(process.env).filter(([_])
|
|
1
|
+
const e=["AUTH_URL","BH_API_URL","HOME","HOSTNAME","INSPECT_MODE","INTERNAL_API_USERNAME","JWT_SECRET_KEY","METRICS_API_PORT","NODE","NODE_OPTIONS","NODE_VERSION","OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","PATH","PLAN_GATES","PORTAL_ID","PWD","SERVER_EDITOR_APP_URL","SHLVL","SUBSCRIPTION_IN_TRIAL","TERM","TYPESENSE_API_URL","UV_USE_IO_URING","VAULT_TOKEN","WEB_SERVER_IDLE_TIMEOUT","YARN_VERSION","npm_config_cache","npm_config_local_prefix","npm_config_user_agent","npm_execpath","npm_node_execpath","npm_package_json","npm_package_name","npm_package_version"],n=["NOMAD_"];function T(_){return!e.includes(_)&&!n.some(E=>_.startsWith(E))}function R(){return Object.fromEntries(Object.entries(process.env).filter(([_])=>T(_)))}export{e as EXCLUDED_ENV_VARS,R as getAllowedEnvs,T as isAllowedEnv};
|