@redocly/reef 0.132.0 → 0.133.0-next.1
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 +58 -3
- package/dist/cli/build/copy-env-files.js +1 -1
- package/dist/cli/develop.js +1 -1
- package/dist/cli/telemetry/index.js +1 -1
- package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.js +1 -1
- package/dist/constants/common.d.ts +2 -1
- package/dist/constants/common.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/server/api-routes/helpers/enhance-context.js +1 -1
- package/dist/server/config/env-config.d.ts +157 -8
- package/dist/server/config/env-config.js +1 -1
- package/dist/server/config/env-schema.d.ts +148 -185
- package/dist/server/config/env-schema.js +1 -3
- package/dist/server/config/env-schemas/auth.d.ts +4 -4
- package/dist/server/config/env-schemas/auth.js +1 -1
- package/dist/server/config/env-schemas/catalog.d.ts +2 -2
- package/dist/server/config/env-schemas/catalog.js +1 -1
- package/dist/server/config/env-schemas/environment-detection.d.ts +13 -13
- package/dist/server/config/env-schemas/environment-detection.js +1 -1
- package/dist/server/config/env-schemas/feature-flags.d.ts +9 -6
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/config/env-schemas/search.d.ts +1 -1
- package/dist/server/config/env-schemas/search.js +1 -1
- package/dist/server/config/env-schemas/server-config.d.ts +2 -2
- package/dist/server/config/env-schemas/server-config.js +1 -1
- package/dist/server/constants/entitlements.js +1 -1
- package/dist/server/esbuild/esbuild-logger.js +3 -3
- package/dist/server/esbuild/esbuild.js +3 -3
- package/dist/server/esbuild/generate.d.ts +3 -0
- package/dist/server/esbuild/generate.js +8 -8
- package/dist/server/esbuild/plugins/api-request-handlers-resolver.js +1 -1
- package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +2 -0
- package/dist/server/persistence/kv/repositories/kv-remote-repository.js +2 -2
- package/dist/server/persistence/kv/services/kv-service.js +1 -1
- package/dist/server/plugins/api-functions/index.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
- package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
- package/dist/server/plugins/default-theme/index.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/adapters/apigee/adapter.js +3 -3
- package/dist/server/plugins/dev-onboarding/api/routes/index.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/routes/meta.d.ts +4 -0
- package/dist/server/plugins/dev-onboarding/api/routes/meta.js +1 -0
- package/dist/server/plugins/dev-onboarding/api/types.d.ts +1 -0
- package/dist/server/plugins/dev-onboarding/template/App.js +5 -5
- package/dist/server/plugins/dev-onboarding/template/CreateAppDialog.js +3 -3
- package/dist/server/plugins/dev-onboarding/template/components/CallbackUrl.d.ts +5 -0
- package/dist/server/plugins/dev-onboarding/template/components/CallbackUrl.js +17 -0
- package/dist/server/plugins/dev-onboarding/template/components/DialogStyledComponents.d.ts +1 -0
- package/dist/server/plugins/dev-onboarding/template/components/DialogStyledComponents.js +6 -2
- package/dist/server/plugins/dev-onboarding/template/components/EditCallbackUrlDialog.d.ts +8 -0
- package/dist/server/plugins/dev-onboarding/template/components/EditCallbackUrlDialog.js +1 -0
- package/dist/server/plugins/enforce-login/index.js +1 -1
- package/dist/server/plugins/entitlements/utils/get-billed-catalog-build-pages-count.js +1 -1
- package/dist/server/plugins/lifecycle.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +6 -1
- 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 +4 -1
- 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 +4 -1
- 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 +4 -1
- 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 +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/helpers/load-api-description.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +23 -5
- package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +5 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/openapi-docs/ast-utils.js +2 -2
- package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +26 -26
- package/dist/server/plugins/scorecards/plugin.js +1 -1
- package/dist/server/providers/database/base-repository.d.ts +1 -0
- package/dist/server/providers/database/base-repository.js +5 -1
- package/dist/server/providers/database/database-preconnect-service.js +1 -1
- package/dist/server/providers/database/pagination/utils/extract-equal-filter-clause-value.d.ts +6 -0
- package/dist/server/providers/database/pagination/utils/extract-equal-filter-clause-value.js +1 -0
- package/dist/server/providers/database/pagination/utils/index.d.ts +1 -0
- package/dist/server/providers/database/pagination/utils/index.js +1 -1
- package/dist/server/providers/database/utils/storage-limit-validator.d.ts +13 -0
- package/dist/server/providers/database/utils/storage-limit-validator.js +1 -0
- package/dist/server/store.d.ts +1 -0
- package/dist/server/store.js +1 -1
- package/dist/server/telemetry/index.js +1 -1
- package/dist/server/tools/notifiers/formatter.js +3 -3
- package/dist/server/tools/notifiers/helpers/colors.js +1 -1
- package/dist/server/types/plugins/common.d.ts +1 -0
- package/dist/server/utils/envs/env-boolean-string.d.ts +12 -0
- package/dist/server/utils/envs/env-boolean-string.js +1 -0
- package/dist/server/utils/envs/load-env-variables.js +1 -1
- package/dist/server/utils/is-catalog-entities-enabled.js +1 -1
- package/dist/server/utils/is-scorecards-enabled.js +1 -1
- package/dist/server/utils/lifecycle-hooks.js +1 -1
- package/dist/server/version.js +1 -1
- package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -1
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/otel/otel.d.ts +2 -16
- package/dist/server/web-server/routes/otel/otel.js +1 -1
- package/dist/server/web-server/routes/otel/otlp.d.ts +4 -1
- package/dist/server/web-server/routes/otel/otlp.js +1 -1
- package/dist/server/web-server/routes/static-content.js +1 -1
- package/dist/server/web-server/utils/content-type.d.ts +2 -0
- package/dist/server/web-server/utils/content-type.js +1 -0
- package/dist/types/entitlements.d.ts +1 -0
- package/package.json +19 -19
- package/dist/server/config/env-schemas/test.d.ts +0 -22
- package/dist/server/config/env-schemas/test.js +0 -1
- package/dist/server/utils/envs/write-env-variable.d.ts +0 -18
- package/dist/server/utils/envs/write-env-variable.js +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{context as m}from"esbuild";import{mkdirSync as b,writeFileSync as M,existsSync as
|
|
2
|
-
const require = topLevelCreateRequire(import.meta.url);`},platform:"node",define:{"process.env.NODE_ENV":`"${t}"
|
|
3
|
-
const require = topLevelCreateRequire(import.meta.url);`},logLevel:"silent"});return c.add(s),s})}export{
|
|
1
|
+
import{context as m}from"esbuild";import{mkdirSync as b,writeFileSync as M,existsSync as Y}from"node:fs";import*as a from"node:path";import{RUNTIME_RESOURCES_DIR as k,TELEMETRY_ENABLED as V}from"../constants/common.js";import{fromCurrentDir as r}from"../utils/paths.js";import{NodeBrowserPlugin as P}from"./plugins/node-browser.js";import{PortalImport as l}from"./plugins/portal-import.js";import{ThemesResolver as u}from"./plugins/themes-resolver.js";import{AssetsResolver as E}from"./plugins/assets-resolver.js";import{EsbuildErrorCollector as R}from"./plugins/esbuild-compile-resolver.js";import{OpenapiDocsModuleReplacer as _}from"./plugins/openapi-docs-module-replacer/index.js";import{ServerPropsResolver as d}from"./plugins/server-props-resolver.js";import{StyledComponentsSSR as f}from"./plugins/styled-components-ssr.js";import{DependencyResolver as v}from"./plugins/dependency-resolver.js";import{YamlLoader as D}from"./plugins/yaml-loader.js";import{ApiRequestHandlersResolver as T}from"./plugins/api-request-handlers-resolver.js";import{McpToolHandlersResolver as A}from"./plugins/mcp-tool-handlers-resolver.js";import{MiddlewareResolver as S}from"./plugins/middleware-resolver.js";import{OnRebuild as N}from"./plugins/on-rebuild.js";import{getPublicEnvVariables as $}from"../utils/envs/get-public-env-variables.js";import{PORTAL_VERSION as I}from"../version.js";import{AsyncApiPatch as L}from"./plugins/async-api-patch.js";import{telemetryTraceStep as w}from"../../cli/telemetry/helpers/trace-step.js";import{initServerRebuildTrigger as q}from"./generate.js";const O={bundle:!0,format:"esm",chunkNames:"chunks/[name]-[hash]"};function y(e){const o=a.join(e,"tsconfig.json");return Y(o)?o:void 0}const c=new Set;async function ae(){await Promise.all([...c].map(e=>e.dispose())),c.clear()}async function le(e,o,t="production",n){return await w("build.create_client_compiler",async()=>{const p=$(),i={};Object.entries(p).map(([h,j])=>i[`process.env.${h}`]=JSON.stringify(j));const s=[...n?[N(n)]:[],P({path:"path-browserify",fs:"{}",tty:"tty-browserify",os:"os-browserify",http:"stream-http",https:"stream-http",readline:"{}",crypto:"{}",stream:"{}",zlib:"{}","https-proxy-agent":"{}"}),u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),d(e),v(),l(),D(),L(),f(),_()],g=[r(import.meta.url,"../../client/browser-entry.js"),r(import.meta.url,"../../client/user-tags-entry.js")],C=await m({...O,entryPoints:g,outdir:a.join(o,k),sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",plugins:s,tsconfig:y(e.contentDir),mainFields:["browser","module","main"],metafile:t!=="production",minify:t==="production",splitting:!0,external:["constants","zlib","stream","https","vm","module","worker_threads","child_process","@swc/core"],inject:[process.env.INSPECT_MODE==="true"?r(import.meta.url,"../../client/inspect-mode-hooks.js"):"",r(import.meta.url,"./web-shim.js")].filter(Boolean),define:{...i,"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.SERVER_EDITOR_APP_URL":`"${process.env.SERVER_EDITOR_APP_URL}"`,"process.env.ENABLE_COMMENTS":`"${process.env.ENABLE_COMMENTS}"`,"process.env.REDOCLY_TELEMETRY":V?'"on"':'"off"',"process.env.REDOCLY_PORTAL_VERSION":`"${I}"`,"process.env":`{"NODE_ENV": "${t}"}`,"process.platform":'"browser"',"process.browser":"true","module.hot":"false",global:"{}",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`},...process.env.INSPECT_MODE==="true"&&{"process.env.INSPECT_MODE":`${process.env.INSPECT_MODE}`},...process.env.MAIN_API_URL&&{"process.env.MAIN_API_URL":`"${process.env.MAIN_API_URL}"`}},logLevel:"silent"});return c.add(C),C})}async function ue(e,o,t="development",n){b(o,{recursive:!0}),q(o),M(a.join(o,"package.json"),JSON.stringify({name:"@redocly/portal/server-cache",type:"module"}));const p=[...n?[N(n)]:[],u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),d(e),T(e),A(e),S(e),v(),l(),D(),L(),f(),_()],i=[{in:r(import.meta.url,"../../client/server-entry.js"),out:"server-entry"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../../client/server-props-entry.js"),out:"server-props-entry"},{in:r(import.meta.url,"../../client/api-request-handlers-entry.js"),out:"api-request-handlers-entry"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"},{in:r(import.meta.url,"../../client/middleware-entry.js"),out:"middleware-entry"}],s=await m({...O,entryPoints:i,outdir:o,plugins:p,sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",minify:t==="production",tsconfig:y(e.contentDir),mainFields:["module","main"],splitting:!0,external:["react","react-router-dom","@dr.pogodin/react-helmet","@swc/core","pnpapi","canvas"],banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);`},platform:"node",define:{"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"module.hot":"false"},logLevel:"silent"});return c.add(s),s}async function Ee(e,o,t="production",n){return await w("build.create_server_compiler",async()=>{const p=[...n?[N(n)]:[],P({"node-fetch":"{}",webpack:"{}",swagger2openapi:"{}"}),u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),d(e),T(e),A(e),S(e),v(),l(),D(),L(),f(),_()],i=[{in:r(import.meta.url,"../node-bundle-entry.js"),out:"index"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../workers/api-routes-worker.js"),out:"api-routes-worker"},{in:r(import.meta.url,"../workers/scorecards-worker.js"),out:"scorecards-worker"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"}],s=await m({...O,entryPoints:i,outExtension:{".js":".mjs"},outdir:o,platform:"node",plugins:p,tsconfig:y(e.contentDir),mainFields:["module","main"],metafile:t!=="production",minify:t==="production",splitting:!1,define:{"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.REDOCLY_EXECUTION_MODE":'"runtime"',"process.env.REDOCLY_PORTAL_VERSION":`"${I}"`,"module.hot":"false",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`}},banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
|
|
3
|
+
const require = topLevelCreateRequire(import.meta.url);`},logLevel:"silent"});return c.add(s),s})}export{le as createClientCompiler,Ee as createNodeBundleCompiler,ue as createServerCompiler,ae as stopAllCompilers};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Store } from '../store.js';
|
|
2
|
+
export declare function getServerRebuildTriggerPath(serverOutDir: string): string;
|
|
3
|
+
export declare function initServerRebuildTrigger(serverOutDir: string): void;
|
|
4
|
+
export declare function writeServerRebuildTrigger(serverOutDir: string): void;
|
|
2
5
|
export declare function generateTemplatesModule(store: Store): void;
|
|
3
6
|
export declare function generateBrowserPluginsModule(store: Store): void;
|
|
4
7
|
export declare function generateClientRoutes(store: Store): void;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{mkdirSync as
|
|
2
|
-
`+
|
|
1
|
+
import{mkdirSync as a,writeFileSync as i,existsSync as R}from"fs";import{dirname as u,join as p}from"path";import{slash as h}from"../../utils/path/slash.js";import{ensureDir as l}from"../utils/fs.js";import{fromCurrentDir as c}from"../utils/paths.js";const x=".server-rebuild-trigger";function m(e){return p(e,x)}function $(e){i(l(m(e)),"")}function v(e){i(m(e),Date.now().toString())}function C(e){return Array.from(e.entries()).sort(([t],[o])=>o.localeCompare(t))}let g=null;function w(e){const t=c(import.meta.url,"../../client/runtime/generated/templates.js"),o=`export const templates = {
|
|
2
|
+
`+C(e.templates).map(([r,s])=>` "${r}": () => import("${h(s)}"),
|
|
3
3
|
`).join(`
|
|
4
|
-
`)+"}";
|
|
5
|
-
${
|
|
4
|
+
`)+"}";a(u(t),{recursive:!0});const n=p(u(t),"package.json");R(n)||i(p(u(t),"package.json"),JSON.stringify({name:"@redocly/portal/ssr-entry"})),g!==o&&(i(l(t),o,"utf-8"),g=o)}let f=null;function F(e){const t=Array.from(e.browserPlugins),o=c(import.meta.url,"../../client/runtime/generated/browser-plugins.js"),n=`
|
|
5
|
+
${t.map((r,s)=>`import * as plugin${s} from '${r.replace(/\\/g,"/")}'`).join(`
|
|
6
6
|
`)}
|
|
7
7
|
|
|
8
8
|
export const onRouteChange = (context, themeConfig) => {
|
|
9
|
-
${
|
|
9
|
+
${t.map((r,s)=>`plugin${s}.onRouteChange?.(context, themeConfig);`).join(`
|
|
10
10
|
`)}
|
|
11
11
|
|
|
12
12
|
// Hooks registered during browser runtime
|
|
@@ -14,8 +14,8 @@ import{mkdirSync as l,writeFileSync as u,existsSync as d}from"fs";import{dirname
|
|
|
14
14
|
typeof hookCallback === 'function' && hookCallback(context, themeConfig)
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
`;
|
|
17
|
+
`;a(u(o),{recursive:!0}),f!==n&&(i(l(o),n,"utf-8"),f=n)}let d=null;function T(e){const t=c(import.meta.url,"../../client/runtime/generated/routes.js"),n=`
|
|
18
18
|
export const clientRoutes = [
|
|
19
|
-
${Array.from(
|
|
19
|
+
${Array.from(e.routesBySlug.values()).filter(r=>r.hasClientRoutes).map(r=>r.baseSlug||r.slug).map(r=>` ${JSON.stringify(r)},`).join(`
|
|
20
20
|
`)}
|
|
21
|
-
]`;
|
|
21
|
+
]`;a(u(t),{recursive:!0}),d!==n&&(i(l(t),n,"utf-8"),d=n)}export{F as generateBrowserPluginsModule,T as generateClientRoutes,w as generateTemplatesModule,m as getServerRebuildTriggerPath,$ as initServerRebuildTrigger,v as writeServerRebuildTrigger};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{generateApiRequestHandlersEntry as
|
|
1
|
+
import{generateApiRequestHandlersEntry as o}from"./codegen/index.js";import{getServerRebuildTriggerPath as l}from"../generate.js";const s="api-request-handlers-ns",u=e=>({name:"esbuild-redocly-api-request-handlers-resolver",setup:r=>{r.onResolve({filter:/@portal\/api-request-handlers/},t=>{const a=Array.from(e.apiRoutesRequestHandlers.values()),n=l(e.serverOutDir);return{namespace:s,path:t.path,watchFiles:[...a,n]}}),r.onLoad({filter:/@portal\/api-request-handlers/,namespace:s},()=>({contents:o(Array.from(e.apiRoutesRequestHandlers.entries())),resolveDir:"/",loader:"ts"}))}});export{u as ApiRequestHandlersResolver};
|
|
@@ -14,5 +14,7 @@ export declare class KvRemoteRepository extends BaseRepository {
|
|
|
14
14
|
delete(key: KvKey): Promise<void>;
|
|
15
15
|
clearExpired(): Promise<void>;
|
|
16
16
|
transaction<T>(operation: (tx: KvTransaction) => Promise<T>): Promise<T>;
|
|
17
|
+
getTotalStoredEntryBytes(): Promise<number>;
|
|
18
|
+
getStoredEntrySizeByEncodedKey(encodedKey: string): Promise<number>;
|
|
17
19
|
}
|
|
18
20
|
//# sourceMappingURL=kv-remote-repository.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{eq as
|
|
2
|
-
All changes and data will only persist locally and will not be synced remotely.`),this.#t=!0);return}await this.databaseClient.sync()}async get(e){try{const r=l(e),n=await this.databaseClient.client.select().from(t).where(
|
|
1
|
+
import{eq as K,and as h,gte as u,gt as B,lt as f,asc as S,desc as L,or as w,isNull as b,sql as s,inArray as M,count as N}from"drizzle-orm";import{logger as i}from"../../../tools/notifiers/logger.js";import{kvTable as t}from"../../../providers/database/databases/sqld-sqlite/schemas/kv-table.js";import{BaseRepository as T}from"../../../providers/database/base-repository.js";import{DatabaseConnectionFactory as $}from"../../../providers/database/database-connection-factory.js";import{createKvValue as D}from"../mappers/create-kv-value.js";import{createKvDbRecord as q,encodeKvKey as l}from"../mappers/create-kv-db-record.js";import{decodeCursor as I}from"../helpers/decode-cursor.js";import{encodeCursor as O}from"../helpers/encode-cursor.js";import{createKvListEntry as E}from"../mappers/create-kv-list-entry.js";const z="";class y extends T{static#e;#t=!1;constructor(e){super(e)}static async getInstance(e){if(!y.#e)try{const r=await $.create("sqld-remote",e);if(!r)return y.#e=null,null;y.#e=new y(r)}catch(r){return i.error("Error creating kv remote repository",r),y.#e=null,null}return y.#e}async sync(){if(this.isNonRemoteDatabaseMode()){this.#t||(i.warn(`KV database is currently operating in local mode: not connected to the remote database.
|
|
2
|
+
All changes and data will only persist locally and will not be synced remotely.`),this.#t=!0);return}await this.databaseClient.sync()}async get(e){try{const r=l(e),n=await this.databaseClient.client.select().from(t).where(h(K(t.encodedKey,r),w(b(t.expiresAt),u(s`datetime(${t.expiresAt})`,s`datetime('now')`)))).get();return n?D(n):null}catch(r){return i.error("Error getting kv entry by key",r),null}}async getMany(e){try{if(e.length===0)return[];const r=e.map(d=>l(d)),n=w(b(t.expiresAt),u(s`datetime(${t.expiresAt})`,s`datetime('now')`)),a=await this.databaseClient.client.select().from(t).where(h(M(t.encodedKey,r),n)).all(),o=new Map(a.map(d=>[d.encodedKey,d]));return e.map((d,C)=>{const g=r[C],x=o.get(g);return x?E(x):null})}catch(r){return i.error("Error getting multiple kv entries",r),[]}}async list(e,r){try{const n=r?.limit??100,a=r?.reverse??!1,o=[],A=w(b(t.expiresAt),u(s`datetime(${t.expiresAt})`,s`datetime('now')`));if(o.push(A),"prefix"in e){const c=l(e.prefix),m="start"in e?l(e.start):c,k="end"in e?l(e.end):c+z;o.push(u(t.encodedKey,m)),o.push(f(t.encodedKey,k))}else if("start"in e&&"end"in e){const c=l(e.start),m=l(e.end);o.push(u(t.encodedKey,c)),o.push(f(t.encodedKey,m))}if(r?.cursor){const c=I(r.cursor),m=a?f(t.encodedKey,c):B(t.encodedKey,c);o.push(m)}const d=this.databaseClient.client.select().from(t),C=o.length>0?d.where(h(...o)):d,g=this.databaseClient.client.select({count:N()}).from(t),v=(await(o.length>0?g.where(h(...o)):g).get())?.count??0,p=await C.orderBy(a?L(t.encodedKey):S(t.encodedKey)).limit(n).all();return{items:p.map(c=>E(c)),total:v,cursor:v>p.length?O(p[p.length-1]?.encodedKey):null}}catch(n){return i.error("Error listing kv entries",n),{items:[],total:0,cursor:null}}}async set(e,r,n){try{const a=q({key:e,value:r,ttlInSeconds:n?.ttlInSeconds});return await this.databaseClient.client.insert(t).values(a).onConflictDoUpdate({target:[t.encodedKey],set:{value:a.value,expiresAt:a.expiresAt,updatedAt:a.updatedAt}}),E(a)}catch(a){return i.error("Error saving kv entry",a),null}}async delete(e){try{const r=l(e);await this.databaseClient.client.delete(t).where(K(t.encodedKey,r))}catch(r){i.error("Error deleting kv entry by key",r)}}async clearExpired(){try{await this.databaseClient.client.delete(t).where(f(s`datetime(${t.expiresAt})`,s`datetime('now')`))}catch(e){i.error("Error clearing expired kv entries",e)}}async transaction(e){return this.databaseClient.transactionsManager.transaction(async()=>e({get:async n=>this.get(n),getMany:async n=>this.getMany(n),set:async(n,a,o)=>this.set(n,a,o),delete:async n=>this.delete(n)}))}async getTotalStoredEntryBytes(){try{return await this.getTableSizeInBytes("kv")}catch(e){return i.error("Error getting total kv stored entry bytes",e),0}}async getStoredEntrySizeByEncodedKey(e){try{const r=w(b(t.expiresAt),u(s`datetime(${t.expiresAt})`,s`datetime('now')`)),n=await this.databaseClient.client.select({bytes:s`COALESCE(LENGTH(CAST(${t.encodedKey} AS BLOB)) + LENGTH(CAST(${t.value} AS BLOB)), 0)`}).from(t).where(h(K(t.encodedKey,e),r)).get();return Number(n?.bytes??0)}catch(r){return i.error("Error getting kv entry size by encoded key",r),0}}}export{z as KV_KEY_END_BOUNDARY,y as KvRemoteRepository};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{KvRemoteRepository as
|
|
1
|
+
import{PLAN_GATES_DEFAULTS as m}from"../../../constants/entitlements.js";import{EntitlementsProvider as u}from"../../../entitlements/entitlements-provider.js";import{StorageLimitValidator as d}from"../../../providers/database/utils/storage-limit-validator.js";import{KvRemoteRepository as h}from"../repositories/kv-remote-repository.js";import{encodeKvKey as g}from"../mappers/create-kv-db-record.js";import{kvKeyValidator as a,kvListOptionsValidator as f,kvListSelectorValidator as w,kvSetOptionsValidator as l}from"../schemas/kv-schemas.js";const E=100*1024*1024;class o{static#e;#t;#s;constructor(t){this.#t=t,this.#s=new d}static async#a(t){const e=await h.getInstance(t),s=new o(e);o.#e=s}static async getInstance(t){return o.#e||await o.#a(t),o.#e}async get(t){const e=a.parse(t);return await this.#t?.sync(),await this.#t?.get(e)??null}async getMany(t){if(t.length===0)return[];const e=t.map(s=>a.parse(s));return await this.#t?.sync(),await this.#t?.getMany(e)??[]}async list(t,e){const s=w.parse(t),r=f.parse(e??{});return await this.#t?.sync(),await this.#t?.list(s,r)??{items:[],total:0,cursor:null}}async set(t,e,s){const r=a.parse(t),n=l.parse(s??{});this.#r(e);const i=JSON.stringify(e);return this.#n(i),await this.#i(r,i),await this.#t?.set(r,e,n)??null}async delete(t){const e=a.parse(t);return this.#t?.delete(e)}async clearExpired(){return await this.#t?.clearExpired()}async transaction(t){if(!this.#t)throw new Error("Remote repository not available for transactions");return await this.#t.sync(),this.#t.transaction(async e=>t({get:async r=>{const n=a.parse(r);return e.get(n)},getMany:async r=>{const n=r.map(i=>a.parse(i));return e.getMany(n)},set:async(r,n,i)=>{const c=a.parse(r),p=l.parse(i??{});this.#r(n);const y=JSON.stringify(n);return this.#n(y),await this.#i(c,y),e.set(c,n,p)},delete:async r=>{const n=a.parse(r);return e.delete(n)}}))}#r(t){try{JSON.stringify(t)}catch(e){const s=e instanceof Error?e.message:"Unknown error";throw new Error(`Value is not JSON serializable: ${s}`)}}#n(t){const s=Buffer.byteLength(t,"utf8");if(s>1048576){const r=(s/1024).toFixed(2);throw new Error(`Value size (${r} KB) exceeds the maximum allowed size of 1 MB (1024 KB)`)}}async#i(t,e){if(!this.#t)return;const s=g(t),r=await this.#t.getTotalStoredEntryBytes(),n=Math.max(0,r-E),i=await this.#t.getStoredEntrySizeByEncodedKey(s),c=Buffer.byteLength(s,"utf8")+Buffer.byteLength(e,"utf8");this.#s.validate({storageLimitGb:this.#o(),currentTotalBytes:n,existingEntryBytes:i,incomingEntryBytes:c,errorMessagePrefix:"KV storage limit"})}#o(){const t=u.instance().entitlements?.kvStorageLimit;return typeof t=="number"&&t>0?t:m.pro.kvStorageLimit}}export{o as KvService};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join as p}from"path";import{REDOCLY_ROUTE_RBAC as
|
|
1
|
+
import{join as p}from"path";import{transformSync as l}from"esbuild";import{REDOCLY_ROUTE_RBAC as d}from"@redocly/config";import{removeTrailingSlash as m}from"../../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as g}from"../../../utils/url/remove-leading-slash.js";import{logger as h}from"../../tools/notifiers/logger.js";import{USER_DEFINED_API_FUNCTIONS_COUNTER_KEY as F}from"../../../server/store.js";import{parseRouteFsPathForHono as A}from"./helpers/parse-route-fs-path-for-hono.js";import{telemetryTraceStep as P}from"../../../cli/telemetry/helpers/trace-step.js";const u="api-functions";async function R(t,n){try{const e=await n.fs.read(t);return l(e,{loader:t.endsWith(".js")?"js":"ts"}),!0}catch(e){const r=e instanceof Error?e.message:String(e);return h.warn(`Skipping API function ${t} because it cannot be parsed: ${r}`),!1}}function E(t){return g(m(t))}function _(t){return`^${E(t)}`}function S(t){const n=t.map(_);return n.push(".*@api"),new RegExp(`(${n.join("|")})/.*.(ts|js)$`)}async function O(){return{id:"ApiFunctions",requiredEntitlements:["apiFunctions"],async processContent(t,n){await P("build.plugin.api_functions",async e=>{const r=await n.getConfig();e?.setAttribute("config",JSON.stringify(r.apiFunctions||{}));const c=S(r.apiFunctions?.folders||[]);let s=0;t.clearRequestHandlersByPrefix(`${u}:`);for(const o of n.fs.scan(c)){if(o.isVirtual)continue;const i=A(o.relativePath);if(!i)continue;const a=`${u}:${i.handler}`,f=p(t.contentDir,i.handler);await R(o.relativePath,n)&&(t.createRequestHandler(a,f),t.addApiRoute({requestHandlerId:a,slug:i.path,fsPath:o.relativePath,httpMethod:i.method,[d]:{fsPath:o.relativePath,slug:i.path}}),s++)}e?.setAttribute("definedApiFunctions",String(s)),t.setGlobalConfig({[F]:s})})}}}export{u as API_FUNCTIONS_REQUEST_HANDLER_ID,O as apiFunctionsPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{and as m,eq as c,isNull as v,or as T,sql as F}from"drizzle-orm";import{logger as u}from"../../../../../tools/notifiers/logger.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{sha1 as O}from"../../../../../utils/crypto/sha1.js";import{envConfig as V}from"../../../../../config/env-config.js";import{VERSION_NOT_SPECIFIED as U}from"@redocly/theme/core/constants";import{entitiesAttributesTable as I}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js";import{createEntityDbRecord as b}from"../../mappers/create-entity-db-record.js";import{createEntityRelationDbRecordFromFileSchema as K}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{entitiesTable as r}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as i}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{convertFilterToWhereCondition as C}from"../../../../../providers/database/pagination/filter.js";import{createEntityAttributesDbRecord as z}from"../../mappers/create-entity-attributes-db-record.js";import{RevisionRepository as L}from"../common/revision-repository.js";import{VersionRepository as P}from"../common/version-repository.js";const w=15;class re{#e;#t;#r;#i;#s;constructor(e,t,s){this.#e=e,this.#t=t,this.#r=s,this.#i=new L(e),this.#s=new P(e)}async createEntity({entity:e,fileHash:t,sourceFile:s,revision:a=new Date().toISOString(),isRootEntity:o=!1,isDeleted:n=!1,rbacTeams:d}){try{const{relations:l=[],...f}=e,p=O(JSON.stringify(f)),y=e.version??U,g=await this.#i.shouldSkipRevisionCreation(e.key,y,p,o,n);if(Array.isArray(d)&&await this.#o({entityKey:e.key,rbacTeams:d}),g)return{result:"skipped",entityKey:e.key};const h=await this.#i.shouldSetNewCurrentRevision({key:e.key,version:y,revision:a}),R=b({entity:{...e,revision:a,hash:p,isCurrent:h,isDefaultVersion:h,isDeleted:n,version:y},sourceFile:s,organizationId:this.#t,projectId:this.#r,source:"file",fileHash:t}),{key:D,source:x,...S}=R;if(h&&(await this.#i.markAllRevisionsAsNotCurrent(D),await this.#s.markAllVersionsAsNotDefault(D)),V.isDevelopMode
|
|
1
|
+
import{and as m,eq as c,isNull as v,or as T,sql as F}from"drizzle-orm";import{logger as u}from"../../../../../tools/notifiers/logger.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{sha1 as O}from"../../../../../utils/crypto/sha1.js";import{envConfig as V}from"../../../../../config/env-config.js";import{VERSION_NOT_SPECIFIED as U}from"@redocly/theme/core/constants";import{entitiesAttributesTable as I}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js";import{createEntityDbRecord as b}from"../../mappers/create-entity-db-record.js";import{createEntityRelationDbRecordFromFileSchema as K}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{entitiesTable as r}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as i}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{convertFilterToWhereCondition as C}from"../../../../../providers/database/pagination/filter.js";import{createEntityAttributesDbRecord as z}from"../../mappers/create-entity-attributes-db-record.js";import{RevisionRepository as L}from"../common/revision-repository.js";import{VersionRepository as P}from"../common/version-repository.js";const w=15;class re{#e;#t;#r;#i;#s;constructor(e,t,s){this.#e=e,this.#t=t,this.#r=s,this.#i=new L(e),this.#s=new P(e)}async createEntity({entity:e,fileHash:t,sourceFile:s,revision:a=new Date().toISOString(),isRootEntity:o=!1,isDeleted:n=!1,rbacTeams:d}){try{const{relations:l=[],...f}=e,p=O(JSON.stringify(f)),y=e.version??U,g=await this.#i.shouldSkipRevisionCreation(e.key,y,p,o,n);if(Array.isArray(d)&&await this.#o({entityKey:e.key,rbacTeams:d}),g)return{result:"skipped",entityKey:e.key};const h=await this.#i.shouldSetNewCurrentRevision({key:e.key,version:y,revision:a}),R=b({entity:{...e,revision:a,hash:p,isCurrent:h,isDefaultVersion:h,isDeleted:n,version:y},sourceFile:s,organizationId:this.#t,projectId:this.#r,source:"file",fileHash:t}),{key:D,source:x,...S}=R;if(h&&(await this.#i.markAllRevisionsAsNotCurrent(D),await this.#s.markAllVersionsAsNotDefault(D)),V.isDevelopMode&&!V.REDOCLY_INTERNAL_DEV)return await this.#n(R,l),{result:"created",entityKey:e.key,entityRevision:a,entityVersion:y};const A=this.#e.client.insert(r).values(R).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:S}),N=l?.length&&l.length>0?this.#e.client.insert(i).values(l.map(k=>K({relation:k,sourceFile:s,fileHash:t,sourceKey:e.key,sourceVersion:y,sourceRevision:a??null,organizationId:this.#t,projectId:this.#r}))).onConflictDoNothing({target:[i.sourceKey,i.targetKey,i.sourceVersion,i.targetVersion,i.sourceRevision,i.targetRevision,i.sourceToTargetRelation]}).run():Promise.resolve();return await E([A,N],w,async k=>k),{result:"created",entityKey:e.key,entityRevision:a,entityVersion:y}}catch(l){return u.error("Error adding entity",l),{result:"error",entityKey:e.key}}}async deleteEntity(e){try{return await this.#e.client.delete(r).where(c(r.key,e)),e}catch(t){return u.error("Error deleting entity",t),null}}async deleteEntities(e){try{const t=C(e);if(!t)return!1;const s=await this.#e.client.delete(r).where(t).returning({key:r.key,source:r.source,isCurrent:r.isCurrent,isDefaultVersion:r.isDefaultVersion,version:r.version});if(s.length===0)return!0;const a=s.reduce((o,n)=>((n.isCurrent||n.isDefaultVersion)&&o.add(n.key),o),new Set);if(a.size===0)return!0;await E(Array.from(a),w,async o=>this.#i.ensureDefaultAndCurrentRevisionForKey(o));for(const o of s)await this.#e.client.delete(i).where(T(m(c(i.sourceKey,o.key),...o.version?[c(i.sourceVersion,o.version)]:[v(i.sourceVersion)]),m(c(i.targetKey,o.key),...o.version?[c(i.targetVersion,o.version)]:[v(i.targetVersion)])));return!0}catch(t){return u.error("Error deleting entities",t),!1}}async deleteEntityRelation(e){try{return await this.#e.client.delete(i).where(c(i.id,e)),e}catch{return null}}async softDeleteEntities(e,t,s){try{const a=e.map(n=>{const d={type:n.type,key:n.key,title:n.title,summary:n.summary??void 0,tags:n.tags??void 0,metadata:n.metadata??void 0,git:n.git??void 0,contact:n.contact??void 0,links:n.links??void 0,version:n.version??void 0};return this.createEntity({entity:d,revision:t,sourceFile:n.sourceFile??"",fileHash:s,isDeleted:!0})});return await E(a,w,async n=>n)}catch(a){return u.error("Error soft deleting entities",a),[]}}async deleteEntityRelations(e){try{const t=C(e);return t?(await this.#e.client.delete(i).where(t),!0):!1}catch(t){return u.error("Error deleting entity relations",t),!1}}async upsertEntityRelation(e){if(!e)return null;try{const{sourceKey:t,targetKey:s,sourceVersion:a,targetVersion:o,sourceRevision:n,targetRevision:d,...l}=e,f=await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.sourceKey,i.targetKey,i.sourceVersion,i.targetVersion,i.sourceRevision,i.targetRevision,i.sourceToTargetRelation],set:l}).returning();return f?.length?f[0]:null}catch(t){return u.error("Error creating entity relation",t),null}}async#n(e,t){const{key:s,source:a,version:o,isDefaultVersion:n,...d}=e,p=(await this.#e.client.select({id:r.id}).from(r).where(m(c(r.key,s),c(r.source,a??"file"),o?c(r.version,o):v(r.version))).limit(1).run()).rows.length>0?this.#e.client.update(r).set(d).where(m(c(r.key,s),c(r.source,a??"file"),o?c(r.version,o):v(r.version))).run():this.#e.client.insert(r).values(e).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:d}).run(),y=t?.map(g=>{const h=K({relation:g,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#t,projectId:this.#r});return this.#e.client.insert(i).values(h).onConflictDoUpdate({target:[i.sourceKey,i.targetKey,i.sourceVersion,i.targetVersion,i.sourceRevision,i.targetRevision,i.sourceToTargetRelation],set:h}).run()})??[];await E([p,...y],w,async g=>g)}async updateEntityScorecardsStatus(e,t){try{return(await this.#e.client.update(r).set({scorecardsStatus:t}).where(c(r.id,e)).returning()).length>0}catch(s){return u.error("Error updating entity scorecards status",s),!1}}async updateEntityScorecardsStatusIfCalculating(e,t){try{return(await this.#e.client.update(r).set({scorecardsStatus:t}).where(F`${r.id} = ${e} AND ${r.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}catch(s){return u.error("Error updating entity scorecards status if calculating",s),!1}}async#o({entityKey:e,rbacTeams:t}){try{await this.#e.client.insert(I).values(z({rbacTeams:t,entityKey:e,organizationId:this.#t,projectId:this.#r})).onConflictDoUpdate({target:[I.entityKey],set:{rbacTeams:JSON.stringify(t)}}).run()}catch(s){u.error("Error saving entity attributes",s)}}async setEntitiesAsOutdated(e){try{const t=C(e);await this.#e.client.update(r).set({scorecardsStatus:"OUTDATED"}).where(t)}catch(t){u.error("Error updating entities as outdated",t)}}}export{re as CatalogEntitiesLocalWriteRepository};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{entityRelationFileSchema as m}from"@redocly/config";import{removeLeadingSlash as E}from"@redocly/theme/core/utils";import{toKebabCase as u}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as v}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as y}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as d}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as R}from"../../../../../utils/rbac.js";import{envConfig as h}from"../../../../../config/env-config.js";import{resolveEntityVersion as A}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as T}from"../../../utils/ajv-validator.js";const C=3;class M{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const e=this.#t(t);await v(Array.from(e.values()),C,async a=>{for(const{description:i,version:r}of a)try{const o=i.hash;if(!o)continue;if(!((await this.fileHashManager.getByPath(i.realRelativePath))?.hash!==o||this.#e||h.FORCE_CATALOG_CACHE_REVALIDATE
|
|
1
|
+
import{entityRelationFileSchema as m}from"@redocly/config";import{removeLeadingSlash as E}from"@redocly/theme/core/utils";import{toKebabCase as u}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as v}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as y}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as d}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as R}from"../../../../../utils/rbac.js";import{envConfig as h}from"../../../../../config/env-config.js";import{resolveEntityVersion as A}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as T}from"../../../utils/ajv-validator.js";const C=3;class M{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const e=this.#t(t);await v(Array.from(e.values()),C,async a=>{for(const{description:i,version:r}of a)try{const o=i.hash;if(!o)continue;if(!((await this.fileHashManager.getByPath(i.realRelativePath))?.hash!==o||this.#e||h.FORCE_CATALOG_CACHE_REVALIDATE)){p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,i.realRelativePath,o,c.UP_TO_DATE);continue}const s=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(i.realRelativePath);h.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:Array.from(s).map(g=>g.split(":")[0])}),s.clear());const l=new Date().toISOString();await this.processApiDescription(i,l,r,s),await this.#a(s,i.realRelativePath,l,o),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,i.realRelativePath,o,c.UP_TO_DATE)}catch(o){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${i.realRelativePath}`),this.context.logger.warn(o)}}),await this.#i()}#t(t){const e=new Map;for(const a of t)if(!(a.isVirtual||!a.hash))try{const i=this.#o(a),r=this.mapApiDescriptionToEntity(a,i),o=e.get(r.key)??[];o.push({description:a,version:i}),e.set(r.key,o)}catch(i){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(i)}return e}#i=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({paginationParams:{limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:a})=>a)},{field:"is_current",operator:"equal",value:!0}]}}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:a})=>a)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#a=async(t,e,a,i)=>{if(t.size===0||h.FORCE_CATALOG_CACHE_REVALIDATE)return;const r=Array.from(t).map(n=>{const[s,l]=n.split(":");return{key:s,version:l}}),o=Array.from(new Set(r.map(({key:n})=>n))),f=r.map(({key:n,version:s})=>({op:y.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:s}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:a,fileHash:i,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:y.OR,conditions:f},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#o(t){const e=t.document?.info?.version??t.definition?.info?.version??null,a=A(e,t.realRelativePath);return a.success?a.version??d:d}validateEntityRelationFileSchema(t){T(m,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(t)}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(t);return R(a||{fsPath:t},e||{})}resolveEntityKey({realRelativePath:t,customKey:e,extensionPattern:a}){const i=this.#r(t,a);return typeof e=="string"&&e.trim()?u(e.trim()):i}#r(t,e){let i=E(t);for(;/^@[^/]+\//.test(i);)i=i.replace(/^@[^/]+\//,"");i=i.replace(/\/@[^/]+/g,"");const r=e?i.replace(e,""):i.replace(/\.[^.]+$/,"");return u(r.replace(/[\\/]/g,"-"))}}export{M as BaseApiEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CATALOG_ENTITIES_FILES_REGEX as E,ENTITY_SCHEMA_EXCLUDED_FOLDERS as d}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as l,FileType as a}from"../../../../persistence/file-hashes/types.js";import{OPERATORS as u}from"../../../../providers/database/pagination/constants.js";import{promiseMapLimit as m}from"../../../../utils/async/promise-map-limit.js";import{VERSION_NOT_SPECIFIED as p}from"@redocly/theme/core/constants";import{parseEntities as h}from"../../../../web-server/routes/catalog/parsers/entities/parse-entities.js";import{envConfig as g}from"../../../../config/env-config.js";import{extractFileContent as y}from"../../entities/extract-file-content.js";import{resolveEntityVersion as I}from"../../utils/resolve-entity-version.js";import{catalogDataCollector as f}from"../../utils/catalog-data-collector.js";const T=15;class ${#t;#e;#i;#r;#s;constructor({fileHashManager:e,context:t,catalogEntitiesService:i,catalogConfig:o,shouldCalculateEntities:s}){this.#t=e,this.#e=t,this.#i=i,this.#r=o,this.#s=s}async extract(e){try{if(e&&this.#o(e)){await this.#n(e);return}await this.#t.markAllAsOutdated(a.ENTITY_DEFINITION);const i=this.#e.fs.scan(E).filter(({relativePath:o})=>this.#o(o));i.length&&f.addExtractor("fs"),await m(i,T,async({relativePath:o})=>{await this.#n(o)}),await this.#f()}catch(t){this.#e.logger.error("Error extracting entities.",t)}}#o=e=>!!(e.match(E)&&!d.some(t=>e.includes(t)));#n=async e=>{try{const t=await y(e,this.#e);if(!t){this.#e.logger.warn(`Error extracting content from ${e}.`);return}const i=await this.#t.computeFileHash(t);if(!((await this.#t.getByPath(e))?.hash!==i||this.#s||g.FORCE_CATALOG_CACHE_REVALIDATE
|
|
1
|
+
import{CATALOG_ENTITIES_FILES_REGEX as E,ENTITY_SCHEMA_EXCLUDED_FOLDERS as d}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as l,FileType as a}from"../../../../persistence/file-hashes/types.js";import{OPERATORS as u}from"../../../../providers/database/pagination/constants.js";import{promiseMapLimit as m}from"../../../../utils/async/promise-map-limit.js";import{VERSION_NOT_SPECIFIED as p}from"@redocly/theme/core/constants";import{parseEntities as h}from"../../../../web-server/routes/catalog/parsers/entities/parse-entities.js";import{envConfig as g}from"../../../../config/env-config.js";import{extractFileContent as y}from"../../entities/extract-file-content.js";import{resolveEntityVersion as I}from"../../utils/resolve-entity-version.js";import{catalogDataCollector as f}from"../../utils/catalog-data-collector.js";const T=15;class ${#t;#e;#i;#r;#s;constructor({fileHashManager:e,context:t,catalogEntitiesService:i,catalogConfig:o,shouldCalculateEntities:s}){this.#t=e,this.#e=t,this.#i=i,this.#r=o,this.#s=s}async extract(e){try{if(e&&this.#o(e)){await this.#n(e);return}await this.#t.markAllAsOutdated(a.ENTITY_DEFINITION);const i=this.#e.fs.scan(E).filter(({relativePath:o})=>this.#o(o));i.length&&f.addExtractor("fs"),await m(i,T,async({relativePath:o})=>{await this.#n(o)}),await this.#f()}catch(t){this.#e.logger.error("Error extracting entities.",t)}}#o=e=>!!(e.match(E)&&!d.some(t=>e.includes(t)));#n=async e=>{try{const t=await y(e,this.#e);if(!t){this.#e.logger.warn(`Error extracting content from ${e}.`);return}const i=await this.#t.computeFileHash(t);if(!((await this.#t.getByPath(e))?.hash!==i||this.#s||g.FORCE_CATALOG_CACHE_REVALIDATE)){f.increaseSkippedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE);return}const r=this.#a(t.entities,e);if(!r)return;const n=await this.#i.getEntityKeysAndVersionsBySourceFile(e);await this.#c(r,e,i,n),await this.#l(n,e),f.increaseProcessedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE)}catch(t){this.#e.logger.warn(`Error processing file "${e}". ${t instanceof Error?t.message:String(t)}.`)}};#a=(e,t)=>{try{return h(e,this.#r)}catch(i){return this.#e.logger.warn(`Error validating entities in "${t}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(e,t,i,o)=>{for(const s of e)try{const r=I(s.version,t);if(!r.success){this.#e.logger.warn(`Entity "${s.key}" in file "${t}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...s,version:r.version};if(await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:t,fileHash:i}),s.key){const c=r.version??p;o.delete(`${s.key}:${c}`)}}catch(r){const n=s.key??"unknown";this.#e.logger.warn(`Error processing entity "${n}" from "${t}". ${r instanceof Error?r.message:String(r)}.`)}};#l=async(e,t)=>{if(e.size===0)return;const i=Array.from(e).map(r=>{const[n,c]=r.split(":");return{key:n,version:c}}),o=Array.from(new Set(i.map(({key:r})=>r))),s=i.map(({key:r,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:r},{field:"version",operator:"equal",value:n}]}));await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:s},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:t}]})};#f=async()=>{const e=await this.#t.getAllOutdated(a.ENTITY_DEFINITION);if(!e||e.length===0)return;const t=await this.#i.getEntities({paginationParams:{limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:e.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}}});!t||t.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:t.items.map(({key:i})=>i)}),await this.#t.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:l.OUTDATED}]}))}}export{$ as FsEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import w from"path";import{lintConfig as A,loadConfig as T,createConfigTypes as U}from"@redocly/openapi-core";import{deepMerge as $}from"../../../../../utils/object/deep-merge.js";import{logger as d}from"../../../../tools/notifiers/logger.js";import{BRANCH_ENV_PREFIX as L}from"../../../../../constants/common.js";import{sanitizeBranchName as x}from"../../../../utils/envs/sanitize-branch-name.js";import{envConfig as C}from"../../../../config/env-config.js";import{safeParsePartial as E}from"../../safe-parse.js";import{formatConfigProblem as B}from"../../format-error.js";import{ExternalResolver as j}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as q}from"../../resolve-mutual-exclusion.js";function g(e,t,s,r){t in e&&e[t]&&typeof e[t]=="string"&&(/^https?:\/\/.*/.test(e[t])||r(new Error(`Invalid ${s} URL: "${e[t]}". ${s} must start with "http://" or "https://".`)))}function N(e,t){if("access"in e&&e.access&&typeof e.access=="object"){const s=e.access;g(s,"logoutReturnUrl","access.logoutReturnUrl",t),g(s,"residency","access.residency",t);const r=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const c of r)c in s&&s[c]!==void 0&&c in e&&e[c]!==void 0&&t(new Error(`Property '${c}' is defined both at root level and in 'access' object. Please use 'access.${c}' to define this configuration.`))}}async function G(e,t,s,r){const u=t.getFileInfo(e)?.realRelativePath||e;async function a(){const l=new j(t),p=w.join(t.cwd,u),i=await T({configPath:p,externalRefResolver:l}),f=await r(i.resolvedConfig);if(f===void 0)return i.resolvedConfig;const P=[...i.document?.source?await A({config:i,externalConfigTypes:U(f,i)}):[],...i.document?.source?q(i.resolvedConfig,i.document?.source):[]];if(P.length>0)for(const b of P)s(new Error(B(b,t.cwd)));return i.resolvedConfig}const n=await t.exists(e)?await a():{},R=k(n),y=await r(n);g(n,"residency","Residency",s),g(n,"logoutReturnUrl","Logout return URL",s),N(n,s);let m=y?E(y,n):n;const{env:h}=m;if(h){const l=C.REDOCLY_ENV,p=h[l]||{},i=C.PUBLIC_REDOCLY_BRANCH_NAME||"",f=i?x(i):"",v=f&&h[`${L}${f}`]||{};m=$(m,v,p)}const o=I(m,R);if(o.imports&&o.imports.length>0){d.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const l=new Set([...o.plugins||[],...o.imports.map(p=>w.posix.join(p,"plugin.js"))]);o.plugins=Array.from(l),delete o.imports}if(o.catalog&&(d.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),o.catalogClassic={...o.catalog},delete o.catalog),o.scorecard&&(d.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),o.scorecardClassic=o.scorecard,delete o.scorecard),o.search?.ai){d.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const l={...o.search?.ai,...o.aiAssistant,suggestions:o.aiAssistant?.suggestions?.length?o.aiAssistant.suggestions:o.search?.ai.suggestions||[]};o.aiAssistant=l,delete o.search.ai}return _(o)}function _(e){const t={...e},r={..."access"in e&&e.access&&typeof e.access=="object"?e.access:{}},c=["requiresLogin","logoutReturnUrl","residency","sso","rbac"],u=[];for(const a of c){const n=t[a];n!==void 0&&(u.push(a),a==="requiresLogin"&&r.requiresLogin===void 0&&(r.requiresLogin=n),a==="logoutReturnUrl"&&r.logoutReturnUrl===void 0&&(r.logoutReturnUrl=n),a==="residency"&&r.residency===void 0&&(r.residency=n),a==="sso"&&r.sso===void 0&&(r.sso=n),a==="rbac"&&r.rbac===void 0&&(r.rbac=n),delete t[a])}return u.length>0&&d.warn(`The following properties at root level are deprecated: ${u.join(", ")}. Please move them to the 'access' object.`),Object.keys(r).length>0&&(t.access=r),t}function k(e){if(!e.theme)return[];d.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const t=[];for(const s of Object.keys(e.theme))e[s]==null?t.push(s):d.warn(`Detected both '${s}' and 'theme.${s}' properties in redocly.yaml. The 'theme.${s}' property will be ignored and needs to be removed or merged into the '${s}'.`);return t}function I(e,t){if(!e.theme||t.length===0)return e;const s={...e};for(const r of t)s[r]=e.theme[r];return delete s.theme,s}export{_ as ensureAccessBackwardsCompatibility,G as readAndValidateConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as u,INVITE_SLUG as h,PUBLIC_RBAC_SCOPE_ITEM as m,UI_ACCESSIBLE_CONFIG_PROPS as P,CONFIG_FILE_NAME as n,DEFAULT_SSO_IDP_TITLE as _}from"../../../constants/common.js";import{envConfig as T}from"../../config/env-config.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as p}from"../nav-utils.js";import{resolveLogoConfig as F}from"./resolve-logo.js";import{extractTeamNames as E}from"./extract-team-names.js";import{resolveProductsConfig as O}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as A}from"./resolve-catalog-entities.js";import{telemetryTraceStep as j}from"../../../cli/telemetry/helpers/trace-step.js";async function q(r){return{id:"Default Theme",async processContent(e){await j("build.plugin.default_theme",async()=>{const t=v(e),i=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,o=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:h,[c]:m,fsPath:h,templateId:o}),r.devLogin&&i){const a={frontmatter:{},seo:{title:"Login page"},authIdps:S(t),rbac:{teams:E(e.getConfig().access?.rbac)}},l=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:a})})}else if(t.length>1){const a={frontmatter:{},seo:{title:"Login page"},authIdps:S(t)},l=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:a})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),T.isDevelopMode&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:i,outdir:o}=e,a=e.getConfig(),{navbar:l,footer:D,userMenu:g,search:f,breadcrumbs:I,products:b}=a,C=Object.keys(a?.ssoDirect||{}).length>0,d=y(a),L={navFile:n,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...k(a),navbar:await p(l,i,e,t,L),footer:await p(D,i,e,t,L),breadcrumbs:{...I,prefixItems:await p(I?.prefixItems||[],i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},userMenu:{...g,hide:g?.hide??!C,menu:await p(g?.items,i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},logo:await F(a.logo,n,o,t.fs),auth:{idpsInfo:v(e),devLogin:r.devLogin&&C},products:await O(b,e,t),search:{...f,suggestedPages:await p(f?.suggestedPages,i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await A(a.entitiesCatalog,n,o,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(r){const e=r.getConfig().ssoDirect;return Object.entries(e||{}).map(([i,o])=>({idpId:i,type:o.type,title:o.title}))}function S(r){return T.LOCALHOST_LOGIN?r:r.filter(e=>e.title!==_)}function k(r){const e={};for(const t of P)r[t]&&(e[t]=r[t]);return e}export{q as defaultThemePlugin,k as pickUiAccessibleConfig};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{logger as n}from"../../../../../tools/notifiers/logger.js";import{canAccessResource as
|
|
1
|
+
import{logger as n}from"../../../../../tools/notifiers/logger.js";import{canAccessResource as U}from"../../../../../utils/rbac.js";import{ApigeeDevOnboardingIntegrationAuthType as w,APIGEE_VERSION as m}from"./types.js";import{AlgorithmTypes as D}from"../../../../../web-server/jwt/types.js";import*as S from"../../../../../web-server/jwt/jwt.js";import{getFirstNameFromClaims as k,getLastNameFromClaims as T}from"../../../utils.js";import{HttpError as b}from"../../../../../utils/errors.js";const f="developer.service.DeveloperDoesNotExist",$=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||"",...s.callbackUrl!==void 0?{callbackUrl:s.callbackUrl}:{},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=C(s)):(n.info("Requesting apigee access token"),h=C(s));try{return(await h).token}catch(e){throw h=null,e}}async function C({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
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
|
|
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
|
|
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 S.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,D.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 d=await o.text(),c=this.getErrorMessage(d);if(c===f){const p=this.userClaims,g=k(p),u=T(p),l=this.email;return await this.createDeveloper(this.email,g,u,l),await this.fetchData(e,t)}throw o.status!==404&&n.warn(`${r.toUpperCase()} request to "${i}" failed with ${o.status} code`),new b(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=>U(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||[],...e.callbackUrl!==void 0?{callbackUrl:e.callbackUrl}:{},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:P(i.expiresAt,$)}),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={attributes:v({...i.attributes,...r})};t.callbackUrl!==void 0&&(o.callbackUrl=t.callbackUrl);const d=await this.fetchData(a,{headers:{"Content-type":"application/json"},body:JSON.stringify(o),method:"PUT"});return A(d)}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:P(t.expiresAt,$)}),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 b(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})}),d=o.apiProducts.filter(c=>!a.apiProductIds.includes(c.apiproduct)).map(c=>c.apiproduct);return await Promise.all(d.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(u=>u.apiProductsStatus.find(l=>l.id===e))),r=p=>i.find(g=>g.credentials?.find(l=>l.status===p&&l.apiProductsStatus.find(E=>E.id===e))),o=t?i.map(p=>{if(p.credentials?.find(u=>u.status==="approved"&&u.apiProductsStatus.find(l=>l.id===e)))return{id:p.id,title:p.name}}).filter(Boolean):void 0,d=r("approved");if(d)return{status:"ACCEPTED",appId:d.id,apps:o};const c=r("pending");return c?{status:"PENDING",appId:c.id,apps:o}:{status:"NONE"}}}function P(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 +1 @@
|
|
|
1
|
-
import{requireAuthMiddleware as
|
|
1
|
+
import{requireAuthMiddleware as e}from"../middlewares/auth.js";import{integrationsMiddleware as d}from"../middlewares/integrations.js";import{listApps as g,createApp as l,getApp as c,createCredential as n,updateCredential as k,deleteCredential as o,deleteApp as y,updateApp as m,getLogs as f,getLogDetails as A}from"./apps.js";import{getMeta as C}from"./meta.js";import{getApiAccessStatus as b,listApiProducts as r}from"./products.js";function w(p,a){const i=a.getConfig().developerOnboarding?.adapters||[],s=a.getConfig().access?.rbac||{},t=a.globalData.apiProducts||{};i&&(p.get("/api/api-keys/meta",e(),C(a)),p.get("/api/api-keys/apps",e(),d(i,t,s),g(a)),p.post("/api/api-keys/apps",e(),d(i,t,s),l(a)),p.get("/api/api-keys/apps/:id",e(),d(i,t,s),c(a)),p.put("/api/api-keys/apps/:id",e(),d(i,t,s),m(a)),p.delete("/api/api-keys/apps/:id",e(),d(i,t,s),y(a)),p.post("/api/api-keys/apps/:id/credentials",e(),d(i,t,s),n(a)),p.put("/api/api-keys/apps/:id/credentials/:credentialId",e(),d(i,t,s),k(a)),p.delete("/api/api-keys/apps/:id/credentials/:credentialId",e(),d(i,t,s),o(a)),p.get("/api/api-keys/apps/:id/logs/:logId",e(),d(i,t,s),A()),p.get("/api/api-keys/apps/:id/logs",e(),d(i,t,s),f()),p.get("/api/api-keys/api-products",e(),d(i,t,s),r(a)),p.get("/api/api-keys/api-products/:id/access",e(),d(i,t,s),b()))}export{w as installRoutes};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function i(t){const n={adapters:(t.getConfig().developerOnboarding?.adapters||[]).map(e=>{const o=e.type==="APIGEE_X"||e.type==="APIGEE_EDGE";return{id:"organizationName"in e?e.organizationName:"",type:e.type,capabilities:{callbackUrls:o}}})};return async e=>e.json(n,200,{"Cache-Control":"no-store"})}export{i as getMeta};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import*as e from"react";import a from"styled-components";import{useQuery as f}from"@tanstack/react-query";import{useParams as b}from"react-router-dom";import{Box as h,Flex as v}from"@redocly/portal-legacy-ui";import{Admonition as y}from"@redocly/theme/markdoc/components/Admonition/Admonition";import{useTranslate as E}from"../../../../client/app/hooks";import x from"../../../../client/app/CircularProgress";import{Container as A}from"./components/Container";import w from"./components/AppOverview";import T from"./components/ApiKeys";import C from"./components/ApiLogs";import
|
|
1
|
+
import*as e from"react";import a from"styled-components";import{useQuery as f}from"@tanstack/react-query";import{useParams as b}from"react-router-dom";import{Box as h,Flex as v}from"@redocly/portal-legacy-ui";import{Admonition as y}from"@redocly/theme/markdoc/components/Admonition/Admonition";import{useTranslate as E}from"../../../../client/app/hooks";import x from"../../../../client/app/CircularProgress";import{Container as A}from"./components/Container";import w from"./components/AppOverview";import T from"./components/ApiKeys";import C from"./components/ApiLogs";import k from"./components/CreateApiKey";import{Description as I}from"./components/Description";import{CallbackUrl as _}from"./components/CallbackUrl";const B="app-tab-actions-portal",m="api_keys",P="logs";function L(D){const{id:s}=b(),{isLoading:p,error:l,data:t}=f({queryKey:["APP:"+s],queryFn:()=>fetch(`/api/api-keys/apps/${s}`).then(n=>n.json())}),{translate:c}=E(),d=n=>o.findIndex(r=>r.id===n),o=[{id:m,name:c("dev.main.tab.appKeys","API keys"),content:e.createElement(e.Fragment,null,e.createElement(T,{credentials:t?.credentials,attributes:t?.attributes}),e.createElement(I,{text:t?.description}),t?.callbackUrl!==void 0&&e.createElement(_,{text:t.callbackUrl})),show:!0},{id:P,name:c("dev.main.tab.logs","Logs"),content:e.createElement(C,null),show:!!t?.supportsLogs}].filter(n=>n.show),[i,g]=e.useState(0),u=t?.canCreateKey&&i===d(m);return e.createElement(h,{my:"2rem"},e.createElement(A,null,p?e.createElement(v,{justifyContent:"center",mt:"2em"},e.createElement(x,null)):l?e.createElement(y,{type:"danger"},l?.message??"Something went wrong"):t?e.createElement(e.Fragment,null,e.createElement(w,{app:t}),e.createElement(K,null,e.createElement(S,null,o.map(({name:n},r)=>e.createElement("span",{key:n,className:i===r?"active":"",onClick:()=>g(r)},n))),e.createElement("div",{id:B}),u&&e.createElement(k,{initialEnabledApis:(t.credentials||[]).flatMap(n=>n.apiProductIds||[])})),e.createElement(z,null,o[i].content)):null))}const W=a.i`
|
|
2
2
|
display: inline-block;
|
|
3
3
|
width: 12px;
|
|
4
4
|
height: 12px;
|
|
5
5
|
background-repeat: no-repeat;
|
|
6
6
|
background-size: 12px 12px;
|
|
7
7
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='black' viewBox='0 0 451.847 451.847' width='12px' height='12px' %3E%3Cpath d='M225.923 354.706c-8.098 0-16.195-3.092-22.369-9.263L9.27 151.157c-12.359-12.359-12.359-32.397 0-44.751 12.354-12.354 32.388-12.354 44.748 0l171.905 171.915 171.906-171.909c12.359-12.354 32.391-12.354 44.744 0 12.365 12.354 12.365 32.392 0 44.751L248.292 345.449c-6.177 6.172-14.274 9.257-22.369 9.257z' /%3E%3C/svg%3E");
|
|
8
|
-
`,
|
|
8
|
+
`,K=a.div`
|
|
9
9
|
display: flex;
|
|
10
10
|
justify-content: space-between;
|
|
11
11
|
align-items: end;
|
|
12
|
-
`,
|
|
12
|
+
`,S=a.div`
|
|
13
13
|
display: flex;
|
|
14
14
|
align-items: center;
|
|
15
15
|
height: 42px;
|
|
@@ -27,6 +27,6 @@ import*as e from"react";import a from"styled-components";import{useQuery as f}fr
|
|
|
27
27
|
> span.active {
|
|
28
28
|
border-bottom: 2px solid var(--border-color-primary);
|
|
29
29
|
}
|
|
30
|
-
`,
|
|
30
|
+
`,z=a.div`
|
|
31
31
|
margin-top: var(--spacing-base);
|
|
32
|
-
`;export{
|
|
32
|
+
`;export{W as ArrowIcon,B as TAB_ACTIONS_PORTAL_ID,L as default};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import*as e from"react";import{useQueryClient as z,useMutation as
|
|
1
|
+
import*as e from"react";import{useQueryClient as z,useMutation as B,useQuery as H}from"@tanstack/react-query";import v from"styled-components";import{Flex as V}from"@redocly/portal-legacy-ui";import{Button as $}from"@redocly/theme/components/Button/Button";import{Admonition as A}from"@redocly/theme/markdoc/components/Admonition/Admonition";import{AppCustomAttributes as Q}from"@redocly/theme/components/ApiOnboarding/AppCustomAttributes";import{usePreloadHistory as G}from"../../../../client/app/usePreloadHistory";import{useTranslate as K}from"../../../../client/app/hooks";import W from"./components/ApisList";import{ButtonWithLoading as J}from"./components/ButtonWithLoading";import{Dialog as X}from"./components/Dialog";import{ButtonsContainer as Y}from"./components/RollAPIKey";import{MAX_DESCRIPTION_LENGTH as k,CharacterCounter as Z}from"./components/CharacterCounter";import{DialogHelperText as ee,DialogInputMultiline as S,DialogRow as c,DialogRowContent as p,DialogRowTitle as m,DialogTitleInput as te}from"./components/DialogStyledComponents";const Ce=e.forwardRef((le,w)=>{const{data:I}=H({queryKey:["DEV_ONBOARDING_META"],staleTime:1/0,queryFn:async()=>{const t=await fetch("/api/api-keys/meta");if(!t.ok)throw new Error(`Failed to load meta: ${t.status}`);return t.json()}}),d=(I?.adapters||[]).some(t=>t.capabilities.callbackUrls),[r,P]=e.useState(""),[n,D]=e.useState(""),[u,U]=e.useState(void 0),x=z(),[R,T]=e.useState({}),[N,O]=e.useState(!0),[g,h]=e.useState(""),[L,o]=e.useState(!1),E=G(),f=new URLSearchParams(E.location.search),[y,_]=e.useState([]),{translate:a}=K(),C=f.has("createApp");e.useEffect(()=>{C&&o(!0)},[C]);const F=e.useCallback((t,q)=>{T(t),O(q)},[]),l=B({mutationFn:()=>fetch("/api/api-keys/apps",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:r,name:r,description:n,callbackUrl:d?u:void 0,apiProductIds:y,attributes:R})}).then(t=>t.json()),onSuccess:t=>{t.error?h(t.error):(E.push("/apps/"+t.id),x.invalidateQueries({queryKey:["APPS"]}),s(),h(""))}}),b=()=>o(!0),s=()=>o(!1);e.useImperativeHandle(w,()=>({open:b}));const M=t=>{_(t||[])},j=async()=>{await l.mutateAsync()},i=/^[a-z][a-z0-9._\-$%#\s]*$/gi.test(r);return e.createElement(e.Fragment,null,e.createElement(X,{open:L,onOpen:b,onClose:s},e.createElement(ae,null,e.createElement(V,{justifyContent:"space-between",alignItems:"center",mb:"2em"},e.createElement(te,{error:!!r&&!i,value:r,onChange:t=>P(t.target.value),placeholder:a("dev.create.app.dialog.appName.placeholder","App name")}),!!r&&!i&&e.createElement(re,null,a("dev.create.app.dialog.appName.error","Name must start with a letter and can only contain: letters, numbers, spaces, ., _, -, $, %, #"))),e.createElement(c,null,e.createElement(m,{"data-translation-key":"dev.create.app.dialog.selectAPIs"},a("dev.create.app.dialog.selectAPIs","Select APIs")),e.createElement(p,null,e.createElement(W,{initialEnabledApis:f.getAll("apiId"),onChange:M}))),e.createElement(c,null,e.createElement(m,{"data-translation-key":"dev.create.app.dialog.description"},a("dev.create.app.dialog.description","Description")),e.createElement(p,null,e.createElement(S,{maxLength:k,value:n,onChange:t=>D(t.target.value),placeholder:a("dev.create.app.dialog.description.placeholder","Empty"),rows:6}))),e.createElement(Z,null,n.length,"/",k),d&&e.createElement(c,null,e.createElement(m,{"data-translation-key":"dev.create.app.dialog.callbackUrls"},a("dev.create.app.dialog.callbackUrls","Callback URLs")),e.createElement(p,null,e.createElement(S,{value:u,onChange:t=>U(t.target.value),placeholder:a("dev.create.app.dialog.callbackUrls.placeholder","https://example.com/callback"),rows:3}),e.createElement(ee,{"data-translation-key":"dev.create.app.dialog.callbackUrls.hint"},a("dev.create.app.dialog.callbackUrls.hint","Separate multiple URLs with a comma")))),e.createElement(Q,{onChange:F}),l.error?e.createElement(A,{type:"danger"},l.error.message):null,e.createElement(Y,null,e.createElement($,{onClick:s,size:"large",variant:"text"},a("dev.create.app.dialog.cancel","Cancel")),e.createElement(J,{variant:"primary",onClick:j,loading:l.isPending,disabled:!N||l.isPending||!i||y.length<1,"data-translation-key":"dev.create.app.dialog.create"},a("dev.create.app.dialog.create","Create application"))),g&&e.createElement(A,{type:"danger"},g))))}),ae=v.div`
|
|
2
2
|
width: 664px;
|
|
3
3
|
min-height: 428px;
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
|
-
`,
|
|
6
|
+
`,re=v.span`
|
|
7
7
|
padding-top: 5px;
|
|
8
8
|
color: var(--color-error-base);
|
|
9
9
|
font-size: 0.9em;
|
|
10
|
-
`;export{
|
|
10
|
+
`;export{Ce as CreateAppDialog};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import e,{useState as o}from"react";import a from"styled-components";import{EditIcon as i}from"@redocly/theme/icons/EditIcon/EditIcon";import{useTranslate as s}from"../../../../../client/app/hooks";import{EditCallbackUrlDialog as c}from"./EditCallbackUrlDialog";const u=({text:l})=>{const[r,t]=o(!1),{translate:n}=s();return e.createElement(e.Fragment,null,e.createElement(c,{open:r,onOpen:()=>t(!0),onClose:()=>t(!1),initialCallbackUrl:l}),e.createElement(m,null,e.createElement(p,{"data-translation-key":"dev.app.callbackUrls.title"},n("dev.app.callbackUrls.title","Callback URLs")),e.createElement(i,{onClick:()=>t(!0)})),e.createElement(g,null,l||"\u2014"))},m=a.div`
|
|
2
|
+
display: flex;
|
|
3
|
+
gap: var(--spacing-sm);
|
|
4
|
+
margin-bottom: var(--spacing-sm);
|
|
5
|
+
margin-top: var(--spacing-base);
|
|
6
|
+
|
|
7
|
+
svg {
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
}
|
|
10
|
+
`,p=a.div`
|
|
11
|
+
font-weight: var(--font-weight-bold);
|
|
12
|
+
`,g=a.div`
|
|
13
|
+
font-size: var(--font-size-base);
|
|
14
|
+
font-weight: var(--font-weight-regular);
|
|
15
|
+
max-width: 50%;
|
|
16
|
+
word-break: break-all;
|
|
17
|
+
`;export{u as CallbackUrl};
|
|
@@ -11,4 +11,5 @@ export declare const DialogTitleInput: import("styled-components").StyledCompone
|
|
|
11
11
|
error?: boolean;
|
|
12
12
|
}, never>;
|
|
13
13
|
export declare const DialogBodyWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
14
|
+
export declare const DialogHelperText: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
14
15
|
//# sourceMappingURL=DialogStyledComponents.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import o,{css as t}from"styled-components";const
|
|
1
|
+
import o,{css as t}from"styled-components";const l=o.div`
|
|
2
2
|
min-height: 44px;
|
|
3
3
|
margin: 11px 0;
|
|
4
4
|
display: flex;
|
|
@@ -52,4 +52,8 @@ import o,{css as t}from"styled-components";const a=o.div`
|
|
|
52
52
|
flex-direction: column;
|
|
53
53
|
min-width: 664px;
|
|
54
54
|
width: 100%;
|
|
55
|
-
|
|
55
|
+
`,x=o.div`
|
|
56
|
+
margin-top: var(--spacing-xs);
|
|
57
|
+
font-size: var(--font-size-sm);
|
|
58
|
+
color: var(--text-color-secondary);
|
|
59
|
+
`;export{d as DialogBodyWrapper,x as DialogHelperText,i as DialogInput,s as DialogInputMultiline,l as DialogRow,c as DialogRowContent,n as DialogRowTitle,p as DialogTitleInput};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as e from"react";import{useMutation as b,useQueryClient as U}from"@tanstack/react-query";import{useParams as C}from"react-router-dom";import{Button as E}from"@redocly/theme/components/Button/Button";import{H2 as w}from"@redocly/theme/components/Typography/H2";import{Admonition as P}from"@redocly/theme/markdoc/components/Admonition/Admonition";import{useTranslate as D}from"../../../../../client/app/hooks";import{Dialog as R}from"./Dialog";import{ButtonWithLoading as S}from"./ButtonWithLoading";import{ButtonsContainer as A}from"./RollAPIKey";import{DialogHelperText as T,DialogInputMultiline as x,DialogRow as K,DialogRowContent as j}from"./DialogStyledComponents";const z=p=>{const{id:o}=C(),{initialCallbackUrl:u,open:g,onOpen:k,onClose:s}=p,l=u||"",{translate:a}=D(),[r,n]=e.useState(l);e.useEffect(()=>{n(l)},[l]);const c=async()=>{await f(),s()},y=t=>{t.key==="Enter"&&!i&&c()},d=()=>{s(),n(l)},h=U(),{mutateAsync:f,isPending:i,error:m}=b({mutationKey:["UPDATE_APP"+o],mutationFn:async()=>{const t=await fetch(`/api/api-keys/apps/${o}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({callbackUrl:r})});if(!t.ok){const v=await t.json().catch(()=>null);throw new Error(v?.error||`Request failed with status ${t.status}`)}return t.json()},onSettled:()=>{h.invalidateQueries({queryKey:["APP:"+o]}),n(r)}});return e.createElement(R,{open:g,onClose:d,onOpen:k},e.createElement(e.Fragment,null,e.createElement(w,{"data-translation-key":"dev.edit.callbackUrls.dialog.title"},a("dev.edit.callbackUrls.dialog.title","Change callback URLs")),e.createElement(K,null,e.createElement(j,null,e.createElement(x,{value:r,onChange:t=>n(t.target.value),onKeyPress:y,placeholder:a("dev.edit.callbackUrls.dialog.placeholder","https://example.com/callback"),rows:3}),e.createElement(T,{"data-translation-key":"dev.edit.callbackUrls.dialog.hint"},a("dev.edit.callbackUrls.dialog.hint","Separate multiple URLs with a comma")))),m&&e.createElement(P,{type:"danger"},m.message," "),e.createElement(A,null,e.createElement(E,{onClick:d,"data-translation-key":"dev.edit.callbackUrls.dialog.cancel",variant:"text",size:"large"},a("dev.edit.callbackUrls.dialog.cancel","Cancel")),e.createElement(S,{variant:"primary",loading:i,onClick:c,disabled:i,"data-translation-key":"dev.edit.callbackUrls.dialog.save"},a("dev.edit.callbackUrls.dialog.save","Save changes")))))};export{z as EditCallbackUrlDialog};
|