@redocly/realm 0.135.0 → 0.136.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 +35 -0
- package/dist/cli/build/analytics/collect-analytics.js +1 -1
- package/dist/cli/build/analytics/collectors/get-skills-usage.d.ts +3 -0
- package/dist/cli/build/analytics/collectors/get-skills-usage.js +1 -0
- package/dist/client/templates/openapi-docs/helpers.js +1 -1
- package/dist/constants/common.d.ts +8 -0
- package/dist/constants/common.js +1 -1
- package/dist/server/api-routes/execute-api-route.js +1 -1
- package/dist/server/api-routes/helpers/enhance-context.d.ts +3 -1
- package/dist/server/api-routes/helpers/enhance-context.js +1 -1
- package/dist/server/api-routes/helpers/is-mock-server.d.ts +2 -0
- package/dist/server/api-routes/helpers/is-mock-server.js +1 -0
- package/dist/server/api-routes/mock-server/kv-state-store.d.ts +3 -0
- package/dist/server/api-routes/mock-server/kv-state-store.js +1 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.d.ts +3 -0
- package/dist/server/api-routes/mock-server/mock-js-executor.js +13 -0
- package/dist/server/config/env-config.d.ts +4 -0
- package/dist/server/config/env-schema.d.ts +10 -0
- package/dist/server/config/env-schemas/catalog.d.ts +3 -0
- package/dist/server/config/env-schemas/catalog.js +1 -1
- package/dist/server/config/env-schemas/feature-flags.d.ts +4 -0
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/constants/plugins/search.d.ts +1 -2
- package/dist/server/constants/plugins/search.js +1 -1
- package/dist/server/esbuild/plugins/on-rebuild.js +1 -1
- package/dist/server/fs/fs.js +1 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +27 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.js +12 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-publisher.js +1 -12
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +20 -0
- package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +42 -0
- package/dist/server/plugins/catalog-entities/database/consts.d.ts +5 -0
- package/dist/server/plugins/catalog-entities/database/consts.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.d.ts +3 -0
- package/dist/server/plugins/mcp/codemode/capabilities/index.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/capabilities/registry.js +1 -0
- package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +13 -0
- package/dist/server/plugins/mcp/codemode/capabilities/utils.js +7 -0
- package/dist/server/plugins/mcp/codemode/constants.d.ts +8 -0
- package/dist/server/plugins/mcp/codemode/constants.js +1 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.d.ts +4 -0
- package/dist/server/plugins/mcp/codemode/invoke-tool.js +1 -0
- package/dist/server/plugins/mcp/codemode/prompts.d.ts +6 -0
- package/dist/server/plugins/mcp/codemode/prompts.js +4 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.d.ts +10 -0
- package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.js +11 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.d.ts +2 -0
- package/dist/server/plugins/mcp/codemode/sandbox/polyfills.js +99 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +7 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +5 -0
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -0
- package/dist/server/plugins/mcp/codemode/types.d.ts +16 -0
- package/dist/server/plugins/mcp/codemode/types.js +0 -0
- package/dist/server/plugins/mcp/constants.d.ts +2 -0
- package/dist/server/plugins/mcp/constants.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +0 -4
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +30 -0
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +13 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +12 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.d.ts +9 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +6 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -0
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.d.ts +3 -21
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +5 -10
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -3
- package/dist/server/plugins/mcp/servers/mcp-server.d.ts +18 -0
- package/dist/server/plugins/mcp/servers/mcp-server.js +1 -0
- package/dist/server/plugins/mcp/types.d.ts +23 -8
- package/dist/server/plugins/mcp/utils/mode.d.ts +7 -0
- package/dist/server/plugins/mcp/utils/mode.js +1 -0
- package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +12 -60
- package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
- package/dist/server/plugins/mcp/utils.d.ts +8 -0
- package/dist/server/plugins/mcp/utils.js +1 -1
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +15 -3
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/search/engines/search-engine.d.ts +2 -1
- package/dist/server/plugins/search/index.js +1 -1
- package/dist/server/plugins/skills/discover-skills.d.ts +17 -0
- package/dist/server/plugins/skills/discover-skills.js +1 -0
- package/dist/server/plugins/skills/index.d.ts +3 -0
- package/dist/server/plugins/skills/index.js +1 -0
- package/dist/server/plugins/skills/utils/parse-skill.d.ts +18 -0
- package/dist/server/plugins/skills/utils/parse-skill.js +1 -0
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/sandbox/constants/host-functions.d.ts +3 -0
- package/dist/server/sandbox/constants/host-functions.js +1 -0
- package/dist/server/sandbox/constants/sandbox.d.ts +6 -0
- package/dist/server/sandbox/constants/sandbox.js +1 -0
- package/dist/server/sandbox/sandbox.d.ts +8 -0
- package/dist/server/sandbox/sandbox.js +3 -0
- package/dist/server/sandbox/types.d.ts +24 -0
- package/dist/server/sandbox/types.js +0 -0
- package/dist/server/sandbox/utils/eval-guest-code.d.ts +15 -0
- package/dist/server/sandbox/utils/eval-guest-code.js +1 -0
- package/dist/server/sandbox/utils/execution-budget.d.ts +11 -0
- package/dist/server/sandbox/utils/execution-budget.js +1 -0
- package/dist/server/sandbox/utils/setup-host-functions.d.ts +18 -0
- package/dist/server/sandbox/utils/setup-host-functions.js +5 -0
- package/dist/server/store.d.ts +4 -0
- package/dist/server/store.js +1 -1
- package/dist/server/types/plugins/common.d.ts +3 -0
- package/dist/server/types/plugins/search.d.ts +0 -1
- package/dist/server/types/plugins/skills.d.ts +16 -0
- package/dist/server/types/plugins/skills.js +0 -0
- package/dist/server/utils/cookie.d.ts +3 -0
- package/dist/server/utils/cookie.js +1 -1
- package/dist/server/utils/fetch-with-client.d.ts +10 -0
- package/dist/server/utils/fetch-with-client.js +1 -0
- package/dist/server/utils/skills/can-access-skill.d.ts +9 -0
- package/dist/server/utils/skills/can-access-skill.js +1 -0
- package/dist/server/utils/skills/get-accessible-skills.d.ts +5 -0
- package/dist/server/utils/skills/get-accessible-skills.js +1 -0
- package/dist/server/utils/skills/get-skill-url.d.ts +2 -0
- package/dist/server/utils/skills/get-skill-url.js +1 -0
- package/dist/server/web-server/auth.js +4 -4
- package/dist/server/web-server/middleware/apiKeyMiddleware.js +1 -1
- package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
- package/dist/server/web-server/middleware/corsMiddleware.d.ts +1 -0
- package/dist/server/web-server/middleware/corsMiddleware.js +1 -1
- package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
- package/dist/server/web-server/routes/ask-ai.js +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/catalog/helpers/create-entity-schema.d.ts +305 -256
- package/dist/server/web-server/routes/catalog/helpers/create-entity-update-schema.d.ts +46 -39
- package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.js +1 -1
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/routes/health.js +1 -1
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/a2a.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/constants.d.ts +14 -0
- package/dist/server/web-server/routes/mcp-routes/constants.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.d.ts +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.d.ts +4 -0
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -0
- package/dist/server/web-server/routes/mcp-routes/types.d.ts +34 -0
- package/dist/server/web-server/routes/mcp-routes/types.js +0 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +10 -0
- package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.js +1 -0
- package/dist/server/web-server/routes/page-data.js +1 -1
- package/dist/server/web-server/routes/semantic-search.js +1 -1
- package/dist/server/web-server/routes/skills/build-skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/build-skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/constants.d.ts +4 -0
- package/dist/server/web-server/routes/skills/constants.js +1 -0
- package/dist/server/web-server/routes/skills/skill-markdown.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skill-markdown.js +1 -0
- package/dist/server/web-server/routes/skills/skills-index.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-index.js +1 -0
- package/dist/server/web-server/routes/skills/skills-routes.d.ts +4 -0
- package/dist/server/web-server/routes/skills/skills-routes.js +1 -0
- package/dist/server/web-server/routes/skills/types.d.ts +12 -0
- package/dist/server/web-server/routes/skills/types.js +0 -0
- package/dist/server/web-server/utils/resolve-public-base-url.d.ts +4 -0
- package/dist/server/web-server/utils/resolve-public-base-url.js +1 -0
- package/dist/server/web-server/utils.js +1 -1
- package/dist/server/workers/api-routes-worker-pool.js +1 -1
- package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
- package/dist/server/workers/scorecards-worker-pool.js +1 -1
- package/dist/server/workers/worker-pool.d.ts +1 -0
- package/dist/server/workers/worker-pool.js +1 -1
- package/package.json +10 -10
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.d.ts +0 -5
- package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.js +0 -4
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.d.ts +0 -3
- package/dist/server/plugins/mcp/docs-mcp/codemode/sandbox.js +0 -7
- package/dist/server/plugins/mcp/docs-mcp/codemode/types.d.ts +0 -9
- package/dist/server/plugins/mcp/docs-mcp/tools/execute.js +0 -1
- package/dist/server/plugins/mcp/mode.d.ts +0 -9
- package/dist/server/plugins/mcp/mode.js +0 -1
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode/capabilities}/types.js +0 -0
- /package/dist/server/plugins/mcp/{docs-mcp → codemode}/tools/execute.d.ts +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import{and as h,eq as m,inArray as l,sql as S}from"drizzle-orm";import{entitiesRelationsTable as O}from"../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{entitiesTable as R}from"../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{fileHashesTable as a}from"../../../providers/database/databases/sqlite-db/schemas/file-hashes-table.js";import{FileHashStatus as T}from"../../../persistence/file-hashes/types.js";import{DELETE_IDS_CHUNK_SIZE as d,VACUUM_AFTER_PRUNED_ROWS as w}from"./consts.js";const p={prunedEntities:0,prunedRelations:0,affectedSourceFiles:[],vacuumed:!1};class u{static async pruneLocalRevisions({localConnection:i,maxRevisions:r,vacuumThreshold:n=w}){if(!Number.isFinite(r)||r<=0)return p;const t=i.client.client,o=await t.transaction(async s=>{const c=await s.all(S`
|
|
2
|
+
SELECT id, source_file
|
|
3
|
+
FROM (
|
|
4
|
+
SELECT id,
|
|
5
|
+
source_file,
|
|
6
|
+
is_current,
|
|
7
|
+
is_default_version,
|
|
8
|
+
ROW_NUMBER() OVER (
|
|
9
|
+
PARTITION BY key, version
|
|
10
|
+
ORDER BY revision DESC, id DESC
|
|
11
|
+
) AS revision_rank
|
|
12
|
+
FROM entities
|
|
13
|
+
WHERE source = 'file' AND source_file IS NOT NULL
|
|
14
|
+
)
|
|
15
|
+
WHERE revision_rank > ${r}
|
|
16
|
+
AND COALESCE(is_current, 1) = 0
|
|
17
|
+
AND COALESCE(is_default_version, 0) = 0
|
|
18
|
+
`);if(c.length===0)return null;const f=new Set;for(const e of c)e.source_file&&f.add(e.source_file);for(const e of u.#e(c.map(_=>_.id),d))await s.delete(R).where(l(R.id,e)).run();const E=await s.all(S`
|
|
19
|
+
SELECT id, source_file
|
|
20
|
+
FROM entities_relations r
|
|
21
|
+
WHERE r.source_file IS NOT NULL
|
|
22
|
+
AND (
|
|
23
|
+
(
|
|
24
|
+
r.source_revision != ''
|
|
25
|
+
AND NOT EXISTS (
|
|
26
|
+
SELECT 1 FROM entities e
|
|
27
|
+
WHERE e.key = r.source_key
|
|
28
|
+
AND e.revision = r.source_revision
|
|
29
|
+
AND (r.source_version = '' OR e.version = r.source_version)
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
OR (
|
|
33
|
+
r.target_revision != ''
|
|
34
|
+
AND NOT EXISTS (
|
|
35
|
+
SELECT 1 FROM entities e
|
|
36
|
+
WHERE e.key = r.target_key
|
|
37
|
+
AND e.revision = r.target_revision
|
|
38
|
+
AND (r.target_version = '' OR e.version = r.target_version)
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
`);for(const e of E)e.source_file&&f.add(e.source_file);for(const e of u.#e(E.map(_=>_.id),d))await s.delete(O).where(l(O.id,e)).run();const N=new Date().toISOString();for(const e of u.#e(Array.from(f),d))await s.update(a).set({status:T.OUTDATED,updatedAt:N}).where(l(a.filePath,e)).run();return{prunedEntities:c.length,prunedRelations:E.length,affectedSourceFiles:Array.from(f)}});if(!o)return p;const D=o.prunedEntities+o.prunedRelations;let A=!1;return D>=n&&(await t.run(S`VACUUM`),A=!0),{...o,vacuumed:A}}static async confirmPrunedFiles({localConnection:i,sourceFiles:r}){if(r.length===0)return;const n=i.client.client,t=new Date().toISOString();for(const o of u.#e(r,d))await n.update(a).set({status:T.UP_TO_DATE,updatedAt:t}).where(h(l(a.filePath,o),m(a.status,T.OUTDATED))).run()}static#e(i,r){const n=[];for(let t=0;t<i.length;t+=r)n.push(i.slice(t,t+r));return n}}export{u as CatalogEntitiesRevisionsPruner};
|
|
@@ -2,6 +2,11 @@ export declare const DEFAULT_CHUNK_SIZE = 20;
|
|
|
2
2
|
export declare const MAX_LOGGED_DB_ERROR_LENGTH = 1000;
|
|
3
3
|
export declare const MIN_RETRYABLE_BATCH_SIZE = 2;
|
|
4
4
|
export declare const MAX_BATCH_PAYLOAD_BYTES = 500000;
|
|
5
|
+
export declare const SCOPE_FILES_BATCH_SIZE = 50;
|
|
6
|
+
export declare const SYNC_SCAN_PAGE_SIZE = 1000;
|
|
7
|
+
export declare const DELETE_IDS_CHUNK_SIZE = 500;
|
|
8
|
+
export declare const DEFAULT_MAX_ENTITY_REVISIONS = 20;
|
|
9
|
+
export declare const VACUUM_AFTER_PRUNED_ROWS = 5000;
|
|
5
10
|
export declare const ENTITIES_UPSERT_SET: {
|
|
6
11
|
organizationId: import("drizzle-orm").SQL<unknown>;
|
|
7
12
|
projectId: import("drizzle-orm").SQL<unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sql as e}from"drizzle-orm";const t=20,c=1e3,
|
|
1
|
+
import{sql as e}from"drizzle-orm";const t=20,c=1e3,_=2,a=5e5,o=50,l=1e3,u=500,r=20,s=5e3,i={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,type:e`excluded.type`,title:e`excluded.title`,summary:e`excluded.summary`,tags:e`excluded.tags`,metadata:e`excluded.metadata`,git:e`excluded.git`,contact:e`excluded.contact`,links:e`excluded.links`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,hash:e`excluded.hash`,isCurrent:e`excluded.is_current`,isDefaultVersion:e`excluded.is_default_version`,isDeleted:e`excluded.is_deleted`,scorecardsStatus:e`excluded.scorecards_status`,lastSeenRunId:e`excluded.last_seen_run_id`},x={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,targetToSourceRelation:e`excluded.target_to_source_relation`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,isDeleted:e`excluded.is_deleted`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,lastSeenRunId:e`excluded.last_seen_run_id`},n={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,rbacTeams:e`excluded.rbac_teams`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`};export{n as ATTRIBUTES_UPSERT_SET,t as DEFAULT_CHUNK_SIZE,r as DEFAULT_MAX_ENTITY_REVISIONS,u as DELETE_IDS_CHUNK_SIZE,i as ENTITIES_UPSERT_SET,a as MAX_BATCH_PAYLOAD_BYTES,c as MAX_LOGGED_DB_ERROR_LENGTH,_ as MIN_RETRYABLE_BATCH_SIZE,x as RELATIONS_UPSERT_SET,o as SCOPE_FILES_BATCH_SIZE,l as SYNC_SCAN_PAGE_SIZE,s as VACUUM_AFTER_PRUNED_ROWS};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{and as
|
|
1
|
+
import{and as v,eq as c,isNull as E,or as T,sql as N}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as I}from"@redocly/theme/core/constants";import{sha1 as V}from"../../../../../utils/crypto/sha1.js";import{envConfig as F}from"../../../../../config/env-config.js";import{entitiesTable as i}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{convertFilterToWhereCondition as K}from"../../../../../providers/database/pagination/filter.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{RevisionRepository as x}from"../common/revision-repository.js";import{VersionRepository as z}from"../common/version-repository.js";import{EntityAttributesWriteRepository as H}from"../entityAttributes/entity-attributes-write-repository.js";import{createEntityDbRecord as O}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as k}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromFileSchema as P}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{createEntityRelationDbRecordFromDto as j}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{EntitiesReadRepository as G}from"./entities-read-repository.js";import{RelationsReadRepository as M}from"../relations/relations-read-repository.js";import{RelationsWriteRepository as $}from"../relations/relations-write-repository.js";const m=15;class ce{#e;#t;#n;#o;#i;#s;#a;#u;#r;constructor(e,s,r){this.#e=e,this.#i=s,this.#s=r,this.#t=new x(e),this.#n=new z(e),this.#o=new H(e),this.#a=new G(e),this.#u=new M(e),this.#r=new $(e,s,r)}async createEntity({entity:e,source:s,fileHash:r,sourceFile:o,isRootEntity:t,isDeleted:n,rbacTeams:l,errorOnSkip:d=!1,revision:h}){const{relations:u=[],...f}=e,y=V(JSON.stringify(f)),R=e.version??I,C=h??new Date().toISOString(),W=await this.#t.shouldSkipRevisionCreation(e.key,R,y,t,n);if(Array.isArray(l)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:l,organizationId:this.#i,projectId:this.#s}),W){if(d)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:g,hasCurrentRevision:L}=await this.#t.getCurrentRevisionInfo({key:e.key,version:R,revision:C}),w=O({entity:{...e,revision:C,hash:y,isCurrent:g,isDefaultVersion:g,isDeleted:n,version:R},organizationId:this.#i,projectId:this.#s,source:s,sourceFile:o??null,fileHash:r??null}),{key:D,..._}=w;if(g&&L&&(await this.#t.markAllRevisionsAsNotCurrent(D),await this.#n.markAllVersionsAsNotDefault(D)),F.isDevelopMode&&!F.REDOCLY_INTERNAL_DEV)return await this.#l(w,u);const A=await this.#e.client.insert(i).values(w).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:_}).returning();return A.length?(u&&await this.#r.createEntityRelations(u.map(S=>({...S,sourceKey:e.key,targetKey:S.key}))),k(A[0])):null}async updateEntity(e,s){const{shouldSetNewCurrentRevision:r,hasCurrentRevision:o}=await this.#t.getCurrentRevisionInfo({key:s.key,version:e.version??s.version??I,revision:s.revision});r&&o&&(await this.#t.markAllRevisionsAsNotCurrent(s.key),await this.#n.markAllVersionsAsNotDefault(s.key));const t=O({entity:{...s,...e,hash:V(JSON.stringify({...s,...e})),isCurrent:r,isDefaultVersion:r,createdAt:s.createdAt??void 0},organizationId:this.#i,projectId:this.#s,source:"remote",sourceFile:null,fileHash:null}),{key:n,source:l,scorecardsStatus:d,...h}=t,u=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...h,scorecardsStatus:N`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return u.length?k(u[0]):null}async setEntitiesAsOutdated(e){const s=K(e);await this.#e.client.update(i).set({scorecardsStatus:"OUTDATED"}).where(s)}async#l(e,s){const{key:r,source:o,version:t,...n}=e,h=await this.#e.client.select({id:i.id}).from(i).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(n).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:n}).returning(),u=s?.map(f=>{const y=P({relation:f,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#i,projectId:this.#s});return this.#e.client.insert(a).values(y).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:y}).run()})??[];return await p(u,m,async f=>f),k(h[0])}async softDeleteEntitiesWithRelations({filter:e,revision:s,fileHash:r}){const t={op:"AND",conditions:[e,{field:"is_deleted",operator:"equal",value:!1}]};for(;;){const n=await this.#a.getEntities({paginationParams:{filter:t,limit:500}});if(n.items.length===0)break;const l=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(l,s)}}async deleteEntity(e){return await this.#r.deleteEntityRelationsOnEntityRemoval(e),await this.#e.client.delete(i).where(c(i.id,e.id)),await this.#t.ensureDefaultAndCurrentRevisionForKey(e.key),e.id}async deleteEntities(e){const s=K(e);if(!s)return!1;const r=await this.#e.client.delete(i).where(s).returning({key:i.key,source:i.source,isCurrent:i.isCurrent,isDefaultVersion:i.isDefaultVersion,version:i.version});if(r.length===0)return!0;const o=r.reduce((t,n)=>((n.isCurrent||n.isDefaultVersion)&&t.add(n.key),t),new Set);if(o.size===0)return!0;await p(Array.from(o),m,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(T(v(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[E(a.sourceVersion)]),v(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[E(a.targetVersion)])));return!0}async updateEntityScorecardsStatus(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(c(i.id,e)).returning()).length>0}async updateEntityScorecardsStatusIfCalculating(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(N`${i.id} = ${e} AND ${i.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}async#c({entities:e,revision:s,fileHash:r}){return(await p(e,m,async t=>{const n={type:t.type,key:t.key,title:t.title,summary:t.summary??void 0,tags:t.tags??void 0,metadata:t.metadata??void 0,git:t.git??void 0,contact:t.contact??void 0,links:t.links??void 0,version:t.version??void 0};return this.createEntity({entity:n,sourceFile:t.sourceFile??"",fileHash:r,isDeleted:!0,errorOnSkip:!1,source:t.source,revision:s})})).filter(t=>t!==null)}async#d(e,s){if(e.length===0)return!0;const r=await p(e,m,async o=>(await this.#u.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const l=n.direction,d=n.sourceToTargetRelation,h=n.targetKey,u=l==="outgoing"?o.key:h,f=l==="outgoing"?h:o.key,y=l==="outgoing"?d:d.startsWith("reverse:")?d.slice(8):d;return!y||!u||!f?null:j({type:y,sourceKey:u,targetKey:f,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await p(r.flat(),m,async o=>this.#r.upsertEntityRelation(o)),!0}}export{ce as EntitiesWriteRepository};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import u from"node:path";import{removeLeadingSlash as w}from"@redocly/theme/core/utils";import{toKebabCase as m}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as f}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as v}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as E}from"./base.js";const g=15;class S extends E{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t,o){const a=w(t.realRelativePath),l=t.document.info.title,e=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:t.document["x-redocly-catalog-key"]});return{type:this.type,key:e,title:l,summary:t.document.info.description?v(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a},version:o}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t,o,a,l){if(!this.#t(t))throw new Error("Arazzo description has no source descriptions");const e=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:{...i},revision:o,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:e,source:"file"}),l.delete(`${i.key}:${a}`),await this.#e(t,i.key,i.version,a,o,l,e);const h=t.document.sourceDescriptions||[];await f(h,g,async r=>{if(!(r.type!=="openapi"||!r.url))try{const s=this.resolveSourceDescriptionUrl(r.url,t.realRelativePath);if(!s){!r.url.startsWith("http://")&&!r.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${r.url}`);return}const c=await this.context.cache.load(s,"load-oas");if(!(c.data&&Array.isArray(c.data)&&c.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${s}`);return}const p=c.data[0],y=this.resolveEntityKey({realRelativePath:p.realRelativePath,customKey:p.definition["x-redocly-catalog-key"]});await this.catalogEntitiesService.createEntityRelation({sourceKey:i.key,type:"relatesTo",targetKey:y,sourceFile:t.realRelativePath,fileHash:t.hash}),await this.#r(t,r.name,p,i.key,y,i.version,o)}catch(s){this.context.logger.warn(`Failed to create relation to OpenAPI source "${r.url}": ${s instanceof Error?s.message:"Unknown error"}`)}})}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,l,e,i,h)=>{try{const r=t.document.components?.inputs,s=r?Object.entries(r):[],c=[];for(const[n,p]of s)c.push(async()=>{const y=`${o}-${m(n)}`,d=await this.#a({schemaName:n,schema:p,description:t,parentKey:o,parentVersion:a,parentRevision:e,rbacTeams:h});i.delete(`${y}:${l}`),d&&await this.catalogEntitiesService.createEntityRelation({sourceKey:o,type:"uses",targetKey:d.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:e,targetRevision:e})});if(c.length===0)return;await f(c,g,n=>n())}catch(r){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${r instanceof Error?r.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:l,parentVersion:e,parentRevision:i,rbacTeams:h})=>{const r={type:"data-schema",key:`${l}-${m(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};try{return await this.catalogEntitiesService.createEntity({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:h,source:"file",revision:i})}catch(s){return this.context.logger.warn(`Failed to create data schema entity for ${t}: ${s instanceof Error?s.message:"Unknown error"}`),null}};#r=async(t,o,a,l,e,i,h)=>{const r=t.document.workflows||[];if(r.length===0)return;const s=new Set;for(const c of r)for(const n of c.steps||[]){if(!n.operationId)continue;const p=n.operationId.startsWith(`${o}.`)?n.operationId.substring(`${o}.`.length):n.operationId;p&&s.add(p)}s.size!==0&&await f(Array.from(s),g,async c=>{try{const n=`${e}-${m(c)}`;await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"uses",targetKey:n,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:i,targetVersion:i,sourceRevision:h,targetRevision:h})}catch(n){this.context.logger.warn(`Failed to create relation to operation "${c}": ${n instanceof Error?n.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),l=a.startsWith("@")?a.slice(1):a,[e]=l.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return w(u.posix.normalize(e));const i=u.posix.dirname(o);return e.startsWith(i+"/")?u.posix.normalize(e):u.posix.normalize(u.posix.join(i,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{S as ArazzoEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{removeLeadingSlash as
|
|
1
|
+
import{removeLeadingSlash as d}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as E}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{extractPartsFromChannelsMessageRef as S}from"../../../utils/extract-parts-from-channels-message-ref.js";const u=15;class T extends w{constructor(e){super("asyncapi",e)}mapApiDescriptionToEntity(e,t){const a=d(e.realRelativePath),r=e.document.info.title,s=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:s,title:r,summary:E(e.document.info.description),tags:e.document.info.tags?.map(n=>n.name),metadata:{specType:this.specType,descriptionFile:a},version:t}}async loadApiDescriptions(){return(await this.context.cache.load(".","asyncapi-docs")).data}async processApiDescription(e,t,a,r){const s=this.getRbacTeamsForDefinition(e.relativePath),n=this.mapApiDescriptionToEntity(e,a);await this.catalogEntitiesService.createEntity({entity:n,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,rbacTeams:s,source:"file"}),r.delete(`${n.key}:${a}`);const o=this.#a(e),[c,i]=await Promise.allSettled([this.#s(e,n.key,n.version,a,t,r,s),this.#n(o,e,n.key,n.version,a,t,r,s)]);c.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",c.reason),i.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",i.reason)}#a=e=>{const t=e.documentWithReferences.operations;return t?Object.entries(t).map(([a,r])=>({operationName:a,operation:r})):[]};#s=async(e,t,a,r,s,n,o)=>{const c=e.document.components?.schemas;if(!c)return;const i=Object.entries(c);if(i.length===0)return;const l=await $(i,u,async([h,m])=>{const R=`${t}-${f(h)}`,g=await this.#r({schemaName:h,schema:m,description:e,parentKey:t,parentVersion:a,parentRevision:s,rbacTeams:o});n.delete(`${R}:${r}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:g.key,sourceFile:e.realRelativePath,fileHash:e.hash,sourceVersion:a,targetVersion:a,sourceRevision:s,targetRevision:s})},this.context.logger);l.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${l.count.failed} failures out of ${i.length} schemas for ${e.realRelativePath}`)};#r=async({schemaName:e,schema:t,description:a,parentKey:r,parentVersion:s,parentRevision:n,rbacTeams:o})=>{const c=`${r}-${f(e)}`,i="title"in t?t.title??t.description:null,l=JSON.stringify(t),h={type:"data-schema",key:c,title:e,summary:i,tags:[],metadata:{specType:this.specType,schema:l},version:s};try{return await this.catalogEntitiesService.createEntity({entity:h,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:o,source:"file",revision:n})}catch(m){return this.context.logger.warn(`Failed to create data schema entity for ${e}: ${m instanceof Error?m.message:"Unknown error"}`),null}};#n=async(e,t,a,r,s,n,o,c)=>{if(!e.length)return;const i=await $(e,u,async({operationName:l,operation:h})=>{const m=await this.#o(h,l,t,a,r,n,c);o.delete(`${m}:${s}`)},this.context.logger);i.count.failed>0&&this.context.logger.warn(`Operation processing completed with ${i.count.failed} failures out of ${e.length} operations for ${t.realRelativePath}`)};#o=async(e,t,a,r,s,n,o)=>{const c=`${r}-${f(t)}`,i=await this.#c(e.messages??[],a,r),l=await this.#i(t,e,i,a,r,s,n,o);return l&&await this.#l({apiOperationKey:l.key,operation:e,descriptionUniqueKey:r,description:a,descriptionVersion:s,parentRevision:n}),c};#c=async(e,t,a)=>{if(!e||e.length===0)return[];const r=new Set;for(const s of e){let n=null;if("$ref"in s){const o=s.$ref.startsWith("#/channels/")?this.#e(s.$ref,t):s.$ref;if(o){const c=y(o);if(c?.componentName&&c.componentType==="messages"){const i=t.documentWithReferences.components?.messages[c.componentName];i?.payload&&"$ref"in i.payload&&i.payload.$ref&&(n=i.payload.$ref)}}}else s.payload&&"$ref"in s.payload&&s.payload.$ref&&(n=s.payload.$ref);if(n){const o=y(n);o?.componentName&&o.componentType==="schemas"&&r.add(`${a}-${f(o.componentName)}`)}}return Array.from(r)};#i=async(e,t,a,r,s,n,o,c)=>{const i={type:"api-operation",key:`${s}-${f(e)}`,title:t.title||e,summary:t.summary??"",tags:t.tags?.map(l=>l.name)??[],metadata:{method:t.action==="send"?"PUBLISH":"SUBSCRIBE",path:t.channel.address??"",payload:t.action==="receive"?a:[],responses:t.action==="send"?a:[]},version:n};try{return await this.catalogEntitiesService.createEntity({entity:i,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:c,source:"file",revision:o})}catch(l){return this.context.logger.warn(`Failed to create API operation entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}};#l=async({apiOperationKey:e,operation:t,descriptionUniqueKey:a,description:r,descriptionVersion:s,parentRevision:n})=>(await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:a,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),await this.#h(t,e,r,s,n),!Array.isArray(t.messages)||!t.messages?.length?[]:await this.#m(t.messages,e,r,a,s,n));#h=async(e,t,a,r,s)=>{e["x-catalogRelations"]?.length&&await p(e["x-catalogRelations"],u,async n=>{try{this.validateEntityRelationFileSchema(n),await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:n.type,targetKey:n.key,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:r,targetVersion:"",sourceRevision:s,targetRevision:""})}catch(o){this.context.logger.warn(`Error creating entity relation for operation ${t} based on custom property: ${o instanceof Error?o.message:"Unknown error"}`)}})};#m=async(e,t,a,r,s,n)=>e.length===0?[]:(await p(e,u,async c=>await this.#f(c,t,a,r,s,n)??"")).filter(c=>!!c);#f=async(e,t,a,r,s,n)=>"$ref"in e?this.#y(e,t,a,r,s,n):e.payload?this.#u(e,t,a,r,s,n):null;#y=async(e,t,a,r,s,n)=>{const o=e.$ref.startsWith("#/channels/")?this.#e(e.$ref,a):e.$ref;if(!o)return null;const c=y(o);if(!c||!c.componentName||c.componentType!=="messages")return null;const i=a.documentWithReferences.components?.messages[c.componentName];return!i?.payload||!("$ref"in i.payload)||!i.payload.$ref?null:this.#t(i.payload.$ref,t,a,r,s,n)};#e=(e,t)=>{const a=S(e);if(!a||!a.channelName||!a.messageName)return null;const r=t.documentWithReferences.channels?.[a.channelName];if(!r?.messages)return null;const s=r.messages[a.messageName];return!s||!("$ref"in s)||typeof s.$ref!="string"||!s.$ref.startsWith("#/components/messages/")?null:s.$ref};#u=async(e,t,a,r,s,n)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#t(e.payload.$ref,t,a,r,s,n);#t=async(e,t,a,r,s,n)=>{const o=y(e);if(!o||!o.componentName||o.componentType!=="schemas")return null;const c=`${r}-${f(o.componentName)}`;return await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:c,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),c}}export{T as AsyncApiEntitiesExtractor};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{buildSchema as
|
|
1
|
+
import{buildSchema as v,isObjectType as T,isScalarType as I,isEnumType as P,isInterfaceType as E,isUnionType as S,isInputObjectType as $,getNamedType as u,printType as F}from"graphql";import{removeLeadingSlash as A}from"@redocly/theme/core/utils";import{toKebabCase as d}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as k}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as R}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as j}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as D}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as L}from"./base.js";const O=15,b=15,C=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class U extends L{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:i,metadata:n}=a.data,s=v(i),r=j(i);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:r,schema:s,content:i,metadata:n})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t,e){const a=A(t.realRelativePath),i=t.relativePath.replace(/\.(gql|graphql)$/,""),n=this.#s(i.split("/").pop()||"GraphQL Schema"),s=this.#c(t.metadata?.tags),r=t.metadata?.["x-redocly-catalog-key"],h=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:typeof r=="string"?r:void 0,extensionPattern:/\.(gql|graphql)$/});return{type:this.type,key:h,title:n,summary:t.metadata?.description||null,tags:s.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,i){const{schema:n}=t;if(!n)throw new Error("GraphQL definition is missing a parsed schema");const s=this.getRbacTeamsForDefinition(t.relativePath),r=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:r,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:s,source:"file",revision:e}),i.delete(`${r.key}:${a}`),await Promise.all([this.#a(t,r.key,r.version,a,e,i,s),this.#f(t,r.key,r.version,a,e,i,s)])}#a=async(t,e,a,i,n,s,r)=>{const{schema:h}=t,c=h.getTypeMap(),l=this.#n(h),o=Object.entries(c).filter(([f])=>!f.startsWith("__")&&!C.has(f)&&!l.has(f));if(o.length===0)return;const p=await R(o,b,async([f,m])=>{const y=this.#e(f,e),g=await this.#l({typeName:f,type:m,description:t,parentKey:e,parentVersion:a,parentRevision:n,rbacTeams:r});s.delete(`${y}:${i}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"uses",targetKey:g.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:n,targetRevision:n})},this.#t);p.count.failed>0&&this.#t.warn(`Schema processing completed with ${p.count.failed} failures out of ${o.length} types for ${t.realRelativePath}`),await this.#p({description:t,descriptionUniqueKey:e,userTypes:o,parentRevision:n})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&k(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${d(t)}`;#r=t=>T(t)?"object":E(t)?"interface":S(t)?"union":P(t)?"enum":$(t)?"input":I(t)?"scalar":"unknown";#n=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const i=t.getMutationType();i&&e.add(i.name);const n=t.getSubscriptionType();return n&&e.add(n.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"QUERY",rootTypeName:a.name})}const i=t.getMutationType();if(i){const s=i.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"MUTATION",rootTypeName:i.name})}const n=t.getSubscriptionType();if(n){const s=n.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"SUBSCRIBE",rootTypeName:n.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const r=u(s.type);r&&!r.name.startsWith("__")&&a.push(this.#e(r.name,e))}const i=[],n=u(t.type);return n&&!n.name.startsWith("__")&&i.push(this.#e(n.name,e)),{inputTypes:a,returnTypes:i}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:i,parentVersion:n,parentRevision:s,rbacTeams:r})=>{const h=this.#e(t,i),c=e.description??null,l=this.#r(e),o={type:"data-schema",key:h,title:t,summary:c,tags:["graphql"],metadata:{specType:this.specType,typeKind:l,sdl:this.#h(e,a.schema)},version:n};try{return await this.catalogEntitiesService.createEntity({entity:o,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:r,source:"file",revision:s})}catch(p){return this.#t.warn(`Failed to create data schema entity for ${t}: ${p instanceof Error?p.message:"Unknown error"}`),null}};#h=(t,e)=>{const a=new Set,i=[],n=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const l=c.name;if(l.startsWith("__")||n.has(l)||a.has(l))return;const o=e.getType(l);o&&(a.add(l),i.push(o))};for(s(t);i.length>0;){const c=i.pop();if(T(c)){for(const o of c.getInterfaces?.()??[])s(o);const l=c.getFields();for(const o of Object.values(l)){s(u(o.type));for(const p of o.args??[])s(u(p.type))}}else if(E(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}else if(S(c))for(const l of c.getTypes())s(l);else if($(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}}const r=[t.name,...[...a].filter(c=>c!==t.name)],h=[];for(const c of r){const l=e.getType(c);l&&h.push(F(l))}return h.join(`
|
|
2
2
|
|
|
3
|
-
`)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:i})=>{const n=a.filter(([,s])=>
|
|
3
|
+
`)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:i})=>{const n=a.filter(([,s])=>T(s));n.length!==0&&await w(n,b,async([s,r])=>{const c=r.getInterfaces?.()??[];if(!c.length)return;const l=this.#e(s,e);await w([...c],5,async o=>{const p=this.#e(o.name,e);try{await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"implements",targetKey:p,sourceFile:t.realRelativePath,fileHash:t.hash,sourceRevision:i,targetRevision:i})}catch(f){this.#t.warn(`Failed to create 'implements' relation ${l} -> ${p}: ${f instanceof Error?f.message:"Unknown error"}`)}})})};#f=async(t,e,a,i,n,s,r)=>{const{schema:h}=t,c=this.#i(h);if(c.length===0)return;const o=(await R(c,O,async({fieldName:p,field:f,operationType:m,rootTypeName:y})=>{const g=await this.#y(p,f,m,y,t,e,a,n,r);s.delete(`${g}:${i}`)},this.#t)).count.failed;o>0&&this.#t.warn(`Operation extraction completed with ${o} failures out of ${c.length} operations for ${e}`)};#y=async(t,e,a,i,n,s,r,h,c)=>{const l=`${s}-${d(`${a.toLowerCase()}-${t}`)}`,{inputTypes:o,returnTypes:p}=this.#o(e,s),f=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:o,returnTypes:p,description:n,descriptionUniqueKey:s,descriptionVersion:r,parentRevision:h,rbacTeams:c});return f&&await this.#m({apiOperationKey:f.key,inputTypes:o,returnTypes:p,descriptionUniqueKey:s,description:n,descriptionVersion:r,parentRevision:h}),l};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:n,returnTypes:s,description:r,descriptionUniqueKey:h,descriptionVersion:c,parentRevision:l,rbacTeams:o})=>{const p=t,m={type:"api-operation",key:`${h}-${d(`${a.toLowerCase()}-${t}`)}`,title:p,summary:e.description?D(e.description):null,tags:["graphql"],metadata:{method:a,path:`${i}.${t}`,payload:n,responses:s},version:c};try{return await this.catalogEntitiesService.createEntity({entity:m,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:o,source:"file",revision:l})}catch(y){return this.#t.warn(`Failed to create API operation entity for ${p}: ${y instanceof Error?y.message:"Unknown error"}`),null}};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:i,description:n,descriptionVersion:s,parentRevision:r})=>{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"partOf",targetKey:i,sourceFile:n.realRelativePath,fileHash:n.hash,sourceVersion:s,targetVersion:s,sourceRevision:r,targetRevision:r});const h=[...new Set(e)],c=[...new Set(a)],l=[...h.map(o=>({key:o,relationType:"uses"})),...c.map(o=>({key:o,relationType:"returns"}))];await w(l,O,async({key:o,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:p,targetKey:o,sourceFile:n.realRelativePath,fileHash:n.hash,sourceVersion:s,targetVersion:s,sourceRevision:r,targetRevision:r})}catch(f){this.#t.warn(`Failed to create relation between operation ${t} and type ${o} (${p}): ${f instanceof Error?f.message:"Unknown error"}`)}})}}export{U as GraphqlEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as g}from"@redocly/config";import{removeLeadingSlash as x}from"@redocly/theme/core/utils";import{toKebabCase as y}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as b}from"../../../../../utils/async/promise-map-limit-with-status.js";import{extractTeamsFromScopeItems as R}from"../../../../../utils/rbac.js";import{removeMarkdocTags as w}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as d}from"./base.js";import{OpenapiSchemaResolver as S}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as A}from"../../../utils/extract-parts-from-components-ref.js";import{isValidTagName as v}from"../../../utils/is-valid-tag-name.js";const N=["get","post","put","delete","patch"],O=15,T=15;class _ extends d{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return await this.actions.loadOpenApiDefinitions(this.context)}mapApiDescriptionToEntity(e,n){const s=x(e.realRelativePath),r=e.definition.info.title,t=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.definition["x-redocly-catalog-key"]});return{type:this.type,key:t,title:r,summary:w(e.definition.info.description),tags:e.definition.tags?.filter(a=>a.name&&v(a.name)).map(a=>a.name),metadata:{specType:this.specType,descriptionFile:s},version:n}}async processApiDescription(e,n,s,r){if(S.clearSchemaCache(),!e?.definition)throw new Error("OpenAPI definition is missing a bundled document");const t=this.getRbacTeamsForDefinition(e.relativePath),a=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntity({entity:a,sourceFile:e.realRelativePath,fileHash:e.hash,source:"file",isRootEntity:!0,rbacTeams:t,revision:n}),r.delete(`${a.key}:${s}`),await this.#r(e,a.key,a.version,s,n,r,t);const o=this.#s(e.definition.paths);if(o.length!==0){const c=(await b(o,O,async({operation:h,path:m,method:f})=>{if(!h.operationId)return;const l=await this.#n(h,m,f,e,a.key,a.version,n,t);r.delete(`${l}:${s}`)},this.#e)).count.failed;c>0&&this.#e.warn(`Extraction completed with ${c} failures out of ${o.length} operations for ${a.key}`)}}#s(e){return Object.entries(e??{}).flatMap(([n,s])=>N.filter(r=>s[r]).map(r=>{const t=s[r];if(!t)throw new Error(`Operation not found for method ${r} on path ${n}`);return{operation:t,path:n,method:r.toUpperCase()}}))}async#r(e,n,s,r,t,a,o){const i=e.definition.components?.schemas;if(!i)return;const c=Object.entries(i);c.length!==0&&await E(c,T,async([h,m])=>{const f=`${n}-${y(h)}`,l=await this.#o({schemaName:h,schema:m,description:e,parentKey:n,parentVersion:s,parentRevision:t,rbacTeams:o});a.delete(`${f}:${r}`),l&&await this.catalogEntitiesService.createEntityRelation({sourceKey:n,sourceVersion:s,sourceRevision:t,type:"uses",targetKey:l.key,targetVersion:s,targetRevision:t,sourceFile:e.realRelativePath,fileHash:e.hash})})}async#o({schemaName:e,schema:n,description:s,parentKey:r,parentVersion:t,parentRevision:a,rbacTeams:o}){const i=S.resolveSchemaRefs(n,s),c=JSON.stringify(i),h=i[g]?R(i[g]):o,m=R(i["x-rbac"]),f={type:"data-schema",key:`${r}-${y(e)}`,title:e,summary:i.description??i.title??null,tags:[],metadata:{specType:this.specType,schema:c},version:t};try{return await this.catalogEntitiesService.createEntity({entity:f,sourceFile:s.realRelativePath,fileHash:s.hash,rbacTeams:m.length?m:h,source:"file",revision:a})}catch(l){return this.#e.error(`Failed to create data schema entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}}async#n(e,n,s,r,t,a,o,i){const c=`${t}-${y(`${e.operationId}`)}`,h=await Promise.all([this.#h(e.requestBody??null,r),this.#m(e.responses??{},r)]),m=h[0].schemaNames,f=h[1].schemaNames;h[0].errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${h[0].errors.join(", ")}`),h[1].errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${h[1].errors.join(", ")}`);const l=m.map(p=>`${t}-${y(p)}`),u=f.map(p=>`${t}-${y(p)}`),$=await this.#f({path:n,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:u,description:r,parentKey:t,parentVersion:a,parentRevision:o,rbacTeams:i});return $&&await Promise.all([this.#i(m,e.operationId??"",r.realRelativePath,r.hash,t,a,o),this.#c(f,e.operationId??"",r.realRelativePath,r.hash,t,a,o),this.#p({apiOperationKey:$.key,operationRelations:e["x-catalogRelations"],descriptionUniqueKey:t,description:r,parentVersion:a,parentRevision:o})]),c}async#i(e,n,s,r,t,a,o){return e.length===0||!n?[]:await this.#a(e,n,s,r,t,a,o)}async#c(e,n,s,r,t,a,o){return e.length===0||!n?[]:await this.#a(e,n,s,r,t,a,o)}#h(e,n){const s=[],r=[];try{if(e&&"content"in e&&e.content)for(const t of Object.values(e.content)){if(!t.schema?.$ref)continue;const a=this.#t(t.schema.$ref);a?.componentType==="schemas"&&a.componentName&&s.push(a.componentName)}if(e&&e.$ref){const t=this.#t(e.$ref);if(t?.componentType==="requestBodies"&&t.componentName){const a=n.definition.components?.requestBodies?.[t.componentName];if(a&&"content"in a)for(const o of Object.values(a.content??{})){if(!o.schema?.$ref)continue;const i=this.#t(o.schema.$ref);i?.componentType==="schemas"&&i.componentName&&s.push(i.componentName)}}}}catch(t){r.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:r}}#m(e,n){const s=[],r=[];try{for(const t of Object.values(e)){if(t&&"content"in t&&t.content)for(const a of Object.values(t.content)){if(!a.schema?.$ref)continue;const o=this.#t(a.schema.$ref);o?.componentType==="schemas"&&o.componentName&&s.push(o.componentName)}if(t&&t.$ref){const a=this.#t(t.$ref);if(a?.componentType==="responses"&&a.componentName){const o=n.definition.components?.responses?.[a.componentName];if(o&&"content"in o)for(const i of Object.values(o.content??{})){if(!i.schema?.$ref)continue;const c=this.#t(i.schema.$ref);c?.componentType==="schemas"&&c.componentName&&s.push(c.componentName)}}}}}catch(t){r.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:r}}#t(e){try{return A(e)}catch{return{componentType:"",componentName:null}}}async#a(e,n,s,r,t,a,o){return e.length===0?[]:await E(e,T,async i=>await this.#l({operationId:n,schemaName:i,descriptionSourceFile:s,descriptionHash:r,parentKey:t,parentVersion:a,parentRevision:o}))}async#l({operationId:e,schemaName:n,descriptionSourceFile:s,descriptionHash:r,parentKey:t,parentVersion:a,parentRevision:o}){const i=`${t}-${y(n)}`;try{return await this.catalogEntitiesService.createEntityRelation({sourceKey:`${t}-${y(e)}`,type:"uses",targetKey:i,sourceFile:s,fileHash:r,sourceVersion:a,targetVersion:a,sourceRevision:o,targetRevision:o}),i}catch(c){throw this.#e.error(`Failed to create relation between operation ${e} and schema ${n}: ${c instanceof Error?c.message:"Unknown error"}`),c}}async#f({path:e,method:n,operation:s,requestBodySchemasKeys:r,responseSchemasKeys:t,description:a,parentKey:o,parentVersion:i,parentRevision:c,rbacTeams:h}){const m=`${s.operationId}`,f=`${o}-${y(m)}`,l=s[g]?R(s[g]):h,u=R(s["x-rbac"]),$={type:"api-operation",key:f,title:m,summary:w(s.summary),tags:s.tags?.filter(p=>v(p)),metadata:{path:e,method:n,payload:r,responses:t},version:i};try{return await this.catalogEntitiesService.createEntity({entity:$,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:u.length>0?u:l,source:"file",revision:c})}catch(p){return this.#e.error(`Failed to create API operation entity for ${m}: ${p instanceof Error?p.message:"Unknown error"}`),null}}async#p({apiOperationKey:e,operationRelations:n,descriptionUniqueKey:s,description:r,parentVersion:t,parentRevision:a}){try{await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:s,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),await this.#y(e,r,n,t,a)}catch(o){this.#e.error(`Failed to create API operation relations for ${e}: ${o instanceof Error?o.message:"Unknown error"}`)}}async#y(e,n,s,r,t){s?.length&&await E(s,O,async a=>{try{this.validateEntityRelationFileSchema(a),await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:a.type,targetKey:a.key,sourceFile:n.realRelativePath,fileHash:n.hash,sourceVersion:r,targetVersion:"",sourceRevision:t,targetRevision:""})}catch(o){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${o instanceof Error?o.message:"Unknown error"}`)}})}}export{_ as OpenApiEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{FileHashStatus as
|
|
1
|
+
import{FileHashStatus as v,FileType as h}from"../../persistence/file-hashes/types.js";import{envConfig as C}from"../../config/env-config.js";import{CATALOG_BASE_SLUG as S}from"../../../constants/catalog-entities.js";import{telemetryTraceStep as k}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as f}from"./utils/catalog-data-collector.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as B,ENTITIES_MAP_GLOBAL_DATA_KEY as $}from"../../constants/plugins/catalog-entities.js";import{CacheService as z}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as O}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as _}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as Y}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as U}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as j}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as q}from"./database/catalog-entities-service.js";import{CatalogEntitiesPublisher as V}from"./database/catalog-entities-publisher.js";import{CatalogEntitiesRevisionsPruner as I}from"./database/catalog-entities-revisions-pruner.js";import{DEFAULT_MAX_ENTITY_REVISIONS as W}from"./database/consts.js";import{DatabaseConnectionFactory as J}from"../../providers/database/database-connection-factory.js";import{ArazzoEntitiesExtractor as X}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as Z}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as K}from"./utils/hash-manager.js";import{RbacConfigHashCache as Q}from"./utils/rbac-config-hash-cache.js";import{OpenApiEntitiesExtractor as ee}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const te="catalog-entity-template",ie="catalog-entity";let w=!0;async function ae(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(e,t){const s=await t.getConfig(),r=_(s.entitiesCatalog);if(!r.show)return;const{logger:n}=t,a=e.registerServerPropsGetter(ie,O("../get-server-props.js")),g=e.createTemplate(te,O("../template/index.js"));e.addRoute({duplicateInAllLocales:!0,slug:S,fsPath:"",templateId:g,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[a],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([P,m])=>!m?.hide)||[];l&&e.addRedirect(S,{type:302,to:`${S}/${l}`},{trackOriginalSource:!1}),n.info("Catalog Entities plugin finished")},async afterRoutesCreated(e,t){await k("build.plugin.catalog_entities",async s=>{const r=await t.getConfig(),n=_(r.entitiesCatalog);if(s?.setAttribute("config",JSON.stringify(n)),!n.show)return;const{logger:a}=t;f.resetForRun();const g=w&&C.isDevelopMode,l=await z.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),P=new Q(l),{rbacConfigChanged:m}=await P.syncAndDetectChange(r.access?.rbac??null),c=g||m,o=await q.getInstance({baseDbDir:e.serverOutDir,removeExisting:g,databaseType:"local",runWithPragmaWalWriteOptimization:!0}),T=await j.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),u=new K(T),F=[new Z({fileHashManager:u,context:t,catalogEntitiesService:o,catalogConfig:n,shouldCalculateEntities:c}),new ee({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.OPENAPI_DESCRIPTION,shouldCalculateEntities:c}),new Y({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:c}),new U({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.GRAPHQL_DESCRIPTION,shouldCalculateEntities:c}),new X({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.ARAZZO_DESCRIPTION,shouldCalculateEntities:c})];a.info("Starting entities extractors...");const R=a.startTiming();await o.transaction(async()=>{await Promise.all(F.map(async i=>i.extract()))});const N=o.getEntitySources();e.setGlobalData({[$]:N}),await l.deleteByNamespace(B),a.infoTime(R,"Entities extractors finished");const b=C.CATALOG_MAX_REVISIONS??W,d=await J.create({baseDbDir:e.serverOutDir,databaseType:"local"}),H=!C.isDevelopMode&&C.isProductionEnv;let E=[];if(H&&d&&b>0){const i=await I.pruneLocalRevisions({localConnection:d,maxRevisions:b});if(i.prunedEntities>0||i.prunedRelations>0){a.info(`Pruned entity revision history: entities=${i.prunedEntities} relations=${i.prunedRelations} files=${i.affectedSourceFiles.length} (keeping ${b} revisions per entity)`),E=i.affectedSourceFiles;for(const D of E)f.markSourceFileAsChanged(D)}}const{changedSourceFiles:L,removedSourceFiles:A}=f.getPublishDelta(),x=a.startTiming(),y=await V.publishFromLocalToRemote(m?{baseDbDir:e.serverOutDir}:{baseDbDir:e.serverOutDir,changedSourceFiles:L,removedSourceFiles:A});if(y.published&&a.infoTime(x,"Entities published to the database"),y.shouldFinalizeFileHashes){A.length&&await T.deleteFileHashes({op:"AND",conditions:[{field:"status",operator:"equal",value:v.OUTDATED},{field:"file_path",operator:"in",value:A}]});const i=f.getFileHashConfirmations();for(const{fileType:D,filePath:G,hash:M}of i)await T.upsertFileHash({fileType:D,filePath:G,hash:M,status:v.UP_TO_DATE});y.published&&E.length&&d&&await I.confirmPrunedFiles({localConnection:d,sourceFiles:E})}else a.warn("Skipped file_hashes finalization because remote catalog publish connection is unavailable; next build will retry.");const p=await f.getCatalogEntitiesData(o);s?.setAttribute("totalEntities",p.totalEntitiesCount),s?.setAttribute("entitiesCountByType",JSON.stringify(p.countOfEntitiesByType)),s?.setAttribute("totalFilesSkippedByHash",p.totalFilesSkippedByHash),s?.setAttribute("totalProcessedFiles",p.totalProcessedFiles),s?.setAttribute("extractors",p.extractors),w=!1})}}}var ve=ae;export{ae as catalogEntitiesPlugin,ve as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{DEFAULT_SEARCH_ENGINE as m,redocConfigSchema as p,rootRedoclyConfigSchema as t}from"@redocly/config";import A from"is-glob";import{I18N_DIR_NAME as d,L10N_DIR_NAME as u}from"../../../constants/common.js";import{CONFIG_FILE_NAME as f}from"../../../../constants/common.js";import{deepMerge as F}from"../../../../utils/object/deep-merge.js";import{logger as b}from"../../../tools/notifiers/logger.js";import{EntitlementsProvider as C}from"../../../entitlements/entitlements-provider.js";import{readAndValidateConfig as h}from"./utils/read-and-validate-config.js";import{resolveExternalPlugins as E}from"../../../external-plugins/resolve-external-plugins.js";import{getPathForAllLocales as l}from"../../../fs/utils/get-path-for-all-locales.js";import{parseRbacConfig as S}from"../../../utils/rbac.js";import{RbacConfigLocation as v,validateRbacConfig as y}from"../../validate-rbac-config.js";const R=["**/_partials/**"],j=async(e,{fs:r},s)=>{const a=await h(e,r,s,async c=>e===f?L(r.cwd,c?.plugins||[]):void 0);if(a?.access?.rbac){const c=await S(a.access.rbac);a.access.rbac=c,y(c,e===f?v.RootRedoclyYaml:void 0)}(a?.l10n||a?.i18n)&&(a.l10n=I(a),a.i18n=void 0);const i=F(a||{},{markdown:{partialsFolders:(a?.markdown?.partialsFolders||R).flatMap(c=>l(c,r))}});return _({...i,configPath:e,ignore:g(a?.ignore,r)})};async function L(e,r){const s=await E(e,r),a=s.map(n=>n.config.schema?n.lifecyclePlugin.id:""),i={};for(const n of s){const o=n.lifecyclePlugin?.id;n.config.schema&&o&&t.properties&&(i[o]=n.config.schema)}return{...t,properties:{...i,...t.properties,openapi:p},$id:t.$id+a.join("")}}function _(e){const r=C.instance();return r.canAccessFeature("apiFunctions")||(e.apiFunctions=void 0),r.canAccessFeature("products")||(e.products=void 0),r.canAccessFeature("breadcrumbs")||(e.breadcrumbs={hide:!0}),r.canAccessFeature("seo")||(e.seo={llmstxt:{hide:!0}}),r.canAccessFeature("redirects")||(e.redirects={}),r.canAccessFeature("l10n")||(e.l10n=void 0),r.canAccessFeature("rbac")||e.access&&(e.access.rbac=void 0),r.canAccessFeature("sso")||e.access&&(e.access.sso=void 0),r.canAccessFeature("ssoDirect")||(e.ssoDirect=void 0),r.canAccessFeature("catalogClassic")||(e.catalog=void 0,e.catalogClassic=void 0),r.canAccessFeature("scorecard")||(e.scorecard=void 0,e.scorecardClassic=void 0),r.canAccessFeature("scorecards")||(e.scorecards=void 0),r.canAccessFeature("devOnboarding")||(e.developerOnboarding=void 0),r.canAccessFeature("analytics")||(e.analytics=void 0),r.canAccessFeature("removeAttribution")||(e.removeAttribution=void 0),r.canAccessFeature("mockServer")||(e.mockServer={off:!0}),r.canAccessFeature("advancedSearch")||e.search&&(e.search.engine=m),r.canAccessFeature("banner")||(e.banner=void 0),e}function g(e=[],r){return["static",...e].flatMap(s=>A(s)&&(s.startsWith("*")||s.startsWith(u)||s.startsWith("/"+u)||s.startsWith(d)||s.startsWith("/"+d))?s:l(s,r))}function I(e){return e.i18n&&b.warn("The `i18n` configuration is deprecated. Please use `l10n` instead."),e.l10n||e.i18n||{}}export{j as redoclyConfigLoader};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import B from"@redocly/portal-plugin-mock-server";import _ from"path";import{REDOCLY_ROUTE_RBAC as x}from"@redocly/config";import{combineUrls as v,withPathPrefix as N}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as
|
|
2
|
-
`+u.stack;
|
|
1
|
+
import B from"@redocly/portal-plugin-mock-server";import _ from"path";import{REDOCLY_ROUTE_RBAC as x}from"@redocly/config";import{combineUrls as v,withPathPrefix as N}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as k}from"../constants/common.js";import{removeTrailingSlash as T}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as L}from"../../utils/url/remove-leading-slash.js";import{isTruthy as j}from"../../utils/guards/is-truthy.js";import{normalizeRouteSlug as F}from"../../utils/path/normalize-route-slug.js";import{slash as q}from"../../utils/path/slash.js";import{parsePathVersions as V}from"../../utils/path/parse-path-versions.js";import{reporter as b}from"../tools/notifiers/reporter.js";import{logger as h}from"../tools/notifiers/logger.js";import{envConfig as S}from"../config/env-config.js";import{shaDirPathShort as $}from"../utils/crypto/sha-dir-path-short.js";import{writeServerRebuildTrigger as M}from"../esbuild/generate.js";import{customPagesPlugin as z}from"../../server/plugins/pages/index.js";import{openAPIDocsPlugin as H}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 Y}from"../esbuild/generate.js";import{graphqlDocsPlugin as J}from"./graphql-docs/index.js";import{searchPlugin as Q}from"./search/index.js";import{skillsPlugin as X}from"./skills/index.js";import{defaultThemePlugin as Z}from"./default-theme/index.js";import{apiKeyMgmtPlugin as ee}from"./dev-onboarding/index.js";import{apiFunctionsPlugin as te}from"./api-functions/index.js";import{scorecardClassicPlugin as oe}from"./scorecard-classic/index.js";import{lintPlugin as ie}from"./lint/index.js";import{resolveExternalPlugins as re}from"../external-plugins/resolve-external-plugins.js";import{sidebarsPlugin as ne}from"./sidebars/index.js";import{l10nPlugin as se}from"./l10n/index.js";import{validateRedirects as ae}from"../utils/redirects/validate-redirects.js";import{analyticsPlugins as le}from"./analytics/index.js";import{sitemapPlugin as ue}from"./sitemap/index.js";import{entitlementsPlugin as ce}from"./entitlements/index.js";import{getBilledPagesCount as fe,slug as me}from"../utils/index.js";import{telemetry as de}from"../../cli/telemetry/index.js";import{telemetryTraceStep as E}from"../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as D}from"../entitlements/entitlements-provider.js";import{enforceLoginPlugin as pe}from"./enforce-login/index.js";import{ssoPlugin as ge}from"./sso/index.js";import{Cache as Pe}from"../fs/cache.js";import{ContentFs as he}from"../fs/content-fs.js";import{findProductBySlug as ye}from"../utils/product.js";import{parseBaseName as Re}from"./utils.js";import{isRouteReserved as we}from"./get-reserved-routes.js";import{catalogClassicPlugin as Ce}from"./catalog-classic/index.js";import{arazzoDocsPlugin as ve}from"./arazzo-docs/index.js";const be=[U,pe,ge,Z,se,G,H,I,ve,oe,ie,te,z,J,ee,Ce,{importPath:"./catalog-entities/plugin.js",loadCondition:()=>S.NEW_CATALOG_ENABLED??!1},{importPath:"./scorecards/plugin.js",loadCondition:()=>S.NEW_SCORECARDS_ENABLED??!1},{importPath:"./mcp/index.js",loadCondition:()=>D.instance().canAccessFeature("mcp")},ne,ue,ce,Q,X,B,...le];async function bt(t,e=be){return await E("build.plugins_init",async()=>{const r=[],w=D.instance(),y={};for(const s of e){let d;if("loadCondition"in s){if(!s.loadCondition())continue;const o=await import(s.importPath);if(!o.default||typeof o.default!="function"){await b.panicOnBuild(`Dynamic plugin ${s.importPath} does not export a default export or it is not a function`);continue}d=o.default}else d=s;const R=await d(t);for(const[o,l]of Object.entries(R.loaders||{}))y[o]&&await b.panicOnBuild(`Duplicate loader with name ${o}`),y[o]=l;(!R.requiredEntitlements||R.requiredEntitlements?.every(o=>w.canAccessFeature(o)))&&r.push(R)}const u=new he(t.contentDir);await u.ready;const m=new Pe(u);return m.setLoaders(y),h.verbose("All plugins instantiated"),{pluginInstances:r,lifecycleContext:Ae(u,m)}})}function O(t){h.verbose("Generating templates"),E("build.write_client_entries",()=>{Y(t),W(t),K(t)})}async function Ee(t){const e=t.getAllRoutes();fe(e)||await b.panicOnBuild("No routes created by plugins. Please check your project configuration.")}async function Et(t,e,r,w={}){const y=D.instance();try{await E("build.plugins_run",async()=>{e.startPluginsRun();const u=S.isDevelopMode&&e.buildRevision>0,m=u?Array.from(e.apiRoutesRequestHandlers.keys()).sort().join(","):"";let s=[];await E("build.plugins_process_content",async o=>{for(const i of t){const a=h.startTiming();await i.processContent?.(e,r),h.verboseTime(a,`processContent for ${i.id}`)}s=(await re(e.contentDir,e.config.plugins)).map(i=>i.lifecyclePlugin).filter(i=>j(i)&&(!i.requiredEntitlements||i.requiredEntitlements?.every(a=>y.canAccessFeature(a)))),r.cache.setLoaders(Object.fromEntries(s.flatMap(i=>Object.entries(i.loaders||{}))));for(const i of s){const a=h.startTiming();await i.processContent?.(e,r),h.verboseTime(a,`processContent for ${i.id}`)}o?.setAttribute("externalPluginsProcessed",s.length.toString())});const d=await Se(e,r),R=[...t,...s];if(O(e),S.isDevelopMode?await e.userCodeReady:e.buildRevision++,await E("build.plugins_after_routes_created",async()=>{for(const o of R){const l=h.startTiming();await o.afterRoutesCreated?.(e,d),h.verboseTime(l,`afterRoutesCreated for ${o.id}`)}}),ae(e),await e.reportUnsetEnvVars(),await Ee(e),O(e),u){const o=Array.from(e.apiRoutesRequestHandlers.keys()).sort().join(",");m!==o&&(e.markRequestHandlersEntryOutdated(),M(e.serverOutDir))}})}catch(u){const m="Unhandled error in plugin. "+u.message+`
|
|
2
|
+
`+u.stack;de.sendCliErrorCaughtMessage({message:m}),w.failFast?await b.panic(m):await b.panicOnBuild(m)}finally{e.finishPluginsRun()}}async function Se(t,e){const{cache:r,fs:w}=e,y=await e.getConfig(),u=Object.values(y.products||{}),m=(await r.load("versions-config","versions-config")).data,s=(await r.load("content-slugs","content-slugs")).data;for(const{duplicateInAllLocales:o,slugSuffix:l,sharedData:i=[],redirectFrom:a=[],...c}of t.newRoutes){const f=F(c.slug?c.slug:d(c.fsPath)),g=T(l?v(f,l):f),n={...c,[x]:{slug:g,fsPath:c.fsPath},slug:g,baseSlug:f,versions:R(c.fsPath,l),product:ye(u,g,d)};we(g,y)&&await b.panicOnBuildContentError(`Route "${g}" is reserved and cannot be used. Please choose a different slug for "${c.fsPath}".`),t.routesByFsPath.set(n.fsPath,n.slug),t.routesBySlug.set(n.slug,n);for(const{key:P,id:p}of i)t.addRouteSharedData(n.slug,P,p);for(const P of a)t.addRedirect(P.from,{type:P.type,to:n.slug});if(o)for(const P of w.localeFolders){const p={...n,slug:"/"+P.toLowerCase()+n.slug};t.routesByFsPath.set(p.fsPath,p.slug),t.routesBySlug.set(p.slug,p);for(const{key:C,id:A}of i)t.addRouteSharedData(p.slug,C,A);for(const C of a){const A=v(w.localizationFolder,P,C.from);t.addRedirect(A,{type:C.type,to:p.slug},{trackOriginalSource:!1})}}}return t.newRoutes=[],{...e,slugify:d};function d(o){const l=q(o).replace(new RegExp("^(@i18n|@l10n)\\/"),""),i=s.fileSlugs.get(l)||s.dirSlugs.get(T(l));if(i)return i;const{baseName:a,isIndexFile:c}=Re(o);let f=_.dirname(o.replace(new RegExp("^(@i18n|@l10n)\\/"),""));return f=f==="."?"/":f,v("/",me(c?f:v(f,a)),"/")}function R(o,l=""){const i=V(o);if(!i?.versionName)return;const{versionFolderPath:a,filePathInVersion:c,versionName:f}=i,g=m.get(a);if(g)return g.versions.map(n=>{const P=g.defaultVersion===n.version,p=L(v(a,k+n.version,c)),C=d(p);return{version:n.version,label:n.name||n.version,link:F(v(C,l)),default:P,active:f===n.version,folderId:$(`${a}`)}})}}function Ae(t,e){return{fs:t,cache:e,getConfig:async(r=".")=>(await e.load(r,"nearest-redocly-config",t.localeFolders)).data,isPathIgnored:async r=>(await e.load(r,"is-ignored")).data,withPathPrefix:N,logger:h}}export{be as INTERNAL_PLUGINS,Ae as createLifecycleContext,bt as initPlugins,Et as runPlugins,O as writeClientEntries};
|
package/dist/server/plugins/mcp/{docs-mcp/codemode → codemode}/build-tool-type-declarations.d.ts
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { McpToolSchema } from '
|
|
1
|
+
import type { McpToolSchema } from '../../../types';
|
|
2
2
|
export declare function sanitizeToolName(name: string): string;
|
|
3
3
|
export declare function buildToolTypeDeclarations(tools: McpToolSchema[]): string;
|
|
4
4
|
//# sourceMappingURL=build-tool-type-declarations.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{getCallableApis as a,isFetchCapable as s}from"../../../gateway-mcp/fetch-capability.js";import{FETCH_TOOL_NAME as i}from"../../constants.js";const l=["```ts","/**"," * Call a documented API. Only the callable APIs' documented hosts are reachable."," * Responses cap at 1 MiB and redirects are not followed."," */","declare function fetch(url: string, init?: {"," method?: string;"," /** `content-type` is set automatically for URLSearchParams/FormData unless you set one. */"," headers?: Record<string, string>;"," /** string \xB7 URLSearchParams (\u2192 application/x-www-form-urlencoded) \xB7 FormData (\u2192 multipart/form-data) */"," body?: string | URLSearchParams | FormData;","}): Promise<{"," status: number;"," statusText: string;"," ok: boolean;"," headers: { get(name: string): string | null };"," json(): Promise<unknown>;"," text(): Promise<string>;","}>;","```"].join(`
|
|
2
|
+
`),c=["Example - List the write endpoints of an API and call one of them with `fetch`:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const ep = endpoints.find((e) => e.method === 'POST' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: items[0].name, path: ep.path, method: ep.method });","const url = (info.servers?.[0]?.url ?? '') + ep.path;","try {"," const res = await fetch(url, { method: 'POST', body: JSON.stringify({ /* fields from info */ }) });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"].join(`
|
|
3
|
+
`);function d(r){const t=new Map;for(const{name:e,version:n}of r){if(!e)continue;const o=t.get(e)??[];n&&o.push(n),t.set(e,o)}return[...t.entries()].map(([e,n])=>n.length>1?`${e} (${n.map(o=>`v${o}`).join(", ")})`:e).join(", ")}const f={id:i,isActive:s,annotations:{readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},renderSection(r){const t=d(a(r));return["## `fetch` \u2014 call the documented APIs","",l,"","Always call `getEndpointInfo` before `fetch` for the exact URL, required parameters, and body shape. Never guess.","",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${t}`,"",c].join(`
|
|
4
|
+
`)}};export{l as FETCH_DECLARATION,f as fetchCapability};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{composeExecuteAnnotations as o,getActiveCapabilities as i,renderDescribeToolsOutput as r}from"./utils.js";export{o as composeExecuteAnnotations,i as getActiveCapabilities,r as renderDescribeToolsOutput};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{fetchCapability as t}from"./fetch/index.js";const i=[t];export{i as ALL_CAPABILITIES};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolAnnotations } from '@redocly/mcp-typescript-sdk/types.js';
|
|
2
|
+
import type { McpToolContext } from '../../types.js';
|
|
3
|
+
/** A capability is a per-request-gated global the code-mode sandbox exposes beyond the schema-driven `tools.*` surface. */
|
|
4
|
+
export type SandboxCapability = {
|
|
5
|
+
id: string;
|
|
6
|
+
/** Whether this capability is live for THIS request (RBAC/config/flag-dependent). */
|
|
7
|
+
isActive(context: McpToolContext): boolean;
|
|
8
|
+
/** How this capability changes `execute`'s MCP annotations when active. */
|
|
9
|
+
annotations: Partial<ToolAnnotations>;
|
|
10
|
+
/** The self-contained `describe-tools` section for this capability: heading, TS declaration, guidance, and example. */
|
|
11
|
+
renderSection(context: McpToolContext): string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolAnnotations } from '@redocly/mcp-typescript-sdk/types.js';
|
|
2
|
+
import type { McpToolSchema } from '../../../../types';
|
|
3
|
+
import type { McpToolContext } from '../../types.js';
|
|
4
|
+
import type { SandboxCapability } from './types.js';
|
|
5
|
+
export declare function getActiveCapabilities(context: McpToolContext): SandboxCapability[];
|
|
6
|
+
/** `execute`'s annotations = the read-only base with every active capability's delta merged over it. */
|
|
7
|
+
export declare function composeExecuteAnnotations(active: SandboxCapability[]): ToolAnnotations;
|
|
8
|
+
/**
|
|
9
|
+
* The describe-tools output: the tool signatures, the always-present
|
|
10
|
+
* `execute` args note, then one self-contained section per selected capability.
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderDescribeToolsOutput(tools: McpToolSchema[], capabilities: SandboxCapability[], context: McpToolContext): string;
|
|
13
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{buildToolTypeDeclarations as i}from"../build-tool-type-declarations.js";import{EXECUTE_BASE_ANNOTATIONS as c}from"../tools/execute-schema.js";import{EXECUTE_ARGS_NOTE as p,USAGE_NOTES as s}from"../prompts.js";import{ALL_CAPABILITIES as u}from"./registry.js";function T(o){return u.filter(t=>t.isActive(o))}function m(o){return o.reduce((t,e)=>({...t,...e.annotations}),{...c})}function l(o,t,e){const n=[];o.length>0&&n.push(`## Sandbox tools
|
|
2
|
+
|
|
3
|
+
${i(o)}
|
|
4
|
+
|
|
5
|
+
${s}`),n.push(p);for(const r of t)n.push(r.renderSection(e));return n.join(`
|
|
6
|
+
|
|
7
|
+
`)}export{m as composeExecuteAnnotations,T as getActiveCapabilities,l as renderDescribeToolsOutput};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const EXECUTE_TOOL_NAME = "execute";
|
|
2
|
+
export declare const DESCRIBE_TOOLS_TOOL_NAME = "describe-tools";
|
|
3
|
+
export declare const FETCH_TOOL_NAME = "fetch";
|
|
4
|
+
export declare const CODE_MODE_TOOL_NAMES: ReadonlySet<string>;
|
|
5
|
+
export declare const TOOLS_BRIDGE_GLOBAL_NAME = "tools";
|
|
6
|
+
export declare const FETCH_BRIDGE_GLOBAL_NAME = "__fetchBridge";
|
|
7
|
+
export declare const FETCH_BRIDGE_FUNCTION_NAME = "fetch";
|
|
8
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t="execute",_="describe-tools",E="fetch",e=new Set([t,_]),o="tools",O="__fetchBridge",c="fetch";export{e as CODE_MODE_TOOL_NAMES,_ as DESCRIBE_TOOLS_TOOL_NAME,t as EXECUTE_TOOL_NAME,c as FETCH_BRIDGE_FUNCTION_NAME,O as FETCH_BRIDGE_GLOBAL_NAME,E as FETCH_TOOL_NAME,o as TOOLS_BRIDGE_GLOBAL_NAME};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpToolContext, McpToolExtra } from '../types.js';
|
|
2
|
+
/** Call a registered MCP tool from inside the sandbox and return its parsed result. */
|
|
3
|
+
export declare function invokeTool(toolName: string, input: unknown, context: McpToolContext, extra: McpToolExtra): Promise<unknown>;
|
|
4
|
+
//# sourceMappingURL=invoke-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{executeMcpTool as i}from"../workers/execute-mcp-tool.js";async function p(t,r,n,c){const e=await i({toolName:t,args:r,context:n,extra:c}),o=u(e);if(e.isError)throw new Error(o);return s(o)}function u(t){return t.content.filter(r=>r.type==="text").map(r=>r.text).join("")}function s(t){try{return JSON.parse(t)}catch{return t}}export{p as invokeTool};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const EXECUTE_ARGS_NOTE = "Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).";
|
|
2
|
+
export declare function buildExecuteDescription(hasFetch: boolean): string;
|
|
3
|
+
export declare const DESCRIBE_TOOLS_DESCRIPTION: string;
|
|
4
|
+
export declare function buildCodeModeInstructions(hasFetch: boolean): string;
|
|
5
|
+
export declare const USAGE_NOTES = "Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.";
|
|
6
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const t="Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).";function o(e){return["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The only extra globals are `tools` and `fetch` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs (every tool name is listed in the `describe-tools` input schema / description).","2. Call `describe-tools` with those names to get their exact TypeScript signatures. NEVER call `execute` with guessed method names, parameter names, or enum values.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs.","",...e?["Example - list the Billing API endpoints and call one of them:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const ep = endpoints.find((e) => e.method === 'POST' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: items[0].name, path: ep.path, method: ep.method });","const url = (info.servers?.[0]?.url ?? '') + ep.path;","try {"," const res = await fetch(url, { method: 'POST', body: JSON.stringify({ /* fields from info */ }) });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"]:["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: items[0].name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"]].join(`
|
|
2
|
+
`)}const s=["Get the exact TypeScript signatures of the sandbox tools available to `execute`.","Analyze the user request first, then pass `tools` with only the tool names the request needs (every name is listed in this input schema / description); omit `tools` only when you cannot tell which tools apply.","Always call this before your first `execute` and never guess signatures. Request every tool the task may need in ONE call instead of calling this repeatedly."].join(`
|
|
3
|
+
`);function n(e){return["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through two tools:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with only the tool names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",e?"The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs.":""].join(`
|
|
4
|
+
`)}const i="Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.";export{s as DESCRIBE_TOOLS_DESCRIPTION,t as EXECUTE_ARGS_NOTE,i as USAGE_NOTES,n as buildCodeModeInstructions,o as buildExecuteDescription};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SetupSandboxContext } from '../../../../sandbox/types.js';
|
|
2
|
+
import type { SandboxFetch, SandboxTool } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the `setupContext` that shapes the shared sandbox (`~/server/sandbox`) for code
|
|
5
|
+
* mode: the given tools — and, when provided, host fetch — become host-function rails, each
|
|
6
|
+
* capped and bound by the run's budget, and the prelude installs the code-mode guest surface
|
|
7
|
+
* over them.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createSandboxSetup(tools: Record<string, SandboxTool>, hostFetch?: SandboxFetch): SetupSandboxContext;
|
|
10
|
+
//# sourceMappingURL=create-sandbox-setup.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{setupHostFunctions as a}from"../../../../sandbox/utils/setup-host-functions.js";import{evalGuestCode as p}from"../../../../sandbox/utils/eval-guest-code.js";import{SANDBOX_FETCH_SETUP as i}from"./polyfills.js";import{FETCH_BRIDGE_FUNCTION_NAME as u,FETCH_BRIDGE_GLOBAL_NAME as c,TOOLS_BRIDGE_GLOBAL_NAME as n}from"../constants.js";const m=100,f=50;function T(r,t){return(e,l)=>{const s=[a(e,r,{globalName:n,budget:l,maxCalls:m,messages:{outputTooLarge:o=>`Tool output is too large (${o} bytes); request narrower data instead`,callLimitExceeded:o=>`Exceeded the limit of ${o} tool calls`}})];return t&&s.push(a(e,{[u]:o=>t(o)},{globalName:c,budget:l,maxCalls:f,messages:{outputTooLarge:o=>`Response is too large (${o} bytes); request less data`,callLimitExceeded:o=>`Exceeded the limit of ${o} fetch calls`}})),p(e,E(!!t)),()=>{for(const o of s)o()}}}function E(r){const t=r?i:"",e=`globalThis[${JSON.stringify(n)}]`;return`(() => {${t}
|
|
2
|
+
const tools = ${e};
|
|
3
|
+
${e} = new Proxy(tools, {
|
|
4
|
+
get(target, prop) {
|
|
5
|
+
if (typeof prop !== 'string' || prop in target || prop === 'then' || prop === 'toJSON') {
|
|
6
|
+
return target[prop];
|
|
7
|
+
}
|
|
8
|
+
throw new TypeError('Unknown tool "' + prop + '". Available tools: ' + Object.keys(target).join(', '));
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
})();`}export{T as createSandboxSetup};
|