@redocly/reef 0.132.0-next.5 → 0.132.0-next.7
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 +44 -0
- package/dist/cli/telemetry/index.js +1 -1
- package/dist/client/App.js +1 -1
- package/dist/client/app/CircularProgress.js +8 -8
- package/dist/client/app/hooks/utils/match-banner-target.d.ts +23 -1
- package/dist/client/app/hooks/utils/match-banner-target.js +1 -1
- package/dist/client/mcp-tool-handlers-entry.d.ts +3 -0
- package/dist/client/mcp-tool-handlers-entry.js +1 -0
- package/dist/client/templates/asyncapi-docs/helpers.d.ts +1 -1
- package/dist/client/types/ai-search.d.ts +5 -3
- 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/nodes/fence/index.js +1 -1
- package/dist/markdoc/nodes/index.d.ts +1 -1
- package/dist/markdoc/nodes/index.js +1 -1
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-schema.d.ts +6 -3
- package/dist/server/config/env-schemas/api-urls.d.ts +3 -3
- package/dist/server/config/env-schemas/api-urls.js +1 -1
- package/dist/server/config/env-schemas/auth.d.ts +3 -0
- package/dist/server/config/env-schemas/auth.js +1 -1
- package/dist/server/esbuild/esbuild.js +3 -3
- package/dist/server/esbuild/plugins/codegen/index.d.ts +1 -0
- package/dist/server/esbuild/plugins/codegen/index.js +7 -3
- package/dist/server/esbuild/plugins/mcp-tool-handlers-resolver.d.ts +7 -0
- package/dist/server/esbuild/plugins/mcp-tool-handlers-resolver.js +1 -0
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
- package/dist/server/plugins/default-theme/resolve-products-config.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/adapter-factory.d.ts +10 -3
- package/dist/server/plugins/dev-onboarding/api/adapter-factory.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/adapters/apigee/adapter.d.ts +5 -4
- package/dist/server/plugins/dev-onboarding/api/adapters/apigee/adapter.js +4 -4
- package/dist/server/plugins/dev-onboarding/api/adapters/gravitee/client.d.ts +3 -3
- package/dist/server/plugins/dev-onboarding/api/adapters/gravitee/client.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/middlewares/integrations.d.ts +3 -2
- package/dist/server/plugins/dev-onboarding/api/middlewares/integrations.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/routes/index.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/types.d.ts +8 -0
- package/dist/server/plugins/dev-onboarding/template/components/ApiLogsActions.js +5 -5
- package/dist/server/plugins/dev-onboarding/template/components/DialogStyledComponents.js +1 -1
- package/dist/server/plugins/dev-onboarding/template/components/MultiSelect.js +1 -1
- package/dist/server/plugins/dev-onboarding/template/components/TextField.js +3 -3
- package/dist/server/plugins/enforce-login/index.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/markdown/attribute-resolvers/index.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-diagram-from-file.d.ts +4 -0
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-diagram-from-file.js +1 -0
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-native-md-link.js +1 -1
- package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/render-diagrams.d.ts +16 -0
- package/dist/server/plugins/markdown/markdoc/plugins/render-diagrams.js +1 -0
- package/dist/server/plugins/markdown/runtime-transform.js +1 -1
- package/dist/server/plugins/markdown/search/to-markdown.js +24 -16
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +7 -0
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/helpers/load-api-description.d.ts +4 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/helpers/load-api-description.js +1 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +10 -7
- package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/search.d.ts +5 -10
- package/dist/server/plugins/mcp/docs-mcp/tools/search.js +3 -3
- package/dist/server/plugins/mcp/docs-mcp/tools/utils.d.ts +6 -3
- package/dist/server/plugins/mcp/docs-mcp/tools/utils.js +6 -6
- package/dist/server/plugins/mcp/docs-mcp/tools/whoami.d.ts +5 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/whoami.js +1 -1
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +13 -22
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/types.d.ts +24 -56
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +2 -2
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/openapi-docs/search-indexer.js +1 -1
- package/dist/server/store.d.ts +5 -2
- package/dist/server/store.js +1 -1
- package/dist/server/telemetry/index.js +1 -1
- package/dist/server/types/plugins/common.d.ts +15 -2
- package/dist/server/types/redirects.d.ts +6 -0
- package/dist/server/utils/rbac.js +1 -1
- package/dist/server/utils/redirects/find-redirect.d.ts +8 -31
- package/dist/server/utils/redirects/find-redirect.js +1 -1
- package/dist/server/utils/redirects/follow-redirect-chain.d.ts +9 -0
- package/dist/server/utils/redirects/follow-redirect-chain.js +1 -0
- package/dist/server/utils/redirects/validate-redirects.d.ts +8 -0
- package/dist/server/utils/redirects/validate-redirects.js +1 -0
- package/dist/server/web-server/routes/otel/otel.js +1 -1
- package/dist/server/workers/types.d.ts +2 -2
- package/dist/server/workers/worker-pool.js +1 -1
- package/dist/types/global-data.d.ts +7 -2
- package/package.json +10 -10
- package/dist/server/plugins/markdown/markdoc/plugins/render-mermaid.d.ts +0 -4
- package/dist/server/plugins/markdown/markdoc/plugins/render-mermaid.js +0 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.d.ts +0 -55
- package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +0 -1
- package/dist/server/plugins/mcp/handlers/mcp-request-handler.d.ts +0 -11
- package/dist/server/plugins/mcp/handlers/mcp-request-handler.js +0 -1
- package/dist/server/plugins/mcp/servers/base-server.d.ts +0 -17
- package/dist/server/plugins/mcp/servers/base-server.js +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{logger as n}from"../../../../../tools/notifiers/logger.js";import{ApigeeDevOnboardingIntegrationAuthType as w,APIGEE_VERSION as m}from"./types.js";import{AlgorithmTypes as
|
|
2
|
-
${await t.text()}`);const
|
|
1
|
+
import{logger as n}from"../../../../../tools/notifiers/logger.js";import{canAccessResource as S}from"../../../../../utils/rbac.js";import{ApigeeDevOnboardingIntegrationAuthType as w,APIGEE_VERSION as m}from"./types.js";import{AlgorithmTypes as b}from"../../../../../web-server/jwt/types.js";import*as T from"../../../../../web-server/jwt/jwt.js";import{getFirstNameFromClaims as U,getLastNameFromClaims as k}from"../../../utils.js";import{HttpError as $}from"../../../../../utils/errors.js";const f="developer.service.DeveloperDoesNotExist",C=3600*24*365*1;function O(s){return s.replace(/\+/g,"%2B")}function y(s){return{id:s.consumerKey,clientId:s.consumerKey,clientSecret:s.consumerSecret,scopes:s.scopes,issuedAt:s.issuedAt,expiresAt:s.expiresAt,attributes:N(s.attributes),status:s.status,apiProductsStatus:s.apiProducts?.map(e=>({id:e.apiproduct,status:e.status,name:e.apiproduct}))||[],canBeRolled:!1,canBeRevoked:!0,valueToUseInHeader:"clientId"}}function A(s){const e=Object.fromEntries((s.attributes||[]).map(t=>[t.name,t.value]));return{id:s.name,name:e.DisplayName||s.name,description:e.Notes||"",attributes:e,createdAt:s.createdAt,lastModifiedAt:s.lastModifiedAt,scopes:s.scopes,credentials:s.credentials?.map(y)||[],supportsLogs:!1,canCreateKey:!0}}function x(s){const e=Object.fromEntries((s.attributes||[]).map(t=>[t.name,t.value]));return{id:s.name,name:e.DisplayName||s.name,description:s.description,attributes:e,createdAt:s.createdAt,lastModifiedAt:s.lastModifiedAt,approvalType:s.approvalType,scopes:s.scopes}}function v(s){return Object.entries(s||{}).map(([e,t])=>({name:e,value:t}))}function N(s){return Object.fromEntries((s||[]).map(e=>[e.name,e.value]))}let h=null;async function I(s){h?(await h).expiresAt<Date.now()/1e3&&(n.info("Token expired, requesting new apigee access token"),h=P(s)):(n.info("Requesting apigee access token"),h=P(s));try{return(await h).token}catch(e){throw h=null,e}}async function P({auth:s}){switch(s.type){case w.OAUTH2:return j(s);case w.SERVICE_ACCOUNT:return _(s)}}async function j(s){const e={grant_type:"client_credentials",client_id:s.clientId,client_secret:s.clientSecret};let t=await fetch(s.tokenEndpoint,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});if(!t.ok)throw new Error(`Failed to get access token: ${t.statusText}
|
|
2
|
+
${await t.text()}`);const a=await t.json(),{access_token:i,expires_in:r}=a;return n.info("Apigee access token received"),{token:i,expiresAt:Math.floor(Date.now()/1e3)+r}}async function _(s){n.verbose(`Using service account to sign JWT token: Email: "%s" Private key:
|
|
3
3
|
%s
|
|
4
|
-
`,s.serviceAccountEmail,s.serviceAccountPrivateKey.slice(0,30)+"***"+s.serviceAccountPrivateKey.slice(-30));const t={grant_type:"urn:ietf:params:oauth:grant-type:jwt-bearer",assertion:await T.sign({sub:s.serviceAccountEmail,iss:s.serviceAccountEmail,aud:"https://www.googleapis.com/oauth2/v4/token",iat:Math.floor(Date.now()/1e3),exp:Math.floor(Date.now()/1e3)+3600,scope:"https://www.googleapis.com/auth/cloud-platform"},s.serviceAccountPrivateKey,
|
|
5
|
-
${await
|
|
4
|
+
`,s.serviceAccountEmail,s.serviceAccountPrivateKey.slice(0,30)+"***"+s.serviceAccountPrivateKey.slice(-30));const t={grant_type:"urn:ietf:params:oauth:grant-type:jwt-bearer",assertion:await T.sign({sub:s.serviceAccountEmail,iss:s.serviceAccountEmail,aud:"https://www.googleapis.com/oauth2/v4/token",iat:Math.floor(Date.now()/1e3),exp:Math.floor(Date.now()/1e3)+3600,scope:"https://www.googleapis.com/auth/cloud-platform"},s.serviceAccountPrivateKey,b.RS256)};n.verbose("Exchanging JWT for access token",s.serviceAccountEmail,s.serviceAccountPrivateKey.slice(0,30)+"***"+s.serviceAccountPrivateKey.slice(-30));let a=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(t).toString()});if(!a.ok)throw new Error(`Failed to get access token: ${a.statusText}
|
|
5
|
+
${await a.text()}`);const i=await a.json(),{access_token:r,expires_in:o}=i;return n.info("Apigee access token received"),{token:r,expiresAt:Math.floor(Date.now()/1e3)+o}}class F{apiUrl;developerUrl;accessToken=null;organizationName;email;organizationUrl;version;userClaims;config;ignoreApiProducts;catalogApiProducts;allowApiProductsOutsideCatalog;adapterId;stage;rbacConfig;constructor(e,t,a,i){const r=e;this.apiUrl=r.apiUrl||"https://apigee.googleapis.com/v1",this.organizationName=r.organizationName,this.email=a.email,this.organizationUrl=`${this.apiUrl}/organizations/${this.organizationName}`,this.developerUrl=`${this.organizationUrl}/developers/${O(this.email)}`,this.version=e.type==="APIGEE_X"?m.x:m.edge,this.userClaims=a,this.adapterId=r.organizationName,this.ignoreApiProducts=new Set(r.ignoreApiProducts||[]),this.catalogApiProducts=new Map(Object.entries(i)),this.allowApiProductsOutsideCatalog=r.allowApiProductsOutsideCatalog??!1,this.config=r,this.stage=r.stage||"non-production",this.rbacConfig=t}async setAuthHeader(e){return e=e||{},e.headers={...e.headers,"Accept-Encoding":"identity",accept:"application/json",Authorization:"Bearer "+await I(this.config),"X-Api-Key":this.config.auth.type===w.OAUTH2?this.config.auth.clientId:void 0},e}getErrorMessage(e){if(!e)return"Fetch error";try{const t=JSON.parse(e);return t.code===f?t.code:t.error.details[0]?.["@type"]==="type.googleapis.com/google.rpc.PreconditionFailure"&&t.error.details[0]?.violations[0]?.type===f?f:t?.message||t.error.message}catch{return e}}async fetchData(e,t){const a=await this.setAuthHeader(t),i=typeof e=="string"?e:e.url,r=typeof e=="string"?"GET":e.method;n.verbose(`${r.toUpperCase()} request to "${i}"`);const o=await fetch(e,a);if(!o.ok){const u=await o.text(),c=this.getErrorMessage(u);if(c===f){const p=this.userClaims,g=U(p),l=k(p),d=this.email;return await this.createDeveloper(this.email,g,l,d),await this.fetchData(e,t)}throw o.status!==404&&n.warn(`${r.toUpperCase()} request to "${i}" failed with ${o.status} code`),new $(o.status,c)}return o.headers.get("x-redocly-apigee-version")===m.x&&(this.version=m.x),n.verbose(`${r.toUpperCase()} request to "${i}" OK`),o.json()}async getApps(){const e=`${this.developerUrl}/apps?expand=true`,{app:t}=await this.fetchData(e),a=(t||[]).map(A);return{data:a,total:a.length}}async getApiProducts(){const e=`${this.organizationUrl}/apiproducts?expand=true`,{apiProduct:t}=await this.fetchData(e),a=(t||[]).filter(i=>S(this.catalogApiProducts.get(i.name)||{},this.userClaims,this.rbacConfig)&&(this.allowApiProductsOutsideCatalog||this.catalogApiProducts.has(i.name))&&!this.ignoreApiProducts.has(i.name)).map(x);return{data:a,total:a.length}}async getApp(e){const t=`${this.developerUrl}/apps/${e}${this.version===m.edge?"?expand=true":""}`,a=await this.fetchData(t);return A(a)}createDeveloper(e,t,a,i){const r=`${this.organizationUrl}/developers`;return this.fetchData(r,{headers:{"Content-type":"application/json"},body:JSON.stringify({email:e,firstName:t,lastName:a,userName:i}),method:"POST"})}async createApp(e){const t=`${this.developerUrl}/apps`;n.verbose(`Creating app ${e.id} ${e.apiProductIds}`);const a=await this.fetchData(t,{headers:{"Content-type":"application/json"},body:JSON.stringify({name:e.id,apiProducts:e.apiProductIds||[],keyExpiresIn:1*365*24*60*60*1e3,attributes:v({...e.attributes,DisplayName:e.name,Notes:e.description||""})}),method:"POST"});if(e.credentials){const i=e.credentials[0];await this.fetchData(`${this.developerUrl}/apps/${e.id}/keys/create`,{headers:{"Content-type":"application/json"},body:JSON.stringify({consumerKey:i.clientId,consumerSecret:i.clientSecret,expiresInSeconds:E(i.expiresAt,C)}),method:"POST"}),n.info("Imported previously provided key");const r=a.credentials[0].consumerKey;await this.fetchData(`${this.developerUrl}/apps/${e.id}/keys/${r}`,{method:"DELETE"}),n.info("Deleted autogenerated key");const o=await this.fetchData(`${this.developerUrl}/apps/${e.id}/keys/${i.clientId}`,{headers:{"Content-type":"application/json"},body:JSON.stringify({apiProducts:e.apiProductIds||[]}),method:"POST"});a.credentials=[o]}return A(a)}async updateApp(e,t){const a=`${this.developerUrl}/apps/${e}`;try{const i=await this.getApp(e),r={...t.attributes};t.name&&(r.DisplayName=t.name),t.description&&(r.Notes=t.description);const o=await this.fetchData(a,{headers:{"Content-type":"application/json"},body:JSON.stringify({attributes:v({...i.attributes,...r})}),method:"PUT"});return A(o)}catch(i){if(i.message.includes("does not exist"))return;throw i}}async deleteApp(e){const t=`${this.developerUrl}/apps/${e}`;try{return await this.fetchData(t,{headers:{"Content-type":"application/json"},method:"DELETE"})}catch(a){if(a.message.includes("does not exist"))return;throw a}}async createCredential(e,t){const a=`${this.developerUrl}/apps/${e}`;let i;if(t.clientId&&t.clientSecret)await this.fetchData(`${this.developerUrl}/apps/${e}/keys/create`,{headers:{"Content-type":"application/json"},body:JSON.stringify({consumerKey:t.clientId,consumerSecret:t.clientSecret,expiresInSeconds:E(t.expiresAt,C)}),method:"POST"}),i=await this.fetchData(`${this.developerUrl}/apps/${e}/keys/${t.clientId}`,{headers:{"Content-type":"application/json"},body:JSON.stringify({apiProducts:t.apiProductIds||[]}),method:"POST"}),n.info("Imported previously provided key");else{const r=await this.getApp(e);i=(await this.fetchData(a,{headers:{"Content-type":"application/json"},method:"PUT",body:JSON.stringify({apiProducts:t.apiProductIds,attributes:v({...r.attributes,...t.attributes})})})).credentials[0]}return y(i)}async updateCredential(e,t,a){let i;try{i=await this.fetchData(`${this.developerUrl}/apps/${e}/keys/${t}`)}catch{i=void 0}if(!i)throw new $(404,"Cannot update credential that does not exist");const r=`${this.developerUrl}/apps/${e}/keys/${t}`,o=await this.fetchData(r,{headers:{"Content-type":"application/json"},method:"PUT",body:JSON.stringify({apiProducts:a.apiProductIds})}),u=o.apiProducts.filter(c=>!a.apiProductIds.includes(c.apiproduct)).map(c=>c.apiproduct);return await Promise.all(u.map(c=>this.fetchData(`${this.developerUrl}/apps/${e}/keys/${t}/apiproducts/${c}`,{method:"DELETE"}))),y(o)}async deleteCredential(e,t){const a=`${this.developerUrl}/apps/${e}/keys/${t}`;return y(await this.fetchData(a,{headers:{"Content-type":"application/octet-stream"},method:"DELETE"}))}async getAppLogDetails(e,t){throw new Error("Not implemented")}async getAppLogs(e,t){return{total:0,data:[]}}async getApiAccessStatus(e,t){const{data:a}=await this.getApps(),i=(a||[]).filter(p=>(p.credentials||[]).find(l=>l.apiProductsStatus.find(d=>d.id===e))),r=p=>i.find(g=>g.credentials?.find(d=>d.status===p&&d.apiProductsStatus.find(D=>D.id===e))),o=t?i.map(p=>{if(p.credentials?.find(l=>l.status==="approved"&&l.apiProductsStatus.find(d=>d.id===e)))return{id:p.id,title:p.name}}).filter(Boolean):void 0,u=r("approved");if(u)return{status:"ACCEPTED",appId:u.id,apps:o};const c=r("pending");return c?{status:"PENDING",appId:c.id,apps:o}:{status:"NONE"}}}function E(s,e){if(!(!s&&!e))return s=s||(Date.now()+e*1e3).toString(),Math.floor((parseInt(s,10)-Date.now())/1e3).toString()}export{F as ApigeeAdapter};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Adapter, App, Paginated, Credential, ApiProduct, ExpandedApp, LogsParams, Log, CredentialInput, ApiAccessStatus, LogDetails } from '../../types';
|
|
1
|
+
import type { Adapter, App, Paginated, Credential, ApiProduct, ExpandedApp, LogsParams, Log, CredentialInput, ApiAccessStatus, LogDetails, CatalogApiProduct } from '../../types';
|
|
2
2
|
import type { GraviteeApp } from './types';
|
|
3
3
|
import type { GraviteeAdapterConfig } from '@redocly/config';
|
|
4
4
|
export declare class GraviteeAdapter implements Adapter {
|
|
@@ -9,13 +9,13 @@ export declare class GraviteeAdapter implements Adapter {
|
|
|
9
9
|
email: string;
|
|
10
10
|
};
|
|
11
11
|
config: GraviteeAdapterConfig;
|
|
12
|
-
catalogApiProducts:
|
|
12
|
+
catalogApiProducts: Map<string, CatalogApiProduct>;
|
|
13
13
|
allowApiProductsOutsideCatalog: boolean;
|
|
14
14
|
adapterId: string;
|
|
15
15
|
stage: string;
|
|
16
16
|
constructor(config: GraviteeAdapterConfig, userClaims: Record<string, string> & {
|
|
17
17
|
email: string;
|
|
18
|
-
}, accessToken: string, catalogApiProducts: string
|
|
18
|
+
}, accessToken: string, catalogApiProducts: Record<string, CatalogApiProduct>);
|
|
19
19
|
setAuthHeader(init: any): Promise<any>;
|
|
20
20
|
protected getErrorMessage(text: string): any;
|
|
21
21
|
protected fetchData<T>(input: RequestInfo, init?: RequestInit): Promise<T>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{LRUCache as w}from"lru-cache";import{randomUUID as m}from"../../../../../utils/crypto/random-uuid.js";import{HTTP_METHOD_TO_QUERY_CODE as y}from"./constants.js";const h="developer.service.DeveloperDoesNotExist";function g(r,t){return{id:r.id,name:r.name,description:r.description,attributes:{},createdAt:Date.parse(r.created_at).toString(),lastModifiedAt:Date.parse(r.updated_at).toString(),scopes:[],credentials:t||[],clientId:r.settings?.app?.client_id||r.settings?.oauth?.client_id||void 0,apiProductIds:t?.flatMap(e=>e.apiProductIds||[])||[],canCreateKey:!t?.length,supportsLogs:!0}}function E({id:r,method:t,path:e,responseTime:s,status:a,timestamp:i,api:n}){return{id:r,timestamp:i.toString(),path:e,method:t,statusCode:a,responseTime:s,apiId:n}}function P({id:r,timestamp:t,metadata:e,status:s,requestContentLength:a,responseContentLength:i,request:n,response:c,path:d}){const o=Object.values(e).find(p=>p.ip)?.ip;return{id:r,timestamp:t.toString(),path:d,ipAddress:o,statusCode:s,request:{contentLength:a,body:n?.body,headers:n?.headers||{}},response:{contentLength:i,body:c?.body,headers:c?.headers||{}}}}function D(r){if(!r.apis?.length&&!r.methods?.length&&!r.statusCodes?.length)return;const t=[];return r.apis?.length&&t.push(`api:(${r.apis.join(" OR ")})`),r.methods?.length&&t.push(`method:(${r.methods.map(e=>y[e]).join(" OR ")})`),r.statusCodes?.length&&t.push(`status:(${r.statusCodes.join(" OR ")})`),t.join(" AND ")}function b({page:r,size:t,fromDate:e,toDate:s,order:a,filters:i}){return{page:r,size:t||50,from:e||Date.now()-1e3*60*60*24*90,to:s||Date.now(),order:a||"DESC",query:D(i)}}function l(r){switch(r){case"ACCEPTED":return"approved";case"REJECTED":case"PAUSED":return"revoked";case"PENDING":case"CLOSED":return"pending";default:throw new Error(`Unknown status: ${r}`)}}function S(r){return{id:r.id,name:r.name,description:r.description,attributes:{},createdAt:r.created_at?Date.parse(r.created_at).toString():"",lastModifiedAt:r.updated_at?Date.parse(r.updated_at).toString():"",scopes:[]}}const f=new w({max:1e4});async function $(r,t){console.log("Exchanging IdP token for new Gravitee token");let e=await fetch(`${r}/auth/oauth2/gravitee-am-oidc/_exchange?token=`+t,{method:"POST",headers:{Accept:"application/json"}});if(!e.ok)throw new Error(`Failed to get access token: ${e.statusText}
|
|
2
|
-
${await e.text()}`);console.log("Exchanged successfully");const s=await e.json(),{token:a,expires_in:i=3600*48}=s;return{token:a,expiresAt:Math.floor(Date.now()/1e3)+i}}async function T(r,t,e){if(!r.auth)return;if("static"in r.auth)return r.auth?.static;if(!e)throw new Error("No access token provided");let s=f.get(e);return(!s||(await s).expiresAt<Date.now()/1e3)&&(s=$(t,e).catch(a=>{throw f.delete(e),a}),f.set(e,s)),(await s).token}class U{apiUrl;accessToken;email;userClaims;config;catalogApiProducts;allowApiProductsOutsideCatalog;adapterId="";stage="";constructor(t,e,s,a){this.config=t,this.apiUrl=`${this.config.apiBaseUrl}/portal/environments/${this.config.env||"DEFAULT"}`,this.email=e.email,this.userClaims=e,this.accessToken=s,this.stage=t.stage||"non-production",this.catalogApiProducts=new
|
|
2
|
+
${await e.text()}`);console.log("Exchanged successfully");const s=await e.json(),{token:a,expires_in:i=3600*48}=s;return{token:a,expiresAt:Math.floor(Date.now()/1e3)+i}}async function T(r,t,e){if(!r.auth)return;if("static"in r.auth)return r.auth?.static;if(!e)throw new Error("No access token provided");let s=f.get(e);return(!s||(await s).expiresAt<Date.now()/1e3)&&(s=$(t,e).catch(a=>{throw f.delete(e),a}),f.set(e,s)),(await s).token}class U{apiUrl;accessToken;email;userClaims;config;catalogApiProducts;allowApiProductsOutsideCatalog;adapterId="";stage="";constructor(t,e,s,a){this.config=t,this.apiUrl=`${this.config.apiBaseUrl}/portal/environments/${this.config.env||"DEFAULT"}`,this.email=e.email,this.userClaims=e,this.accessToken=s,this.stage=t.stage||"non-production",this.catalogApiProducts=new Map(Object.entries(a)),this.allowApiProductsOutsideCatalog=t.allowApiProductsOutsideCatalog??!1}async setAuthHeader(t){return t=t||{},t.headers={...t.headers,"Accept-Encoding":"identity",accept:"application/json",Authorization:"Bearer "+await T(this.config,this.apiUrl,this.accessToken)},t}getErrorMessage(t){if(!t)return"Fetch error";try{const e=JSON.parse(t);return e.code===h?e.code:e.error.details[0]?.["@type"]==="type.googleapis.com/google.rpc.PreconditionFailure"&&e.error.details[0]?.violations[0]?.type===h?h:e?.message||e.error.message}catch{return t}}async fetchData(t,e){const s=await this.setAuthHeader(e),a=await fetch(t,s);if(!a.ok){const i=await a.json();throw new Error(i.message||i?.errors?.[0]?.message)}return a.json()}async fetchAppCredentials(t,e=!1){const s=[],a=await this.fetchData(`${this.apiUrl}/subscriptions?applicationId=${t.id}&size=-1&statuses=ACCEPTED&statuses=PAUSED&statuses=PENDING`),i=a.data[0],n=t.api_key_mode==="SHARED"?i?[i]:[]:a.data;return await Promise.all(n.map(async c=>{const d=await this.fetchData(`${this.apiUrl}/subscriptions/${c.id}?include=keys`);d.keys?.length||(s.push({id:d.id,expiresAt:"-1",issuedAt:"-1",canBeRolled:!0,canBeRevoked:!1,clientSecret:"",attributes:{},status:l(i.status),apiProductsStatus:t.api_key_mode==="SHARED"?a.data.map(o=>({id:o.id,apiId:o.api,name:a.metadata[o.api].name,status:l(o.status)})):[{id:c.id,apiId:c.api,name:a.metadata[c.api].name,status:l(c.status)}]}),s[s.length-1].apiProductIds=s[s.length-1].apiProductsStatus.map(o=>o.apiId));for(const o of d.keys||[])o.expired||o.revoked&&!e||(s.push({id:o.key,expiresAt:o.expire_at?Date.parse(o.expire_at).toString():"-1",canBeRolled:o.expire_at==null,canBeRevoked:!1,issuedAt:Date.parse(o.created_at).toString(),clientSecret:o.key,attributes:{},status:l(i.status),apiProductsStatus:t.api_key_mode==="SHARED"?a.data.map(p=>({id:p.id,apiId:p.api,name:a.metadata[p.api].name,status:l(p.status)})):o.subscriptions.map(p=>({id:c.id,apiId:p.api,name:a.metadata[p.api].name,status:l(c.status)}))}),s[s.length-1].apiProductIds=s[s.length-1].apiProductsStatus.map(p=>p.apiId))})),s}async unsubscribeFromApis(t,e){const s=await this.getApp(t),a=[],i=await this.setAuthHeader({});return e.map(n=>{const c=s.credentials.find(u=>u.apiProductIds?.includes(n)),d=c?.apiProductIds?.findIndex(u=>u===n),o=c?.apiProductsStatus[d??-1]?.id;if(!o)throw new Error("Not found");const p=`${this.apiUrl}/subscriptions/${o}/_close`;a.push(fetch(p,{...i,method:"POST"}))}),Promise.all(a)}async subscribeToApis(t,e){return Promise.all(e.map(async s=>{const a=await this.fetchData(`${this.apiUrl}/apis/${s}/plans?size=-1`),i=a.data.find(n=>n.security==="API_KEY"&&n.validation=="AUTO")||a.data.find(n=>n.security==="API_KEY")||a.data[0];if(!i)throw new Error("No plan found");return this.fetchData(`${this.apiUrl}/subscriptions`,{headers:{"Content-type":"application/json"},body:JSON.stringify({application:t,plan:i.id,request:""}),method:"POST"})}))}async getApps(){const t=`${this.apiUrl}/applications?size=-1`,e=await this.fetchData(t),{data:s}=e,a=(s||[]).map(i=>g(i));return{data:a,total:a.length}}async getApiProducts(){const t=`${this.apiUrl}/apis?size=-1`,e=await this.fetchData(t),{data:s}=e,a=(s||[]).filter(i=>this.allowApiProductsOutsideCatalog||this.catalogApiProducts.has(i.name)).map(i=>S(i));return{data:a,total:a.length}}async getApp(t){const e=`${this.apiUrl}/applications/${t}`,s=await this.fetchData(e);let a=await this.fetchAppCredentials(s);return g(s,a)}async createApp(t){const e=`${this.apiUrl}/applications`;if(!t.apiProductIds||!t.apiProductIds.length)throw new Error("At least one API Product is required");const s=await this.fetchData(e,{headers:{"Content-type":"application/json"},body:JSON.stringify({name:t.name,description:t.description||"",domain:t.attributes?.domain||null,picture:t.attributes?.picture||null,api_key_mode:"SHARED",background:void 0,settings:{app:{type:t.attributes?.appType||"",client_id:t.attributes?.clientId||m()}}}),method:"POST"});if(await this.subscribeToApis(s.id,t.apiProductIds||[]),t.credentials)throw new Error("Gravitee adapter does not support manual credentials");return this.getApp(s.id)}async getAppLogDetails(t,e){const s=`${this.apiUrl}/applications/${t}/logs/${e}`,a=await this.fetchData(s);return P(a)}async getAppLogs(t,e){const s=new URL(`${this.apiUrl}/applications/${t}/logs`),a=b(e);Object.keys(a).forEach(n=>{a[n]&&s.searchParams.append(n,a[n])});const i=await this.fetchData(s.toString());return{total:i.metadata.data.total,data:i.data.map(E)}}async updateApp(t,e){const s=`${this.apiUrl}/applications/${t}`,a=await this.getApp(t),i=await this.fetchData(s,{headers:{"Content-type":"application/json"},body:JSON.stringify({id:t,name:e.name||a.name,description:e.description||a.description||"",domain:e.attributes?.domain||a.attributes?.domain||null,picture:e.attributes?.picture||a.attributes?.picture||null,api_key_mode:"SHARED",background:void 0,settings:{app:{type:e.attributes?.appType||a.attributes?.appType||"",client_id:e.attributes?.clientId||a.attributes?.clientId||m()}}}),method:"PUT"});return this.getApp(i.id)}async deleteApp(t){const e=`${this.apiUrl}/applications/${t}`;await this.fetchData(e,{method:"DELETE"})}async createCredential(t,e){const s=await this.getApp(t),a=new Set(e.apiProductIds.filter(c=>!(s.apiProductIds||[]).includes(c))),i=new Set((s.apiProductIds||[]).filter(c=>!e.apiProductIds.includes(c)));return await this.subscribeToApis(t,Array.from(a)),await this.unsubscribeFromApis(t,Array.from(i)),(await this.getApp(t)).credentials[0]}async updateCredential(t,e,s){if(s.apiProductIds)return this.createCredential(t,s);const a=`${this.apiUrl}/applications/${t}`,i=await this.fetchData(a);let n;if(i.api_key_mode==="SHARED")n=`${this.apiUrl}/applications/${t}/keys/_renew`;else{const p=(await this.fetchAppCredentials(i)).find(A=>A.id===e);if(!p)throw new Error("Not found!");const u=p.apiProductsStatus[0].id;n=`${this.apiUrl}/subscriptions/${u}/keys/_renew`}const c=await fetch(n,await this.setAuthHeader({method:"POST"}));if(!c.ok)throw new Error(`Failed to renew the key: ${c.statusText}`);return(await this.fetchAppCredentials(i,!0)).find(o=>o.id===e)}async deleteCredential(t,e){const s=`${this.apiUrl}/applications/${t}`,a=await this.fetchData(s);let i;if(a.api_key_mode==="SHARED")i=`${this.apiUrl}/applications/${t}/keys/${e}/_revoke`;else{const o=(await this.fetchAppCredentials(a)).find(u=>u.id===e);if(!o)throw new Error("Not found!");const p=o.apiProductsStatus[0].id;i=`${this.apiUrl}/subscriptions/${p}/keys/${e}/_revoke`}const n=await fetch(i,await this.setAuthHeader({method:"POST"}));if(!n.ok)throw new Error(`Failed to remove the key: ${n.statusText}`);return(await this.fetchAppCredentials(a,!0)).find(d=>d.id===e)}async getApiAccessStatus(t,e){const s=`${this.apiUrl}/subscriptions?apiId=${t}&size=-1&statuses=ACCEPTED&statuses=PENDING`,a=await this.fetchData(s),i=e?a.data.map(d=>{if(d.status==="ACCEPTED")return{id:d.application,title:a.metadata[d.application]?.name||d.application}}).filter(Boolean):void 0,n=a.data.find(d=>d.status==="ACCEPTED");if(n)return{status:"ACCEPTED",appId:n.application,apps:i};const c=a.data.find(d=>d.status==="PENDING");return c?{status:"PENDING",appId:c.application,apps:i}:{status:"NONE"}}}export{U as GraviteeAdapter};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Context, Next } from 'hono';
|
|
2
|
-
import type { DevOnboardingAdapterConfig } from '@redocly/config';
|
|
3
|
-
|
|
2
|
+
import type { DevOnboardingAdapterConfig, RbacConfig } from '@redocly/config';
|
|
3
|
+
import type { CatalogApiProduct } from '../types.js';
|
|
4
|
+
export declare function integrationsMiddleware(integrations: DevOnboardingAdapterConfig[], catalogApiProducts: Record<string, CatalogApiProduct>, rbacConfig: RbacConfig): (ctx: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
4
5
|
error: string;
|
|
5
6
|
}, 401, "json">) | undefined>;
|
|
6
7
|
//# sourceMappingURL=integrations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AdapterFactory as
|
|
1
|
+
import{AdapterFactory as s}from"../adapter-factory.js";import{CombineAdapter as p}from"../combine.js";const c=new s;function u(n,o,i){return async(e,d)=>{const t=e.get("auth");if(!t.isAuthenticated)return e.json({error:"Unauthorized"},401);const r=n.map(a=>c.getAdapter({config:a,catalogApiProducts:o,userClaims:t.claims,rbacConfig:i,idpAccessToken:t.idpAccessToken}));if(r.length===1)e.set("devOnboardingAdapter",r[0]);else{const a=new p(r);e.set("devOnboardingAdapter",a)}await d()}}export{u as integrationsMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{requireAuthMiddleware as
|
|
1
|
+
import{requireAuthMiddleware as t}from"../middlewares/auth.js";import{integrationsMiddleware as d}from"../middlewares/integrations.js";import{listApps as l,createApp as c,getApp as g,createCredential as n,updateCredential as o,deleteCredential as k,deleteApp as y,updateApp as A,getLogs as f,getLogDetails as m}from"./apps.js";import{getApiAccessStatus as C,listApiProducts as b}from"./products.js";function v(a,i){const p=i.getConfig().developerOnboarding?.adapters||[],e=i.getConfig().access?.rbac||{},s=i.globalData.apiProducts||{};p&&(a.get("/api/api-keys/apps",t(),d(p,s,e),l(i)),a.post("/api/api-keys/apps",t(),d(p,s,e),c(i)),a.get("/api/api-keys/apps/:id",t(),d(p,s,e),g(i)),a.put("/api/api-keys/apps/:id",t(),d(p,s,e),A(i)),a.delete("/api/api-keys/apps/:id",t(),d(p,s,e),y(i)),a.post("/api/api-keys/apps/:id/credentials",t(),d(p,s,e),n(i)),a.put("/api/api-keys/apps/:id/credentials/:credentialId",t(),d(p,s,e),o(i)),a.delete("/api/api-keys/apps/:id/credentials/:credentialId",t(),d(p,s,e),k(i)),a.get("/api/api-keys/apps/:id/logs/:logId",t(),d(p,s,e),m()),a.get("/api/api-keys/apps/:id/logs",t(),d(p,s,e),f()),a.get("/api/api-keys/api-products",t(),d(p,s,e),b(i)),a.get("/api/api-keys/api-products/:id/access",t(),d(p,s,e),C()))}export{v as installRoutes};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { REDOCLY_ROUTE_RBAC, REDOCLY_TEAMS_RBAC, RbacScopeItems } from '@redocly/config';
|
|
1
2
|
export type App = {
|
|
2
3
|
id: string;
|
|
3
4
|
name: string;
|
|
@@ -16,6 +17,13 @@ export type ExpandedApp = {
|
|
|
16
17
|
credentials: Credential[];
|
|
17
18
|
_adapterIds?: string[];
|
|
18
19
|
} & App;
|
|
20
|
+
export type CatalogApiProduct = {
|
|
21
|
+
[REDOCLY_TEAMS_RBAC]?: RbacScopeItems;
|
|
22
|
+
[REDOCLY_ROUTE_RBAC]?: {
|
|
23
|
+
slug?: string;
|
|
24
|
+
fsPath?: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
19
27
|
export type ApiProduct = {
|
|
20
28
|
id: string;
|
|
21
29
|
name: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-popup";import l from"styled-components";import{useQuery as N}from"@tanstack/react-query";import{DateTimeRangePicker as R}from"@wojtekmaj/react-datetimerange-picker";import"@wojtekmaj/react-datetimerange-picker/dist/DateTimeRangePicker.css";import{fetch as S}from"../../../../../client/app/utils";import{PopupMenuUl as I}from"./PopupMenuUl";const A=[{name:"OTHER",id:"OTHER"},{name:"CONNECT",id:"CONNECT"},{name:"DELETE",id:"DELETE"},{name:"GET",id:"GET"},{name:"HEAD",id:"HEAD"},{name:"OPTIONS",id:"OPTIONS"},{name:"PATCH",id:"PATCH"},{name:"POST",id:"POST"},{name:"PUT",id:"PUT"},{name:"TRACE",id:"TRACE"}],y=[{type:"predefined",name:"last 5m",fromDateOffset:1e3*60*5},{type:"predefined",name:"last 1h",fromDateOffset:1e3*60*60},{type:"predefined",name:"last 3h",fromDateOffset:1e3*60*60*3},{type:"predefined",name:"last 12h",fromDateOffset:1e3*60*60*12},{type:"predefined",name:"last 1d",fromDateOffset:1e3*60*60*24},{type:"predefined",name:"last 3d",fromDateOffset:1e3*60*60*24*3},{type:"predefined",name:"last 7d",fromDateOffset:1e3*60*60*24*7},{type:"predefined",name:"last 30d",fromDateOffset:1e3*60*60*24*30}],P=[{name:"100 CONTINUE",id:"100"},{name:"101 SWITCHING PROTOCOLS",id:"101"},{name:"102 PROCESSING",id:"102"},{name:"200 OK",id:"200"},{name:"201 CREATED",id:"201"},{name:"202 ACCEPTED",id:"202"},{name:"203 NON AUTHORITATIVE INFORMATION",id:"203"},{name:"204 NO CONTENT",id:"204"},{name:"205 RESET CONTENT",id:"205"},{name:"206 PARTIAL CONTENT",id:"206"},{name:"207 MULTI STATUS",id:"207"},{name:"300 MULTIPLE CHOICES",id:"300"},{name:"301 MOVED PERMANENTLY",id:"301"},{name:"302 FOUND",id:"302"},{name:"303 SEE OTHER",id:"303"},{name:"304 NOT MODIFIED",id:"304"},{name:"305 USE PROXY",id:"305"},{name:"307 TEMPORARY REDIRECT",id:"307"},{name:"400 BAD REQUEST",id:"400"},{name:"401 UNAUTHORIZED",id:"401"},{name:"402 PAYMENT REQUIRED",id:"402"},{name:"403 FORBIDDEN",id:"403"},{name:"404 NOT FOUND",id:"404"},{name:"405 METHOD NOT ALLOWED",id:"405"},{name:"406 NOT ACCEPTABLE",id:"406"},{name:"407 PROXY AUTHENTICATION REQUIRED",id:"407"},{name:"408 REQUEST TIMEOUT",id:"408"},{name:"409 CONFLICT",id:"409"},{name:"410 GONE",id:"410"},{name:"411 LENGTH REQUIRED",id:"411"},{name:"412 PRECONDITION FAILED",id:"412"},{name:"413 REQUEST ENTITY TOO LARGE",id:"413"},{name:"414 REQUEST URI TOO LONG",id:"414"},{name:"415 UNSUPPORTED MEDIA TYPE",id:"415"},{name:"416 REQUESTED RANGE NOT SATISFIABLE",id:"416"},{name:"417 EXPECTATION FAILED",id:"417"},{name:"422 UNPROCESSABLE ENTITY",id:"422"},{name:"423 LOCKED",id:"423"},{name:"424 FAILED DEPENDENCY",id:"424"},{name:"429 TOO MANY REQUESTS",id:"429"},{name:"500 INTERNAL SERVER ERROR",id:"500"},{name:"501 NOT IMPLEMENTED",id:"501"},{name:"502 BAD GATEWAY",id:"502"},{name:"503 SERVICE UNAVAILABLE",id:"503"},{name:"504 GATEWAY TIMEOUT",id:"504"},{name:"505 HTTP VERSION NOT SUPPORTED",id:"505"},{name:"507 INSUFFICIENT STORAGE",id:"507"}];function x(e){return n.createElement(L,null,n.createElement(w,{onFiltersChange:e.onFiltersChange,activeFilters:e.activeFilters}),n.createElement(U,null))}var j=n.memo(x);const U=()=>null,w=n.memo(e=>{const{onFiltersChange:d,activeFilters:t}=e,{data:i}=N({queryKey:["API-PRODUCTS"],queryFn:()=>S("/api/api-keys/api-products").then(o=>o.json())}),[s,r]=O(),a=()=>r(void 0),m=(o,g)=>{const T={...t,[o]:g};d(T)};return n.createElement(h,{trigger:n.createElement(k,null,"Filter"),position:"bottom right"},n.createElement(
|
|
1
|
+
import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-popup";import l from"styled-components";import{useQuery as N}from"@tanstack/react-query";import{DateTimeRangePicker as R}from"@wojtekmaj/react-datetimerange-picker";import"@wojtekmaj/react-datetimerange-picker/dist/DateTimeRangePicker.css";import{fetch as S}from"../../../../../client/app/utils";import{PopupMenuUl as I}from"./PopupMenuUl";const A=[{name:"OTHER",id:"OTHER"},{name:"CONNECT",id:"CONNECT"},{name:"DELETE",id:"DELETE"},{name:"GET",id:"GET"},{name:"HEAD",id:"HEAD"},{name:"OPTIONS",id:"OPTIONS"},{name:"PATCH",id:"PATCH"},{name:"POST",id:"POST"},{name:"PUT",id:"PUT"},{name:"TRACE",id:"TRACE"}],y=[{type:"predefined",name:"last 5m",fromDateOffset:1e3*60*5},{type:"predefined",name:"last 1h",fromDateOffset:1e3*60*60},{type:"predefined",name:"last 3h",fromDateOffset:1e3*60*60*3},{type:"predefined",name:"last 12h",fromDateOffset:1e3*60*60*12},{type:"predefined",name:"last 1d",fromDateOffset:1e3*60*60*24},{type:"predefined",name:"last 3d",fromDateOffset:1e3*60*60*24*3},{type:"predefined",name:"last 7d",fromDateOffset:1e3*60*60*24*7},{type:"predefined",name:"last 30d",fromDateOffset:1e3*60*60*24*30}],P=[{name:"100 CONTINUE",id:"100"},{name:"101 SWITCHING PROTOCOLS",id:"101"},{name:"102 PROCESSING",id:"102"},{name:"200 OK",id:"200"},{name:"201 CREATED",id:"201"},{name:"202 ACCEPTED",id:"202"},{name:"203 NON AUTHORITATIVE INFORMATION",id:"203"},{name:"204 NO CONTENT",id:"204"},{name:"205 RESET CONTENT",id:"205"},{name:"206 PARTIAL CONTENT",id:"206"},{name:"207 MULTI STATUS",id:"207"},{name:"300 MULTIPLE CHOICES",id:"300"},{name:"301 MOVED PERMANENTLY",id:"301"},{name:"302 FOUND",id:"302"},{name:"303 SEE OTHER",id:"303"},{name:"304 NOT MODIFIED",id:"304"},{name:"305 USE PROXY",id:"305"},{name:"307 TEMPORARY REDIRECT",id:"307"},{name:"400 BAD REQUEST",id:"400"},{name:"401 UNAUTHORIZED",id:"401"},{name:"402 PAYMENT REQUIRED",id:"402"},{name:"403 FORBIDDEN",id:"403"},{name:"404 NOT FOUND",id:"404"},{name:"405 METHOD NOT ALLOWED",id:"405"},{name:"406 NOT ACCEPTABLE",id:"406"},{name:"407 PROXY AUTHENTICATION REQUIRED",id:"407"},{name:"408 REQUEST TIMEOUT",id:"408"},{name:"409 CONFLICT",id:"409"},{name:"410 GONE",id:"410"},{name:"411 LENGTH REQUIRED",id:"411"},{name:"412 PRECONDITION FAILED",id:"412"},{name:"413 REQUEST ENTITY TOO LARGE",id:"413"},{name:"414 REQUEST URI TOO LONG",id:"414"},{name:"415 UNSUPPORTED MEDIA TYPE",id:"415"},{name:"416 REQUESTED RANGE NOT SATISFIABLE",id:"416"},{name:"417 EXPECTATION FAILED",id:"417"},{name:"422 UNPROCESSABLE ENTITY",id:"422"},{name:"423 LOCKED",id:"423"},{name:"424 FAILED DEPENDENCY",id:"424"},{name:"429 TOO MANY REQUESTS",id:"429"},{name:"500 INTERNAL SERVER ERROR",id:"500"},{name:"501 NOT IMPLEMENTED",id:"501"},{name:"502 BAD GATEWAY",id:"502"},{name:"503 SERVICE UNAVAILABLE",id:"503"},{name:"504 GATEWAY TIMEOUT",id:"504"},{name:"505 HTTP VERSION NOT SUPPORTED",id:"505"},{name:"507 INSUFFICIENT STORAGE",id:"507"}];function x(e){return n.createElement(L,null,n.createElement(w,{onFiltersChange:e.onFiltersChange,activeFilters:e.activeFilters}),n.createElement(U,null))}var j=n.memo(x);const U=()=>null,w=n.memo(e=>{const{onFiltersChange:d,activeFilters:t}=e,{data:i}=N({queryKey:["API-PRODUCTS"],queryFn:()=>S("/api/api-keys/api-products").then(o=>o.json())}),[s,r]=O(),a=()=>r(void 0),m=(o,g)=>{const T={...t,[o]:g};d(T)};return n.createElement(h,{trigger:n.createElement(k,null,"Filter"),position:"bottom right"},n.createElement(b,null,n.createElement(E,{open:s==="api",name:"API name",options:i||[],activeOptions:t.api,onOpen:()=>r("api"),onClose:a,onChange:o=>m("api",o),active:(t.api?.length??0)>0}),n.createElement(E,{open:s==="status",name:"Status",options:P,activeOptions:t.status,onOpen:()=>r("status"),onClose:a,onChange:o=>m("status",o),active:(t.status?.length??0)>0}),n.createElement(E,{open:s==="method",name:"Method",options:A,activeOptions:t.method,onOpen:()=>r("method"),onClose:a,onChange:o=>m("method",o),active:(t.method?.length??0)>0}),n.createElement(E,{name:"Date range",open:s==="date",onOpen:()=>r("date"),onClose:a,active:!!t.date,renderSubmenu:()=>n.createElement(M,{onChange:o=>m("date",o),selectedDateFilter:t.date})}),n.createElement(_,null),n.createElement(H,{onClick:()=>d({})},"Clear filters")))}),M=e=>{const{selectedDateFilter:d,onChange:t}=e,i=d?.type==="custom",[s,r]=O(!1),[a,m]=O([null,null]),o=a?.[0]?a[0]:null,g=a?.[1]?a[1]:null,T=()=>{if(!a?.[0]&&!a?.[1])return t();const c=a[1]||new Date,p=a[0]||new Date(c.getDate()-1e3*60*60*24);r(!1),t({type:"custom",fromDate:p.getTime(),toDate:c.getTime()})};return n.createElement(v,{onMouseDown:u,onTouchStart:u},n.createElement(E,{open:s,active:i,name:"Custom range",onOpen:()=>r(!0),onClose:()=>r(!1),renderSubmenu:()=>n.createElement(F,null,n.createElement(Y,{onClick:T},"Submit"),n.createElement(_,null),n.createElement(R,{isCalendarOpen:!0,format:"yyyy-MM-dd HH:mm",closeWidgets:!1,dayPlaceholder:"DD",monthPlaceholder:"MM",yearPlaceholder:"YYYY",hourPlaceholder:"HH",minutePlaceholder:"mm",disableClock:!0,value:[o,g],onChange:c=>m(c)}))}),y.map(c=>{const p=d?.type==="predefined"&&d.name===c.name;return n.createElement(f,{active:p,key:c.name,onClick:C=>{u(C),t(p?void 0:c)}},c.name)}))},E=e=>{const d=e.activeOptions||[],t=D(()=>new Set(d.map(i=>i.id)),[e.activeOptions]);return n.createElement(h,{open:e.open,onOpen:e.onOpen,onClose:e.onClose,trigger:n.createElement(f,{active:e.active||e.open},e.name),position:"left top",arrow:!1},e.options?n.createElement(v,{onMouseDown:u,onTouchStart:u},e.options?.map(i=>n.createElement(f,{active:t.has(i.id),key:i.id,onClick:s=>{if(e.onChange)if(u(s),t.has(i.id)){const r=[...d],a=r.findIndex(m=>m.id===i.id);r.splice(a,1),e.onChange(r)}else e.onChange([...d,i])}},i.name))):null,e.renderSubmenu?e.renderSubmenu():null)},u=e=>{e.stopPropagation()},k=l.div`
|
|
2
2
|
color: var(--text-color-primary);
|
|
3
3
|
border-radius: var(--border-radius);
|
|
4
4
|
cursor: pointer;
|
|
@@ -14,7 +14,7 @@ import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-
|
|
|
14
14
|
`,L=l.div`
|
|
15
15
|
display: flex;
|
|
16
16
|
gap: var(--spacing-xxs);
|
|
17
|
-
`,
|
|
17
|
+
`,b=l(I)`
|
|
18
18
|
padding: var(--spacing-xs);
|
|
19
19
|
width: 288px;
|
|
20
20
|
li {
|
|
@@ -32,7 +32,7 @@ import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-
|
|
|
32
32
|
margin-bottom: 2px;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
`,v=l(
|
|
35
|
+
`,v=l(b)`
|
|
36
36
|
max-height: 200px;
|
|
37
37
|
overflow-y: scroll;
|
|
38
38
|
&::-webkit-scrollbar {
|
|
@@ -96,7 +96,7 @@ import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
.react-calendar__tile--now {
|
|
99
|
-
color: var(--color-primary-base);
|
|
99
|
+
color: var(--color-primary-base, var(--color-blueberry-6));
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
.react-datetimerange-picker__inputGroup__input:invalid {
|
|
@@ -146,7 +146,7 @@ import n,{useMemo as D,useState as O}from"react";import{Popup as h}from"reactjs-
|
|
|
146
146
|
font-size: var(--font-size-lg);
|
|
147
147
|
text-align: center;
|
|
148
148
|
margin: 0 var(--spacing-xs);
|
|
149
|
-
`,
|
|
149
|
+
`,_=l.div`
|
|
150
150
|
margin: var(--spacing-xs);
|
|
151
151
|
width: auto;
|
|
152
152
|
min-width: auto;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import i from"react";import c from"react-select";import{useTranslate as d}from"../../../../../client/app/hooks";const
|
|
1
|
+
import i from"react";import c from"react-select";import{useTranslate as d}from"../../../../../client/app/hooks";const v=function(r){const{options:o,defaultValue:e,onChange:a}=r,{translate:l}=d();return i.createElement(c,{isMulti:!0,defaultValue:e,options:o,closeMenuOnSelect:!1,styles:p,placeholder:l("dev.select.placeholder","Empty"),onChange:t=>{a(t.map(n=>n.value))}})},p={control:r=>({...r,border:"1px solid var(--border-color-primary)",boxShadow:"none",backgroundColor:"var(--bg-color-raised)","&:hover":{borderColor:"var(--color-primary-base, var(--color-blueberry-6))",cursor:"pointer"}}),placeholder:r=>({...r,color:"var(--input-content-placeholder-color)",fontSize:"var(--font-size-lg)"}),indicatorsContainer:()=>({display:"none"}),menu:r=>({...r,padding:"var(--spacing-xxs)",margin:"0",boxShadow:"var(--bg-raised-shadow)",border:"1px solid var(--border-color-primary)",backgroundColor:"var(--bg-color)"}),menuList:r=>({...r,paddingBottom:0,paddingTop:0}),option:r=>({...r,cursor:"pointer",borderRadius:"4px",color:"var(--text-color-primary)",backgroundColor:"transparent",fontSize:"14px","&:hover":{backgroundColor:"var(--bg-color-hover)"}}),multiValue:r=>({...r,backgroundColor:"var(--bg-color-raised)",color:"var(--text-color-primary)",border:"1px solid var(--border-color-primary)",borderRadius:"32px",height:"32px",alignItems:"center"}),multiValueLabel:r=>({...r,fontSize:"14px",color:"var(--text-color-primary)",paddingLeft:"var(--spacing-sm)"}),valueContainer:r=>({...r,padding:"6px 8px"}),multiValueRemove:r=>({...r,padding:0,margin:"0 var(--spacing-xxs)","&:hover":{backgroundColor:"var(--bg-color-raised)",color:"var(--text-color-secondary)"}})};export{v as MultiSelect};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as e from"react";import o from"styled-components";function i(r){return e.createElement(t,null,r.label?e.createElement("span",null,r.label):null,e.createElement(l,{...r.inputProps}))}const l=o.input`
|
|
2
2
|
border: 1px solid var(--border-color-primary);
|
|
3
3
|
padding: var(--spacing-sm);
|
|
4
4
|
border-radius: var(--border-radius);
|
|
5
5
|
width: 100%;
|
|
6
6
|
height: 48px;
|
|
7
7
|
display: block;
|
|
8
|
-
outline-color: var(--color-primary-base);
|
|
8
|
+
outline-color: var(--color-primary-base, var(--color-blueberry-6));
|
|
9
9
|
transition: outline 0.25s ease;
|
|
10
|
-
`,
|
|
10
|
+
`,t=o.label`
|
|
11
11
|
color: var(--text-color-primary);
|
|
12
12
|
span {
|
|
13
13
|
font-size: 0.9em;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as
|
|
1
|
+
import{envConfig as r}from"../../config/env-config.js";async function f(c){return{id:"enforce-login",async processContent(o){const i=!!r.REDOCLY_ENFORCE_RESIDENCY,n=r.REDOCLY_ENFORCE_LOGIN==="true";if(!i&&!n)return;const e=o.getConfig();o.setGlobalConfig({...n&&"rbac"in e&&{rbac:void 0},...n&&"requiresLogin"in e&&{requiresLogin:void 0},...i&&"residency"in e&&{residency:void 0},access:{...e.access,...i&&{residency:r.REDOCLY_ENFORCE_RESIDENCY},...n&&{requiresLogin:!0,rbac:void 0}}})}}}export{f as enforceLoginPlugin};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import x from"@redocly/portal-plugin-mock-server";import B from"path";import{REDOCLY_ROUTE_RBAC as O}from"@redocly/config";import{combineUrls as v,withPathPrefix as N}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as L}from"../constants/common.js";import{removeTrailingSlash as F}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as
|
|
2
|
-
`+s.stack;
|
|
1
|
+
import x from"@redocly/portal-plugin-mock-server";import B from"path";import{REDOCLY_ROUTE_RBAC as O}from"@redocly/config";import{combineUrls as v,withPathPrefix as N}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as L}from"../constants/common.js";import{removeTrailingSlash as F}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as k}from"../../utils/url/remove-leading-slash.js";import{isTruthy as V}from"../../utils/guards/is-truthy.js";import{normalizeRouteSlug as T}from"../../utils/path/normalize-route-slug.js";import{slash as j}from"../../utils/path/slash.js";import{parsePathVersions as $}from"../../utils/path/parse-path-versions.js";import{reporter as E}from"../tools/notifiers/reporter.js";import{logger as P}from"../tools/notifiers/logger.js";import{envConfig as A}from"../config/env-config.js";import{shaDirPathShort as z}from"../utils/crypto/sha-dir-path-short.js";import{customPagesPlugin as M}from"../../server/plugins/pages/index.js";import{openAPIDocsPlugin as q}from"../../server/plugins/openapi-docs/index.js";import{asyncAPIDocsPlugin as I}from"../../server/plugins/asyncapi-docs/index.js";import{configParserPlugin as U}from"./config-parser/index.js";import{markdownPlugin as G}from"./markdown/index.js";import{generateBrowserPluginsModule as W,generateClientRoutes as K,generateTemplatesModule as H}from"../esbuild/generate.js";import{graphqlDocsPlugin as Y}from"./graphql-docs/index.js";import{searchPlugin as J}from"./search/index.js";import{defaultThemePlugin as Q}from"./default-theme/index.js";import{apiKeyMgmtPlugin as X}from"./dev-onboarding/index.js";import{apiFunctionsPlugin as Z}from"./api-functions/index.js";import{scorecardClassicPlugin as ee}from"./scorecard-classic/index.js";import{lintPlugin as te}from"./lint/index.js";import{resolveExternalPlugins as oe}from"../external-plugins/resolve-external-plugins.js";import{sidebarsPlugin as ie}from"./sidebars/index.js";import{l10nPlugin as ne}from"./l10n/index.js";import{validateRedirects as re}from"../utils/redirects/validate-redirects.js";import{analyticsPlugins as se}from"./analytics/index.js";import{sitemapPlugin as ae}from"./sitemap/index.js";import{entitlementsPlugin as le}from"./entitlements/index.js";import{getBilledPagesCount as ce,slug as ue}from"../utils/index.js";import{telemetry as fe}from"../../cli/telemetry/index.js";import{telemetryTraceStep as b}from"../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as D}from"../entitlements/entitlements-provider.js";import{enforceLoginPlugin as me}from"./enforce-login/index.js";import{ssoPlugin as de}from"./sso/index.js";import{Cache as ge}from"../fs/cache.js";import{ContentFs as pe}from"../fs/content-fs.js";import{findProductBySlug as Pe}from"../utils/product.js";import{parseBaseName as he}from"./utils.js";import{isRouteReserved as ye}from"./get-reserved-routes.js";import{catalogClassicPlugin as Ce}from"./catalog-classic/index.js";import{arazzoDocsPlugin as we}from"./arazzo-docs/index.js";const Re=[U,me,de,Q,ne,G,q,I,we,ee,te,Z,M,Y,X,Ce,{importPath:"./catalog-entities/plugin.js",loadCondition:()=>A.NEW_CATALOG_ENABLED==="true"},{importPath:"./scorecards/plugin.js",loadCondition:()=>A.NEW_SCORECARDS_ENABLED==="true"},{importPath:"./mcp/index.js",loadCondition:()=>D.instance().canAccessFeature("mcp")},ie,ae,le,J,x,...se];async function Ct(o,t=Re){return await b("build.plugins_init",async()=>{const n=[],w=D.instance(),h={};for(const f of t){let a;if("loadCondition"in f){if(!f.loadCondition())continue;const e=await import(f.importPath);if(!e.default||typeof e.default!="function"){await E.panicOnBuild(`Dynamic plugin ${f.importPath} does not export a default export or it is not a function`);continue}a=e.default}else a=f;const d=await a(o);for(const[e,i]of Object.entries(d.loaders||{}))h[e]&&await E.panicOnBuild(`Duplicate loader with name ${e}`),h[e]=i;(!d.requiredEntitlements||d.requiredEntitlements?.every(e=>w.canAccessFeature(e)))&&n.push(d)}const s=new pe(o.contentDir);await s.ready;const u=new ge(s);return u.setLoaders(h),P.verbose("All plugins instantiated"),{pluginInstances:n,lifecycleContext:be(s,u)}})}function _(o){P.verbose("Generating templates"),b("build.write_client_entries",()=>{H(o),W(o),K(o)})}async function ve(o){const t=o.getAllRoutes();ce(t)||await E.panicOnBuild("No routes created by plugins. Please check your project configuration.")}async function wt(o,t,n,w={}){const h=D.instance();try{await b("build.plugins_run",async()=>{t.startPluginsRun();let s=[];await b("build.plugins_process_content",async a=>{for(const e of o){const i=P.startTiming();await e.processContent?.(t,n),P.verboseTime(i,`processContent for ${e.id}`)}s=(await oe(t.contentDir,t.config.plugins)).map(e=>e.lifecyclePlugin).filter(e=>V(e)&&(!e.requiredEntitlements||e.requiredEntitlements?.every(i=>h.canAccessFeature(i)))),n.cache.setLoaders(Object.fromEntries(s.flatMap(e=>Object.entries(e.loaders||{}))));for(const e of s){const i=P.startTiming();await e.processContent?.(t,n),P.verboseTime(i,`processContent for ${e.id}`)}a?.setAttribute("externalPluginsProcessed",s.length.toString())});const u=await Ee(t,n),f=[...o,...s];_(t),A.isDevelopMode?await t.userCodeReady:t.buildRevision++,await b("build.plugins_after_routes_created",async()=>{for(const a of f){const d=P.startTiming();await a.afterRoutesCreated?.(t,u),P.verboseTime(d,`afterRoutesCreated for ${a.id}`)}}),re(t),await t.reportUnsetEnvVars(),await ve(t),_(t)})}catch(s){const u="Unhandled error in plugin. "+s.message+`
|
|
2
|
+
`+s.stack;fe.sendCliErrorCaughtMessage({message:u}),w.failFast?await E.panic(u):await E.panicOnBuild(u)}finally{t.finishPluginsRun()}}async function Ee(o,t){const{cache:n,fs:w}=t,h=await t.getConfig(),s=Object.values(h.products||{}),u=(await n.load("versions-config","versions-config")).data,f=(await n.load("content-slugs","content-slugs")).data;for(const{duplicateInAllLocales:e,slugSuffix:i,sharedData:y=[],redirectFrom:C=[],...l}of o.newRoutes){const c=T(l.slug?l.slug:a(l.fsPath)),g=F(i?v(c,i):c),r={...l,[O]:{slug:g,fsPath:l.fsPath},slug:g,baseSlug:c,versions:d(l.fsPath,i),product:Pe(s,g,a)};ye(g,h)&&await E.panicOnBuildContentError(`Route "${g}" is reserved and cannot be used. Please choose a different slug for "${l.fsPath}".`),o.routesByFsPath.set(r.fsPath,r.slug),o.routesBySlug.set(r.slug,r);for(const{key:p,id:m}of y)o.addRouteSharedData(r.slug,p,m);for(const p of C)o.addRedirect(p.from,{type:p.type,to:r.slug});if(e)for(const p of w.localeFolders){const m={...r,slug:"/"+p.toLowerCase()+r.slug};o.routesByFsPath.set(m.fsPath,m.slug),o.routesBySlug.set(m.slug,m);for(const{key:R,id:S}of y)o.addRouteSharedData(m.slug,R,S);for(const R of C){const S=v(w.localizationFolder,p,R.from);o.addRedirect(S,{type:R.type,to:m.slug},{trackOriginalSource:!1})}}}return o.newRoutes=[],{...t,slugify:a};function a(e){const i=j(e).replace(new RegExp("^(@i18n|@l10n)\\/"),""),y=f.fileSlugs.get(i)||f.dirSlugs.get(F(i));if(y)return y;const{baseName:C,isIndexFile:l}=he(e);let c=B.dirname(e.replace(new RegExp("^(@i18n|@l10n)\\/"),""));return c=c==="."?"/":c,v("/",ue(l?c:v(c,C)),"/")}function d(e,i=""){const y=$(e);if(!y?.versionName)return;const{versionFolderPath:C,filePathInVersion:l,versionName:c}=y,g=u.get(C);if(g)return g.versions.map(r=>{const p=g.defaultVersion===r.version,m=k(v(C,L+r.version,l)),R=a(m);return{version:r.version,label:r.name||r.version,link:T(v(R,i)),default:p,active:c===r.version,folderId:z(`${C}`)}})}}function be(o,t){return{fs:o,cache:t,getConfig:async(n=".")=>(await t.load(n,"nearest-redocly-config",o.localeFolders)).data,isPathIgnored:async n=>(await t.load(n,"is-ignored")).data,withPathPrefix:N,logger:P}}export{Re as INTERNAL_PLUGINS,be as createLifecycleContext,Ct as initPlugins,wt as runPlugins,_ as writeClientEntries};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveOpenApiRef as e}from"./resolve-open-api-ref.js";import{resolveJsonSchemaRef as o}from"./resolve-json-schema-ref.js";import{resolveParsedYaml as r}from"./resolve-parsed-yaml.js";import{resolveRawContent as m}from"./resolve-raw-content.js";import{resolveSvgContent as t}from"./resolve-svg-content.js";import{resolveRelativePath as i}from"./resolve-relative-path.js";import{resolveLink as l}from"./resolve-link.js";import{resolveNativeMdLink as s}from"./resolve-native-md-link.js";import{resolveCodeSnippetFromFile as a}from"./resolve-code-snippet-from-file.js";import{
|
|
1
|
+
import{resolveOpenApiRef as e}from"./resolve-open-api-ref.js";import{resolveJsonSchemaRef as o}from"./resolve-json-schema-ref.js";import{resolveParsedYaml as r}from"./resolve-parsed-yaml.js";import{resolveRawContent as m}from"./resolve-raw-content.js";import{resolveSvgContent as t}from"./resolve-svg-content.js";import{resolveRelativePath as i}from"./resolve-relative-path.js";import{resolveLink as l}from"./resolve-link.js";import{resolveNativeMdLink as s}from"./resolve-native-md-link.js";import{resolveCodeSnippetFromFile as a}from"./resolve-code-snippet-from-file.js";import{resolveDiagramFromFile as p}from"./resolve-diagram-from-file.js";import{resolveHtmlSourceAttribute as n}from"./resolve-html-source-attribute.js";import{resolveHtmlHref as v}from"./resolve-html-href.js";import{resolveImageSrc as f}from"./resolve-image-src.js";import{resolveImageSrcSet as S}from"./resolve-image-src-set.js";import{resolveNavLinks as c}from"./resolve-nav-links.js";import{resolveRelativeOrCdnIcon as h}from"./resolve-relative-or-cdn-icon.js";import{resolveCodeWalkthroughFilesets as d}from"./code-walkthrough/filesets-resolver.js";import{resolveJsonExampleRef as g}from"./resolve-json-example-ref.js";import{resolveSampleFromJsonSchema as F}from"./resolve-sample-from-json-schema.js";const Y={openapiRef:e,jsonSchemaRef:o,parsedYaml:r,rawContent:m,svgContent:t,relativePath:i,link:l,nativeMdLink:s,codeSnippetFile:a,diagramFile:p,htmlSourceAttribute:n,htmlHref:v,imageSrc:f,imageSrcSet:S,navLinks:c,relativeOrCdnIcon:h,codeWalkthroughFilesets:d,jsonExampleRef:g,sampleFromJsonSchema:F};export{Y as attributeResolvers};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Node } from '@markdoc/markdoc';
|
|
2
|
+
import type { MarkdocResolveContext, WithOriginalAttr } from '../../../types';
|
|
3
|
+
export declare function resolveDiagramFromFile(node: WithOriginalAttr<Node>, attributeName: string, pageRelativePath: string, { actions: { contentDir }, context }: MarkdocResolveContext): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=resolve-diagram-from-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import a from"node:path";import{slash as f}from"../../../../utils/path/slash.js";import{reporter as l}from"../../../tools/notifiers/reporter.js";import{getNodeAttribute as p}from"../../../../markdoc/helpers/get-node-attribute.js";async function h(t,s,m,{actions:{contentDir:e},context:o}){const r=p(t,s);if(!r)return;const i=r.startsWith("/")?r.slice(1):f(a.relative(e,a.resolve(e,a.dirname(m),r)));if(!o.fs.exists(i)){await l.panicOnBuildContentError(`Diagram file ${i} does not exist`);return}const n=await o.fs.read(i);t.children=[],t.attributes.rawContent=n}export{h as resolveDiagramFromFile};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPathPrefix as s,withPathPrefix as n}from"@redocly/theme/core/utils";import{isLocalLink as m}from"../../../../utils/path/is-local-link.js";import{getNodeAttribute as
|
|
1
|
+
import{getPathPrefix as s,withPathPrefix as n}from"@redocly/theme/core/utils";import{isLocalLink as m}from"../../../../utils/path/is-local-link.js";import{getNodeAttribute as p}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as a}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{resolveLink as l}from"./resolve-link.js";async function v(r,i,o,f){if(await l(r,i,o,f),r.type==="link")return;const e=s();if(!e)return;const t=p(r,i);!t||t==="#"||!m(t)||t.startsWith(e)||a(r,i,t.startsWith("#")?t:n(t))}export{v as resolveNativeMdLink};
|
|
@@ -100,8 +100,8 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
|
|
|
100
100
|
description?: string;
|
|
101
101
|
};
|
|
102
102
|
link: {
|
|
103
|
+
render: string;
|
|
103
104
|
children: string[];
|
|
104
|
-
render?: string | undefined;
|
|
105
105
|
attributes?: Record<string, import("@markdoc/markdoc").SchemaAttribute>;
|
|
106
106
|
slots?: Record<string, import("@markdoc/markdoc").SchemaSlot>;
|
|
107
107
|
selfClosing?: boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type DiagramInput = {
|
|
2
|
+
type: DiagramType;
|
|
3
|
+
source: string;
|
|
4
|
+
};
|
|
5
|
+
type DiagramType = 'mermaid' | 'excalidraw' | 'plantuml';
|
|
6
|
+
type DiagramHtmlVariants = {
|
|
7
|
+
light: string;
|
|
8
|
+
dark: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const cache: Record<string, DiagramHtmlVariants>;
|
|
12
|
+
export declare function generateDiagramHash(source: string, type?: DiagramType): string;
|
|
13
|
+
export declare function renderDiagramsWithVariants(diagrams: DiagramInput[]): Promise<DiagramHtmlVariants[]>;
|
|
14
|
+
export declare function renderDiagrams(diagrams: DiagramInput[], theme?: string): Promise<string[]>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=render-diagrams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{nanoid as w}from"nanoid";import{envConfig as l}from"../../../../config/env-config.js";import{logger as m}from"../../../../tools/notifiers/logger.js";import{sha as I}from"../../../../utils/crypto/sha.js";const u={};function g(r,n="mermaid"){const s=`${n}:${r}`;if(n==="mermaid"&&r.toLowerCase().includes("gantt")&&!r.toLowerCase().includes("todaymarker off")){const t=new Date().toISOString().split("T")[0];return I(s+t)}return I(s)}function y(){return l.REDOCLY_DIAGRAM_MICROSERVICE_URL||"https://tools.redocly.com/diagram-renders"}function R(r,n){return n==="dark"?r.dark??r.light??"":r.light??r.dark??""}async function D(r,n){const s=y(),a=m.startTiming(),e=w(),t=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","x-request-id":l.REQUEST_ID||""},body:JSON.stringify({type:r,definitions:n,rayId:e,theme:"both",organizationId:l.ORGANIZATION_ID})});if(t.status!==200)throw m.error("Diagram rendering service returned %s (rayId: %s)",t.status,e),new Error(`Something went wrong during rendering of ${r} diagrams`);return m.verboseTime(a,"Rendered %s diagrams (%s)",r,n.length),t.json()}async function T(r){if(r.length===0)return[];const n=new Map;for(let e=0;e<r.length;e++){const{type:t,source:i}=r[e],f=g(i,t);if(!u[f]){n.has(t)||n.set(t,[]);const o=n.get(t);o&&o.push({index:e,source:i})}}const s=[],a=new Map;for(const[e,t]of n){const i=t.map(o=>o.source),f=D(e,i).then(o=>{for(let c=0;c<t.length;c++){const d=o[c],h=g(t[c].source,e);if(d.error)m.error("Failed to render %s diagram: %s",e,d.error),a.set(h,{light:"",dark:"",error:`Failed to render ${e} diagram: ${d.error}`});else{const p={light:d.light??"",dark:d.dark??""};u[h]=p,a.set(h,p)}}}).catch(o=>{m.error("Failed to render %s diagrams: %s",e,o.message);for(const c of t){const d=g(c.source,e);a.set(d,{light:"",dark:"",error:`Failed to render ${e} diagram: ${o.message}`})}});s.push(f)}return await Promise.all(s),r.map(({type:e,source:t})=>{const i=g(t,e);return a.get(i)??u[i]})}async function M(r,n="light"){return(await T(r)).map(a=>R(a,n))}export{u as cache,g as generateDiagramHash,M as renderDiagrams,T as renderDiagramsWithVariants};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import u from"@markdoc/markdoc";import{isTag as b}from"../../../markdoc/helpers/guards/is-tag.js";import{slugger as
|
|
1
|
+
import u from"@markdoc/markdoc";import{isTag as b}from"../../../markdoc/helpers/guards/is-tag.js";import{slugger as l}from"../../utils/index.js";import{getMarkdocOptions as f}from"./markdoc/markdoc-options.js";import{visit as h,getHeadingData as k}from"./markdoc/plugins/utils.js";import{renderDiagramsWithVariants as v}from"./markdoc/plugins/render-diagrams.js";import{deepStringify as y}from"./markdoc/utils/deep-stringify.js";import{stringifyTagChildrenObjects as D}from"./utils/stringify-tag-children-objects.js";async function _(d,a,p){const g=await f(p),i=[],t=[],s=y(a.variables?.pageProps),{headers:H,...c}=a.variables||{};l.reset();const o=u.transform(d,{...g,...a,variables:{...c,pageProps:s}});let m=0;h(o,r=>{if(b(r)){switch(r.name){case"Heading":r.attributes.__idx=m,m++;const n=k(r);n&&i.push(n);break;case"Diagram":t.push({tag:r,input:{type:r.attributes.diagramType,source:r.attributes.diagramSource}});break}D(r)}});const e=await v(t.map(r=>r.input));for(let r=0;r<t.length;r++)t[r].tag.attributes.diagramError=e[r].error,t[r].tag.attributes.diagramHtml=e[r].light,t[r].tag.attributes.diagramHtmlDark=e[r].dark;return{headings:i,renderableAst:o,pageProps:s}}export{_ as transformMdAst};
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import{isPrimitive as
|
|
2
|
-
`);break;case"fence":const i=
|
|
3
|
-
`);break;case"item":
|
|
4
|
-
`).join(""));break;case"thead":const
|
|
5
|
-
`);break;case"tr":const
|
|
6
|
-
`);break;case"em":
|
|
7
|
-
`);break;case"hr":
|
|
1
|
+
import{isPrimitive as v}from"../../../../utils/guards/is-primitive.js";import{getNodeAttribute as c}from"../../../../markdoc/helpers/get-node-attribute.js";import{getVariable as T}from"../../../../markdoc/helpers/get-variable.js";import{isTag as C}from"../../../../markdoc/helpers/guards/is-tag.js";import{isNode as N}from"../../../../markdoc/helpers/guards/is-node.js";import{isConditionalNode as A}from"../../../../markdoc/helpers/guards/is-conditional-node.js";import{isVariable as E}from"../../../../markdoc/helpers/guards/is-variable.js";import{isExampleNode as w}from"../../../../markdoc/helpers/guards/is-example-node.js";import{isFenceNode as x}from"../../../../markdoc/helpers/guards/is-fence-node.js";function s(a,n={}){const r=[];for(const e of a){if(v(e)){const i=n.isTrim?d(String(e)):String(e);i&&r.push(i)}else if(N(e))switch(e.type){case"text":r.push(s([c(e,"content")],n));break;case"code":r.push(`\`${s([c(e,"content")],n)}\``);break;case"blockquote":r.push(`> ${s(e.children,n)}
|
|
2
|
+
`);break;case"fence":const i=c(e,"process")===!1;r.push(f(e,n,i));break;case"list":const l=c(e,"ordered")||!1,o=c(e,"marker"),u=e.children.map((t,h)=>`${" ".repeat((n?.indent??0)*2)}${l?h+1:""}${o} ${s([t],{...n??{},indent:(n?.indent??0)+1})}`);r.push(`${u.join("")}
|
|
3
|
+
`);break;case"item":r.push(e.children.map(t=>`${s([t],n).trimEnd()}
|
|
4
|
+
`).join(""));break;case"thead":const p=e.children.map(t=>s([t],n));r.push(`${p}| ${" --- |".repeat(e.children?.[0]?.children.length)}
|
|
5
|
+
`);break;case"tr":const $=e.children.map(t=>s([t],n));r.push(`| ${$.join(" | ")} |
|
|
6
|
+
`);break;case"em":r.push(`*${s(e.children,n)}*`);break;case"strong":r.push(`**${s(e.children,n)}**`);break;case"softbreak":case"hardbreak":r.push(`
|
|
7
|
+
`);break;case"hr":r.push(`
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
`);break;case"heading":const k=
|
|
12
|
-
`);break;case"image":const
|
|
13
|
-
`);break;case"tag":if(
|
|
14
|
-
\`\`\`${`${
|
|
15
|
-
${
|
|
11
|
+
`);break;case"heading":const k=c(e,"level")??0;r.push(`${"#".repeat(k)} ${s(e.children,n)}
|
|
12
|
+
`);break;case"image":const g=c(e,"alt")||"",b=c(e,"src")||"";r.push(``);break;case"link":const j=c(e,"href")||"";r.push(`[${s(e.children,n)}](${j})`);break;case"paragraph":case"table":r.push(`${s(e.children,n)}
|
|
13
|
+
`);break;case"tag":if(A(e)&&n.skipConditionals)continue;if(w(e)){r.push(...e.children.map(t=>{if(x(t)){const h=c(t,"process")!==!0;return f(t,n,h)}return s([t],n)}));continue}if(e.tag==="code-snippet"){const t=c(e,"rawContent");if(t){const h=c(e,"language"),m=c(e,"title"),S=`
|
|
14
|
+
\`\`\`${`${h||""}${m?`${h?" ":""}${m}`:""}`}
|
|
15
|
+
${t.trimEnd()}
|
|
16
16
|
\`\`\`
|
|
17
|
-
`;
|
|
18
|
-
\`\`\`${
|
|
19
|
-
${
|
|
17
|
+
`;r.push(S)}continue}if(e.tag==="json-example"){const t=y(e);t&&r.push(t);continue}if(e.tag==="json-schema"){const t=B(e);t&&r.push(t);continue}r.push(`${s(e.children,n)}`);break;default:r.push(s(e.children,n));break}else C(e)&&r.push(s(e.children,n));E(e)&&r.push(s([T(e,n.variables)],n))}return n.isTrim?d(r.map(e=>d(e)).join("")):r.join("")}function d(a){return a.replace(/^[ \t\r\f]+|[ \t\r\f]+$/g,"")}function f(a,n={},r=!1){const e=c(a,"title"),i=c(a,"language"),l=`${i||""}${e?`${i?" ":""}${e}`:""}`,o=r?(c(a,"content")||"").trimEnd():s(a.children,n).trimEnd();return`
|
|
18
|
+
\`\`\`${l}
|
|
19
|
+
${o}
|
|
20
20
|
\`\`\`
|
|
21
|
-
`}
|
|
21
|
+
`}function y(a){const n=c(a,"json")??c(a,"valueResolved")??c(a,"schemaResolved"),r=c(a,"title");return n===null?null:`
|
|
22
|
+
\`\`\`${`json${r?` ${r}`:""}`}
|
|
23
|
+
${JSON.stringify(n,null,2)}
|
|
24
|
+
\`\`\`
|
|
25
|
+
`}function B(a){const n=c(a,"schemaResolved");if(n===null)return null;const{components:r,openapi:e,...i}=n,{__root:l,...o}=r?.schemas||{},u=l?{...l,...Object.keys(o).length>0?{components:{schemas:o}}:{},...i}:n;return`
|
|
26
|
+
\`\`\`json
|
|
27
|
+
${JSON.stringify(u,null,2)}
|
|
28
|
+
\`\`\`
|
|
29
|
+
`}export{s as toMarkdown};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{logger as
|
|
1
|
+
import{logger as u}from"../../../tools/notifiers/logger.js";import{isNode as f}from"../../../../markdoc/helpers/guards/is-node.js";import{isConditionalNode as y}from"../../../../markdoc/helpers/guards/is-conditional-node.js";import{isContentNode as N}from"../../../../markdoc/helpers/guards/is-content-node.js";import{getNodeAttribute as n}from"../../../../markdoc/helpers/get-node-attribute.js";import{extractRbacFromCondition as T}from"../../../../markdoc/helpers/extract-rbac-from-condition-node.js";import{TextNode as e}from"./nodes/text-node.js";import{TAG_TITLE_ATTRIBUTES as b,TagNode as p}from"./nodes/tag-node.js";import{HeadingNode as a}from"./nodes/heading-node.js";class j{#s;#o;#i;#t;constructor({ast:i,partials:s,skipConditionals:r=!1,getInnerContent:t}){if(this.#s=i,this.#o=s,this.#i=r,this.#t=t,!this.#s||!f(this.#s))throw new Error("ast is not a valid Markdoc Node.")}*transform(){yield*this.#l(this.#s,{parentNode:null})}*#l(i,s,r=this.#t){if(!(!i||!f(i))){if(y(i)){if(this.#i)return;const t=T(i);t&&t.length>0&&(yield*this.#r(i,{...s,rbacTeams:t},r));return}if(N(i)){yield new e({node:i,content:r([i],{skipConditionals:this.#i}),...s});return}if(i.type==="heading"){yield new a({node:i,content:r([i],{skipConditionals:this.#i}),rbacTeams:s?.rbacTeams});return}if(i.type==="tag"){yield*this.#c(i,s,r);return}yield*this.#r(i,s,r)}}*#c(i,s,r=this.#t){switch(i.tag){case"partial":{const t=i.attributes.file,o=i.attributes.variables??{};if(t&&this.#o[t]){yield*this.#l(this.#o[t],s,(l,h)=>r(l,{...h,variables:o}));return}u.warn(`Could not create search indexes for partial \u201C${t}\u201D: file not found`);return}case"cards":case"tabs":case"code-walkthrough":{yield*this.#r(i,s,r);return}case"markdoc-example":{const t=r([i],{skipConditionals:this.#i});yield new e({node:i,content:t,...s});return}case"code-snippet":{const t=n(i,"title"),o=r([i],{skipConditionals:this.#i});if(t){const l=new p({node:i,content:t,...s});s={...s,parentNode:l},yield l}o&&(yield new e({node:i,content:o,...s}));return}default:{const t=b.find(c=>c in i.attributes),o=(t&&n(i,t))??"",l=typeof o=="string"?o:r([o]);if(l){const c=new p({node:i,content:l,...s});s={...s,parentNode:c},yield c}if(i.children.length>0||Object.keys(i.slots).length>0)yield*this.#r(i,s,r);else{const c=r([i],{skipConditionals:this.#i});c&&(yield new e({node:i,content:c,...s}))}return}}}*#r(i,s,r=this.#t){for(const t of[...Object.values(i.slots),...i.children])for(const o of this.#l(t,s,r))o instanceof a&&(s={...s,parentNode:o}),yield o}}export{j as AstToSearchNodeTransformer};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{shouldHandleMcpAuth as n}from"../auth/auth-handlers.js";const i=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"];function s(e){const t=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:{type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:{type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:{type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...i,...i.map(r=>r.toLowerCase())],minLength:1}}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:{type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:{type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}}},a(e.products)];return n(e.requiresLogin,e.rbac)&&t.push({name:"whoami",description:"Get information about the currently authenticated user",schema:{type:"object",required:[],additionalProperties:!1,properties:{}}}),t}function a(e){const t=e&&e.length>0;return{name:"search",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...t?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{}}}}}export{s as getDefaultToolSchemas};
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly requiredContext: readonly ContextKey[];
|
|
7
|
-
constructor();
|
|
8
|
-
protected executeAction(args: ToolArgsMap['get-endpoint-info'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
|
|
9
|
-
}
|
|
1
|
+
import type { McpToolHandler } from '../../types.js';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
'get-endpoint-info': McpToolHandler;
|
|
4
|
+
};
|
|
5
|
+
export default _default;
|
|
10
6
|
//# sourceMappingURL=get-endpoint-info.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveParameters as
|
|
1
|
+
import{resolveParameters as y,resolveRequestBody as h,resolveResponses as x}from"../utils.js";import{isMcpEndpoint as E}from"./utils.js";import{loadApiDescription as v}from"./helpers/load-api-description.js";import{checkEndpointAndDeleteXMcp as g}from"../../utils/xmcp-utils.js";const P=async(s,i)=>{const{name:p,path:o,method:n}=s;let t;try{t=await v(p,i)}catch(f){return{content:[{type:"text",text:f.message}],isError:!0}}const a=o.startsWith("/")?o:`/${o}`,{title:c=""}=t.info||{},r=t.paths?.[a],d=n.toLowerCase();if(!r)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const e=r[d];if(!E(e)||!g(e,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const m=r?.parameters||[],u=e.parameters||[],l={...e,parameters:y({pathParams:m,opParams:u,definition:t}),requestBody:h(e.requestBody,t),responses:x(e.responses,t)};return{content:[{type:"text",text:JSON.stringify({api:c,version:t.info?.version||"",servers:t.servers||[],endpoint:{path:o,method:n.toUpperCase(),...l},globalSecurity:t.security||[],securitySchemes:t.components?.securitySchemes||[]},null,2)}]}};var C={"get-endpoint-info":P};export{C as default};
|