@redocly/realm 0.134.0-next.1 → 0.134.0-next.3
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 +36 -0
- package/dist/client/app/utils/getBlocksHeight.d.ts +5 -14
- package/dist/client/app/utils/getBlocksHeight.js +1 -1
- package/dist/client/app/utils/loadAndNavigate.js +1 -1
- package/dist/client/app/utils/syncScrollWithEditor.js +1 -1
- package/dist/client/providers/hooks.js +1 -1
- package/dist/client/templates/asyncapi-docs/helpers.d.ts +3 -13
- package/dist/compiled/svgo/svgo-node.js +55 -49
- package/dist/constants/common.d.ts +1 -0
- package/dist/constants/common.js +1 -1
- package/dist/markdoc/tags/index.d.ts +30 -0
- package/dist/markdoc/types.d.ts +2 -2
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-config.d.ts +6 -0
- package/dist/server/config/env-schema.d.ts +149 -2
- package/dist/server/config/env-schema.js +1 -1
- package/dist/server/config/env-schemas/feature-flags.d.ts +12 -0
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/constants/feedback.d.ts +2 -0
- package/dist/server/constants/feedback.js +1 -1
- package/dist/server/node-bundle-entry.js +1 -1
- package/dist/server/persistence/cache/repositories/cache-repository.js +1 -1
- package/dist/server/persistence/file-hashes/repositories/file-hashes-repository.js +1 -1
- package/dist/server/persistence/kv/repositories/kv-repository.d.ts +1 -1
- package/dist/server/persistence/kv/repositories/kv-repository.js +2 -2
- package/dist/server/persistence/kv/services/kv-service.d.ts +3 -2
- package/dist/server/persistence/kv/services/kv-service.js +1 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +2 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/catalog-entities-repository.d.ts +1 -4
- package/dist/server/plugins/catalog-entities/database/repositories/catalog-entities-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-read-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
- package/dist/server/plugins/entitlements/utils/get-billed-catalog-build-pages-count.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
- package/dist/server/plugins/markdown/search/create-render-tag-fn.d.ts +4 -0
- package/dist/server/plugins/markdown/search/create-render-tag-fn.js +1 -0
- package/dist/server/plugins/markdown/search/get-ai-search-documents.js +7 -8
- package/dist/server/plugins/markdown/search/join-section-content.d.ts +3 -0
- package/dist/server/plugins/markdown/search/join-section-content.js +2 -0
- package/dist/server/plugins/markdown/search/nodes/heading-node.d.ts +1 -7
- package/dist/server/plugins/markdown/search/nodes/section-node.d.ts +2 -14
- package/dist/server/plugins/markdown/search/nodes/section-node.js +1 -1
- package/dist/server/plugins/markdown/search/nodes/tag-node.d.ts +1 -7
- package/dist/server/plugins/markdown/search/walk-sections.d.ts +3 -1
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.d.ts +2 -2
- package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +30 -30
- package/dist/server/plugins/scorecards/database/repositories/scorecards-config-repository.d.ts +4 -0
- package/dist/server/plugins/scorecards/database/repositories/scorecards-config-repository.js +1 -1
- package/dist/server/plugins/scorecards/database/scorecards-config-service.d.ts +4 -4
- package/dist/server/plugins/scorecards/database/scorecards-config-service.js +1 -1
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +3 -1
- package/dist/server/providers/database/base-service.d.ts +25 -0
- package/dist/server/providers/database/base-service.js +1 -0
- package/dist/server/providers/database/database-preconnect-service.js +1 -1
- package/dist/server/providers/database/instance-cache-resolver.d.ts +19 -0
- package/dist/server/providers/database/instance-cache-resolver.js +1 -0
- package/dist/server/store.d.ts +2 -34
- package/dist/server/types/plugins/common.d.ts +5 -0
- package/dist/server/types/plugins/markdown.d.ts +3 -0
- package/dist/server/utils/is-api-download-link.d.ts +2 -0
- package/dist/server/utils/is-api-download-link.js +1 -0
- package/dist/server/utils/is-realm-or-reef.d.ts +2 -0
- package/dist/server/utils/is-realm-or-reef.js +1 -0
- package/dist/server/utils/llmstxt/agent-feedback-llms-footer.d.ts +3 -0
- package/dist/server/utils/llmstxt/agent-feedback-llms-footer.js +2 -0
- package/dist/server/utils/shared-data.js +1 -1
- package/dist/server/web-server/dev-server.js +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/feedback.d.ts +16 -0
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/utils/feedback-ip.d.ts +2 -0
- package/dist/server/web-server/utils/feedback-ip.js +1 -0
- package/dist/server/web-server/utils/get-client-ip.d.ts +1 -0
- package/dist/server/web-server/utils/get-client-ip.js +1 -1
- package/dist/utils/auth/is-auth-route-path.js +1 -0
- package/package.json +7 -7
- package/dist/client/utils/auth/is-auth-route-path.js +0 -1
- package/dist/server/plugins/catalog-entities/utils/has-options-changed.d.ts +0 -2
- package/dist/server/plugins/catalog-entities/utils/has-options-changed.js +0 -1
- /package/dist/{client/utils → utils}/auth/is-auth-route-path.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{and as a,count as h,eq as l,isNotNull as R,or as A,sql as u}from"drizzle-orm";import{applyPagination as
|
|
1
|
+
import{and as a,count as h,eq as l,isNotNull as R,or as A,sql as u}from"drizzle-orm";import{applyPagination as b}from"../../../../../providers/database/pagination/index.js";import{getEffectivePaginationLimit as D}from"../../../../../providers/database/pagination/limit.js";import{entitiesTable as t}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{entitiesAttributesTable as m}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-attributes-table.js";import{VERSION_NOT_SPECIFIED as L}from"@redocly/theme/core/constants";import{applyFilter as B}from"../../../../../providers/database/pagination/filter.js";import{getFirstRunRow as O}from"../../../../../providers/database/utils/get-first-row.js";import{createEntityReadModel as f}from"../../mappers/create-entity-read-model.js";import{createEntityFieldsForSelect as w,FIELDS_TO_SELECT_FOR_ENTITY as p}from"../utils.js";import{buildRbacFilter as g}from"../utils/build-rbac-filter.js";import{buildEntitiesExclusionFilter as F}from"../utils/build-entities-exclusion-filter.js";class Y{#t;constructor(e){this.#t=e}async getEntities({paginationParams:e,rbacTeams:i,excludedTypes:n,excludedEntities:o}){const s=F(n,o,"entities"),r=this.#t.client.select(w("entities")).from(t).leftJoin(m,l(t.key,m.entityKey)).where(a(g(i,"entities_attributes"),s)),c=this.#t.client.select(p).from(r.as("combined_entities")),S=this.#t.client.select(p).from(r.as("combined_entities")).$dynamic(),T=b(S,{...e,limit:void 0,skip:void 0,after:void 0,before:void 0}),C=this.#t.client.$count(T),_=c.$dynamic(),y=D(e),$=b(_,{...e,limit:y+1}),[k,I]=await Promise.all([$.all(),C]),E=k,N=E.length>y;return{items:E.slice(0,y).map(d=>f(d)).filter(d=>d!==null),hasMore:N,total:I}}async getEntityById(e,i){const{rbacTeams:n,excludedTypes:o,excludedEntities:s}=i||{},r=F(o,s,"entities"),c=await this.#t.client.select(w("entities")).from(t).leftJoin(m,l(t.key,m.entityKey)).where(a(l(t.id,e),g(n,"entities_attributes"),r)).get();return c?f(c):null}async getEntityKeysAndVersionsBySourceFile(e){const i=await this.#t.client.selectDistinct({keyVersion:u`${t.key} || ':' || COALESCE(${t.version}, ${L})`.as("keyVersion")}).from(t).where(a(l(t.sourceFile,e),l(t.source,"file"),R(t.key))).all();return new Set(i.map(n=>n.keyVersion))}async getEntitiesCountByTypes(){return this.#t.client.select({type:t.type,count:h()}).from(t).where(a(l(t.isCurrent,!0),l(t.isDeleted,!1))).groupBy(t.type)}async getOutdatedEntities(e){const i=this.#t.client.select(p).from(t).$dynamic(),{whereCondition:n}=B(i,e),o=A(u`scorecards_status = 'OUTDATED'`,u`scorecards_status IS NULL`),s=n?a(n,o):o;return(await i.where(s).all()).map(c=>f(c)).filter(c=>c!==null)}async getEntitiesCount(e,i,n){const o=await this.#t.client.select({count:h()}).from(t).where(l(t.source,e));let s=Number(o[0]?.count??0);if(i?.length){const r=await this.#e(e,i);s+=i.length-r}return n!==void 0&&(s-=n),{total:s}}async#e(e,i){const n=u.join(i.map(r=>u`(${r.key}, ${r.version}, ${r.revision})`),u`, `),o=await this.#t.client.run(u`SELECT count(*) AS count FROM entities WHERE source = ${e} AND (key, version, revision) IN (VALUES ${n})`),s=O(o);return Number(s?.count??0)}}export{Y as EntitiesReadRepository};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{and as
|
|
1
|
+
import{and as E,eq as c,isNull as R,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 m}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 v=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:u,errorOnSkip:h=!1,revision:f}){const{relations:l=[],...y}=e,d=V(JSON.stringify(y)),p=e.version??I,C=f??new Date().toISOString(),W=await this.#t.shouldSkipRevisionCreation(e.key,p,d,t,n);if(Array.isArray(u)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:u,organizationId:this.#i,projectId:this.#s}),W){if(h)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:g,hasCurrentRevision:L}=await this.#t.getCurrentRevisionInfo({key:e.key,version:p,revision:C}),w=O({entity:{...e,revision:C,hash:d,isCurrent:g,isDefaultVersion:g,isDeleted:n,version:p},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,l);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?(l&&await this.#r.createEntityRelations(l.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:u,scorecardsStatus:h,...f}=t,l=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...f,scorecardsStatus:N`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return l.length?k(l[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,isDefaultVersion:n,...u}=e,l=await this.#e.client.select({id:i.id}).from(i).where(E(c(i.key,r),t?c(i.version,t):R(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(u).where(E(c(i.key,r),t?c(i.version,t):R(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:u}).returning(),y=s?.map(d=>{const p=P({relation:d,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(p).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:p}).run()})??[];return await m(y,v,async d=>d),k(l[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 u=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(u,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 m(Array.from(o),v,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(T(E(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[R(a.sourceVersion)]),E(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[R(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 m(e,v,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 m(e,v,async o=>(await this.#u.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const u=n.direction,h=n.sourceToTargetRelation,f=n.targetKey,l=u==="outgoing"?o.key:f,y=u==="outgoing"?f:o.key,d=u==="outgoing"?h:h.startsWith("reverse:")?h.slice(8):h;return!d||!l||!y?null:j({type:d,sourceKey:l,targetKey:y,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await m(r.flat(),v,async o=>this.#r.upsertEntityRelation(o)),!0}}export{ce as EntitiesWriteRepository};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{isRealmOrReef as n}from"../../../utils/is-realm-or-reef.js";import{isCatalogEntitiesEnabled as l}from"../../../utils/is-catalog-entities-enabled.js";import{CatalogEntitiesService as r}from"../../catalog-entities/database/catalog-entities-service.js";async function d(t,a){if(!n()||!l())return{total:0};const e=await r.getInstance({baseDbDir:t,databaseType:"local"}),{total:i}=await e.getEntitiesCount("file"),s=g(a);return{total:i+s}}function g(t){return t?.show?Object.entries(t.catalogs??{}).filter(([o,e])=>!e?.hide).length:0}export{d as getBilledCatalogBuildPagesCount};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as
|
|
1
|
+
import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as T,GRAPHQL_TEMPLATE_ID as v,OPENAPI_DOCS_TEMPLATE_ID as y}from"../../../../constants/common.js";import{isLocalLink as D}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as h}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as F}from"../../../../utils/path/remove-fragment.js";import{getInnerText as M}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as U}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isAuthRoutePath as W}from"../../../../utils/auth/is-auth-route-path.js";import{isApiDownloadLink as j}from"../../../utils/is-api-download-link.js";import{MdResolveError as g}from"./md-resolve-error.js";import{getLinkOriginalAttrName as B}from"./utils.js";import{isOpenApiURL as $}from"../../openapi-docs/is-openapi-doc.js";import{parseBaseName as C}from"../../utils.js";import{isMarkdownPage as V}from"../is-markdown-page.js";import{copyStaticFile as b}from"../../../utils/fs.js";async function at(i,s,E,{actions:k,context:f}){const{contentDir:d,outdir:S,getRouteByFsPath:w,hasRouteOrRedirectBySlug:A}=k,L=B(s),e=i[L]||U(i,s);if(i[L]=e,!D(e)||j(e)||W(e))return;const[z,t="",R,P]=/^([^\?#]+)?([^#]+)?(.+)?/.exec(e)||[],c=i.type==="image"?"IMAGE":"LINK",u=String(i.attributes.title||i.attributes.alt||M([i])||""),n=F(E);if(i.type!=="image"){const{isOpenapiDetected:r,isOpenapiValid:m}=await $(t,n,k,f);if(r&&!m)throw new g(`OpenAPI route ${e} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c})}if(o.extname(t)===""){if(t.startsWith("/")){if(!A(h(t)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c});p(i,s,t+(R||"")+(P||""))}if(!e.startsWith("#")&&!t.startsWith("/")&&V(n)){const r=w(n)?.slug;if(!r)return;const{isIndexFile:m}=C(n),x=m?h(o.posix.join(r,t)):h(o.posix.join(r,"../",t));if(!A(h(x)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:x,title:u,brokenLinkType:c});p(i,s,x+(R||"")+(P||""))}return}const a=t.startsWith("/")?t.substring(1):o.posix.join(o.posix.dirname(n),decodeURI(t)),_=t.startsWith("/")?o.posix.join("static",t.substring(1)):"",I=f.fs.exists(a),O=f.fs.exists(_),l=w(a);if(!I&&!l&&!O)throw p(i,s,"#"),new g(`File ${a} does not exist`,{rawLink:e,link:a,title:u,brokenLinkType:c});if(l){const r=[y,v,T].includes(l.templateId);p(i,s,(r?l.baseSlug:l.slug)+(P||""))}else if(I){const r=f.fs.getFileInfo(a);if(!r||r.isVirtual)return;const m=await b(d,r.realRelativePath,S);p(i,s,m)}}export{at as resolveLink};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MarkdocTagSchema } from '@redocly/theme/markdoc/tags/types';
|
|
2
|
+
import type { RenderTagFn } from '../../../types/plugins/markdown';
|
|
3
|
+
export declare function createRenderTagFn(markdocTags: Record<string, MarkdocTagSchema> | undefined): RenderTagFn;
|
|
4
|
+
//# sourceMappingURL=create-render-tag-fn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function t(e){return(r,n)=>{if(r.tag)return e?.[r.tag]?.renderForLlms?.(r,n)}}export{t as createRenderTagFn};
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import _ from"@markdoc/markdoc";import D from"node:path";import{AI_SEARCH_CHUNK_SIZE as E,AI_SEARCH_DOCUMENT_CHUNK_SIZE as M}from"../../../constants/plugins/search.js";import{slugger as P}from"../../../../utils/slugger.js";import{
|
|
2
|
-
`).trim();return[{title:a,description:g,slug:e.slug,fsPath:e.fsPath,content:C,includeInLLMsTxt:!0}]},async getSearchDocuments(){return j(e,d,n,a)}}};function j(n,r,e,c){const s=n.slug,i=new Map,a=n.metadata||{},m=y(a,e),f=L(a),d=f?`Metadata:
|
|
1
|
+
import _ from"@markdoc/markdoc";import D from"node:path";import{AI_SEARCH_CHUNK_SIZE as E,AI_SEARCH_DOCUMENT_CHUNK_SIZE as M}from"../../../constants/plugins/search.js";import{slugger as P}from"../../../../utils/slugger.js";import{joinSectionContent as U}from"./join-section-content.js";import{toMarkdown as b}from"./to-markdown.js";import{AstToSearchNodeTransformer as I}from"./walk-sections.js";import{createRenderTagFn as x}from"./create-render-tag-fn.js";import{getLocaleFromRelativePath as y}from"../../../fs/utils/get-locale-from-relative-path.js";import{HeadingNode as L}from"./nodes/heading-node.js";import{extractDocumentSearchFacets as H}from"./search-facets.js";import{formatDocumentMetadata as K}from"../../search/utils.js";import{TagNode as N}from"./nodes/tag-node.js";import{MARKDOC_PARTIALS_DATA_KEY as R}from"../../../store.js";const j=Symbol(),et=(n,r)=>async(e,c,i,s)=>{if(r?.excludeFromSearch)return;P.reset();const a=await e.getNavText?.()||D.basename(e.fsPath),u=_.Ast.fromJSON(c.ast),f=new I({partials:s.getGlobalConfig(R)||{},renderTag:x(s.markdocOptions.tags),getInnerContent:b,ast:u,skipConditionals:!0}),d=Array.from(f.transform());return{async getLLMsTxts(){const o=r?.seo,g=o&&typeof o=="object"&&"description"in o?String(o.description):void 0,C=U(d);return[{title:a,description:g,slug:e.slug,fsPath:e.fsPath,content:C,includeInLLMsTxt:!0}]},async getSearchDocuments(){return F(e,d,n,a)}}};function F(n,r,e,c){const i=n.slug,s=new Map,a=n.metadata||{},u=H(a,e),f=K(a),d=f?`Metadata:
|
|
3
2
|
${f}
|
|
4
|
-
`:"";let o=[];for(const t of r)if(t instanceof
|
|
3
|
+
`:"";let o=[];for(const t of r)if(t instanceof L){o.splice(t.attributes.level-1,6);const l=t.attributes.level>2,m=o[o.length-1]?.title,S=o[o.length-1]?.url,T=l&&m?m:O(c,t),A=l&&S?S:t.getUrl(i),h={title:T,content:"",url:A,level:t.attributes.level,toc:o.map(v=>p(v.section)).join(`
|
|
5
4
|
`)};(t.attributes.level>1||p(t)!==c)&&(h.content+=h.content?`
|
|
6
|
-
`:"",h.content+=t.content.trimEnd()),
|
|
7
|
-
`)});else{const l=t.parentNode?.id??
|
|
8
|
-
`:"",
|
|
9
|
-
`),fsPath:n.fsPath,locale:C,product:n.product?.name,facets:
|
|
10
|
-
`+
|
|
5
|
+
`:"",h.content+=t.content.trimEnd()),s.set(t.id,h),o.push({section:t,title:T,url:A})}else if(t instanceof N)s.set(t.id,{title:t.content,content:t.content,url:t.getUrl(i),level:t.attributes.level+1,toc:o.map(l=>p(l.section)).concat(t.content).join(`
|
|
6
|
+
`)});else{const l=t.parentNode?.id??j,m=s.get(l)??{title:c,content:"",url:i,level:1/0,toc:""};m.content+=m.content?`
|
|
7
|
+
`:"",m.content+=t.content.trimEnd(),s.set(l,m)}const g=w(Array.from(s.values())),C=y(n.fsPath);return g.filter(t=>t.content).map(t=>({title:t.title,url:t.url,content:[d,t.toc||`# ${c}`,t.content].filter(Boolean).join(`
|
|
8
|
+
`),fsPath:n.fsPath,locale:C,product:n.product?.name,facets:u}))}function k(n){return n.length/4}function w(n){if(n.length===0)return[];const r=[];let e=n[0];for(let c=1;c<n.length;c++){const i=n[c],s=k(e.content),a=k(i.content),u=c===n.length-1;a<E&&(s<M||u)&&i.level>e.level?e.content+=`
|
|
9
|
+
`+i.content:(r.push(e),e=i)}return r.push(e),r}function O(n,r){return r.content===n?n:`${n} \u2192 ${p(r)}`}function p(n){return n.content.replace(/^#+/,"").trim()}export{et as getAiDocumentsStore};
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { SectionNode, type SectionNodeParams } from './section-node.js';
|
|
2
|
-
declare const HeadingNode_base:
|
|
3
|
-
new (...args: any[]): {
|
|
4
|
-
[x: string]: any;
|
|
5
|
-
"__#private@#id": string;
|
|
6
|
-
get id(): string;
|
|
7
|
-
};
|
|
8
|
-
} & typeof SectionNode;
|
|
2
|
+
declare const HeadingNode_base: typeof SectionNode;
|
|
9
3
|
export declare class HeadingNode extends HeadingNode_base {
|
|
10
4
|
constructor(params: Omit<SectionNodeParams, 'parentNode'>);
|
|
11
5
|
getUrl(slug: string): string;
|
|
@@ -17,19 +17,7 @@ export declare class SectionNode {
|
|
|
17
17
|
get rbacTeams(): string[] | undefined;
|
|
18
18
|
}
|
|
19
19
|
type Constructor<T = any> = new (...args: any[]) => T;
|
|
20
|
-
export declare function WithCounterId<TBase extends Constructor>(Base: TBase):
|
|
21
|
-
|
|
22
|
-
[x: string]: any;
|
|
23
|
-
"__#private@#id": number;
|
|
24
|
-
get id(): number;
|
|
25
|
-
};
|
|
26
|
-
} & TBase;
|
|
27
|
-
export declare function WithSlugId<TBase extends Constructor>(Base: TBase): {
|
|
28
|
-
new (...args: any[]): {
|
|
29
|
-
[x: string]: any;
|
|
30
|
-
"__#private@#id": string;
|
|
31
|
-
get id(): string;
|
|
32
|
-
};
|
|
33
|
-
} & TBase;
|
|
20
|
+
export declare function WithCounterId<TBase extends Constructor>(Base: TBase): TBase;
|
|
21
|
+
export declare function WithSlugId<TBase extends Constructor>(Base: TBase): TBase;
|
|
34
22
|
export {};
|
|
35
23
|
//# sourceMappingURL=section-node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getInnerText as o}from"../../../../../markdoc/helpers/get-inner-text.js";import{slugger as
|
|
1
|
+
import{getInnerText as o}from"../../../../../markdoc/helpers/get-inner-text.js";import{slugger as d}from"../../../../../utils/slugger.js";class c{#t;#e;#r;#n;constructor(t){const{node:r,content:n,rbacTeams:i,parentNode:s}=t;this.#t=r,this.#e=n,this.#r=s,this.#n=i}get attributes(){return this.#t.attributes}get content(){return this.#e}get node(){return this.#t}get id(){throw new Error("SectionNode needs an id mixin applied")}get parentNode(){return this.#r}get rbacTeams(){return this.#n}}function a(e){let t=0;return class extends e{#t;get id(){return this.#t!==void 0?this.#t:(this.#t=++t,this.#t)}}}function g(e){return class extends e{#t;get id(){if(this.#t!==void 0)return this.#t;const t=this;return this.#t=d.slug(o(t.node.children),{replaceDots:!0,replaceSlashes:!0}),this.#t}}}export{c as SectionNode,a as WithCounterId,g as WithSlugId};
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { SectionNode, type SectionNodeParams } from './section-node.js';
|
|
2
2
|
export declare const TAG_TITLE_ATTRIBUTES: readonly ["title", "alt", "name", "label"];
|
|
3
|
-
declare const TagNode_base:
|
|
4
|
-
new (...args: any[]): {
|
|
5
|
-
[x: string]: any;
|
|
6
|
-
"__#private@#id": number;
|
|
7
|
-
get id(): number;
|
|
8
|
-
};
|
|
9
|
-
} & typeof SectionNode;
|
|
3
|
+
declare const TagNode_base: typeof SectionNode;
|
|
10
4
|
export declare class TagNode extends TagNode_base {
|
|
11
5
|
constructor(params: SectionNodeParams);
|
|
12
6
|
getUrl(slug: string): string;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import type { Node } from '@markdoc/markdoc';
|
|
2
2
|
import type { GetInnerContentFn } from '../../../../types/index.js';
|
|
3
3
|
import type { SearchNode } from './nodes/types.js';
|
|
4
|
+
import type { RenderTagFn } from '../../../types/plugins/markdown.js';
|
|
4
5
|
type Params = {
|
|
5
6
|
ast: Node;
|
|
6
7
|
partials: Record<string, Node>;
|
|
7
8
|
skipConditionals?: boolean;
|
|
8
9
|
getInnerContent: GetInnerContentFn;
|
|
10
|
+
renderTag?: RenderTagFn;
|
|
9
11
|
};
|
|
10
12
|
export declare class AstToSearchNodeTransformer {
|
|
11
13
|
#private;
|
|
12
|
-
constructor({ ast, partials, skipConditionals, getInnerContent }: Params);
|
|
14
|
+
constructor({ ast, partials, skipConditionals, getInnerContent, renderTag }: Params);
|
|
13
15
|
transform(): Generator<SearchNode, void, any>;
|
|
14
16
|
}
|
|
15
17
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{logger as
|
|
1
|
+
import{logger as N}from"../../../tools/notifiers/logger.js";import{isNode as h}from"../../../../markdoc/helpers/guards/is-node.js";import{isConditionalNode as T}from"../../../../markdoc/helpers/guards/is-conditional-node.js";import{isContentNode as m}from"../../../../markdoc/helpers/guards/is-content-node.js";import{getNodeAttribute as u}from"../../../../markdoc/helpers/get-node-attribute.js";import{extractRbacFromCondition as w}from"../../../../markdoc/helpers/extract-rbac-from-condition-node.js";import{TextNode as l}from"./nodes/text-node.js";import{TAG_TITLE_ATTRIBUTES as b,TagNode as p}from"./nodes/tag-node.js";import{HeadingNode as a}from"./nodes/heading-node.js";import{joinSectionContent as d}from"./join-section-content.js";class B{#s;#o;#i;#r;#c;constructor({ast:i,partials:t,skipConditionals:r=!1,getInnerContent:s,renderTag:o}){if(this.#s=i,this.#o=t,this.#i=r,this.#r=s,this.#c=o,!this.#s||!h(this.#s))throw new Error("ast is not a valid Markdoc Node.")}*transform(){yield*this.#e(this.#s,{parentNode:null})}*#e(i,t,r=this.#r){if(!(!i||!h(i))){if(T(i)){if(this.#i)return;const s=w(i);s&&s.length>0&&(yield*this.#t(i,{...t,rbacTeams:s},r));return}if(m(i)){yield new l({node:i,content:r([i],{skipConditionals:this.#i}),...t});return}if(i.type==="heading"){yield new a({node:i,content:r([i],{skipConditionals:this.#i}),rbacTeams:t?.rbacTeams});return}if(i.type==="tag"){yield*this.#l(i,t,r);return}yield*this.#t(i,t,r)}}*#l(i,t,r=this.#r){switch(i.tag){case"partial":{const s=i.attributes.file,o=i.attributes.variables??{};if(s&&this.#o[s]){yield*this.#e(this.#o[s],t,(e,n)=>r(e,{...n,variables:o}));return}N.warn(`Could not create search indexes for partial \u201C${s}\u201D: file not found`);return}case"cards":case"tabs":case"code-walkthrough":{yield*this.#t(i,t,r);return}case"markdoc-example":{const s=r([i],{skipConditionals:this.#i});yield new l({node:i,content:s,...t});return}case"code-snippet":{const s=u(i,"title"),o=r([i],{skipConditionals:this.#i});if(s){const e=new p({node:i,content:s,...t});t={...t,parentNode:e},yield e}o&&(yield new l({node:i,content:o,...t}));return}default:{const s=this.#n(i,t,r);if(s){yield*s;return}const o=b.find(c=>c in i.attributes),e=(o&&u(i,o))??"",n=typeof e=="string"?e:r([e]);if(n){const c=new p({node:i,content:n,...t});t={...t,parentNode:c},yield c}if(y(i))yield*this.#t(i,t,r);else{const c=r([i],{skipConditionals:this.#i});c&&(yield new l({node:i,content:c,...t}))}return}}}#n(i,t,r){const s=()=>y(i)?d([...this.#t(i,t,r)]):"",o=this.#c?.(i,{getBody:s});return o===void 0?void 0:[new l({node:i,content:o,...t})]}*#t(i,t,r=this.#r){for(const s of[...Object.values(i.slots),...i.children])for(const o of this.#e(s,t,r))o instanceof a&&(t={...t,parentNode:o}),yield o}}function y(f){return f.children.length>0||Object.keys(f.slots).length>0}export{B as AstToSearchNodeTransformer};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContentItemModel, OpenAPIParser, Options, OpenAPIInfo } from '@redocly/openapi-docs';
|
|
2
|
-
import type { AfterRoutesCreatedLifecycleContext, MdPageStaticData, PageRouteDetails } from '../../../types';
|
|
2
|
+
import type { AfterRoutesCreatedActions, AfterRoutesCreatedLifecycleContext, MdPageStaticData, PageRouteDetails } from '../../../types';
|
|
3
3
|
import type { AiDocumentsStore } from '../../../plugins/search/types.js';
|
|
4
4
|
import type { TagOperations } from '../types.js';
|
|
5
5
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
@@ -14,5 +14,5 @@ export declare const getAiDocumentsStore: ({ parser, options, info, tagOperation
|
|
|
14
14
|
getSearchFacets: () => Map<string, SearchFacet>;
|
|
15
15
|
includeInLLMsTxt: boolean;
|
|
16
16
|
excludeFromSearch?: boolean;
|
|
17
|
-
}) => (route: PageRouteDetails, staticData: MdPageStaticData, context: AfterRoutesCreatedLifecycleContext) => Promise<AiDocumentsStore | undefined>;
|
|
17
|
+
}) => (route: PageRouteDetails, staticData: MdPageStaticData, context: AfterRoutesCreatedLifecycleContext, actions: AfterRoutesCreatedActions) => Promise<AiDocumentsStore | undefined>;
|
|
18
18
|
//# sourceMappingURL=get-ai-search-documents.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as
|
|
2
|
-
`;for(const[T
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as w}from"@redocly/config";import{basename as L,join as _}from"node:path";import q from"@markdoc/markdoc";import{joinSectionContent as C}from"../../../plugins/markdown/search/join-section-content.js";import{toMarkdown as G}from"../../../plugins/markdown/search/to-markdown.js";import{AstToSearchNodeTransformer as J}from"../../../plugins/markdown/search/walk-sections.js";import{createRenderTagFn as z}from"../../../plugins/markdown/search/create-render-tag-fn.js";import{canDownloadApiDefinition as B,isResourcePubliclyAccessible as V}from"../../../utils/rbac.js";import{PUBLIC_API_DEFINITIONS_FOLDER as Y}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as H}from"../../../../constants/common.js";import{getLlmsTxtMdPathBySlug as I}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{AiSearchIndexer as K}from"../ai-search-indexer.js";import{getLocaleFromRelativePath as Q}from"../../../fs/utils/get-locale-from-relative-path.js";import{extractDocumentSearchFacets as W}from"./search-facets.js";import{formatDocumentMetadata as X}from"../../search/utils.js";import{llmsTxtLink as M}from"../../search/llmstxt/index.js";import{replaceFileExtension as Z}from"../store-definition-bundles.js";const k=new Map,we=({parser:s,options:c,info:t,tagOperations:r,relativePath:n,openapiContentItem:e,metadata:i,getSearchFacets:o,includeInLLMsTxt:a,excludeFromSearch:d})=>async(u,m,l,j)=>{if(d)return;const U=await u.getNavText?.()||L(u.fsPath),A=new K(s,c,u.baseSlug||u.slug),p=A.addItem(e);if(!p)return;const O=await l.getConfig(),b=Array.isArray(p.title)?p.title.join(" "):p.title;let $,f,y=k.get(n);if((e.type==="tag"||e.type==="section"&&e.infoDefinition)&&!y){const{all:D,publiclyAccessible:g}=ie(r.tagged,A,O),{all:S,publiclyAccessible:T}=oe(r.untagged,A,O);k.set(n,{taggedSearchDocuments:new Map(D),untaggedSearchDocuments:S,publiclyAccessibleTaggedSearchDocuments:new Map(g),publiclyAccessibleUntaggedSearchDocuments:T})}y=k.get(n);const h="#";switch(e.type){case"operation":const D=A.getOperation(e);$=f=te({title:b,security:s.definition.security,document:p,version:p.version||t.version,headingLevel:h,operation:D});break;case"section":if(e.infoDefinition){y=k.get(n),f=await P({parser:s,info:t,staticData:m,relativePath:n,headingLevel:h,pageName:U,config:O}),f+=`
|
|
2
|
+
`;for(const[S,T]of y?.publiclyAccessibleTaggedSearchDocuments?.entries()||[]){if(!T.length)continue;const E=s.definition.tags?.find(F=>F.name===S);f+=x({title:E?.["x-displayName"]||S,description:E?.description,operationSearchDocuments:T,headingLevel:`${h}#`})}const g=y?.publiclyAccessibleUntaggedSearchDocuments||[];g.length&&(f+=x({title:"Other",description:void 0,operationSearchDocuments:g,headingLevel:`${h}#`})),$=await P({parser:s,info:t,staticData:m,relativePath:n,headingLevel:h,pageName:U,config:O})}else if(e.ast){const g=new q.Ast.Node("document",{},e.ast),S=Array.from(new J({ast:g,partials:{},renderTag:z(j.markdocOptions.tags),getInnerContent:G,skipConditionals:!0}).transform());f=$=C(S)}break;case"tag":f=x({title:b,description:e.description,operationSearchDocuments:y?.publiclyAccessibleTaggedSearchDocuments.get(e.name)||[],headingLevel:h}),$=x({title:b,description:e.description,operationSearchDocuments:[],headingLevel:h});break;case"rsrc":case"prompt":case"tool":f=ce({title:b,description:e.description,name:e.name,xMcpConfig:s.definition["x-mcp"],headingLevel:h}),$=f;break}return{async getLLMsTxts(){return[{title:e.name,description:e.type==="tag"?e.description:void 0,content:f||"",slug:u.slug,fsPath:u.fsPath,includeInLLMsTxt:a}]},async getSearchDocuments(){if(e.type==="operation"||e.type==="section"&&(e.infoDefinition||e.ast)||e.type==="tag"){const D=Q(u.fsPath),g=W({...p,...i},t,o);return[{title:b,description:Array.isArray(p.text)?p.text.join(" "):p.text,content:$||"",url:p.url??u.slug,fsPath:u.fsPath,locale:D,product:u.product?.name,rbacTeams:p.rbacTeams,facets:g}]}return[]}}};async function P({parser:s,info:c,staticData:t,relativePath:r,pageName:n,headingLevel:e,config:i}){const o=X(c["x-metadata"]);let a=c.title?`${e} ${c.title}
|
|
3
3
|
|
|
4
4
|
`:`${e} ${n}
|
|
5
5
|
|
|
@@ -12,30 +12,30 @@ import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as F,join a
|
|
|
12
12
|
`:"",e=`${e}#`,a+=o.length?`Metadata:
|
|
13
13
|
${o}
|
|
14
14
|
`:"",a+=`
|
|
15
|
-
`,a+=
|
|
15
|
+
`,a+=v({parser:s,headingLevel:e}),a+=ne({parser:s,headingLevel:e}),a+=await ee({info:c,staticData:t,relativePath:r,pageName:n,headingLevel:e,config:i}),a}function x({title:s="",description:c,operationSearchDocuments:t,headingLevel:r}){let n=`${r} ${s}
|
|
16
16
|
|
|
17
17
|
`;return c&&(n+=`${c}
|
|
18
18
|
|
|
19
|
-
`),t.length&&t.forEach(e=>{const
|
|
19
|
+
`),t.length&&t.forEach(e=>{const i=Array.isArray(e.title)?e.title.join(" "):e.title;n+=`${r}# ${i}${e.deprecated?" (deprecated)":""}
|
|
20
20
|
|
|
21
|
-
`,n+=` - ${
|
|
22
|
-
`}),n}function
|
|
21
|
+
`,n+=` - ${M({title:`${e.httpMethod?.toUpperCase()} ${e.httpPath}`,description:Array.isArray(e.text)?e.text.join(" "):e.text,slug:I(e.url)})}`,n+=`
|
|
22
|
+
`}),n}function v({parser:s,headingLevel:c}){const{servers:t}=s.definition;if(t&&t.length){let r=`${c} Servers
|
|
23
23
|
|
|
24
|
-
`;return t.forEach(n=>{
|
|
25
|
-
`:"",
|
|
24
|
+
`;return t.forEach(n=>{r+=n.description?`${n.description}
|
|
25
|
+
`:"",r+=`\`\`\`
|
|
26
26
|
${n.url}
|
|
27
27
|
\`\`\`
|
|
28
28
|
|
|
29
|
-
`,n.variables&&(
|
|
30
|
-
`,Object.entries(n.variables).forEach(([e,
|
|
31
|
-
`,i
|
|
32
|
-
`:"",i
|
|
33
|
-
`:""}),
|
|
34
|
-
`)}),
|
|
29
|
+
`,n.variables&&(r+=`Variables:
|
|
30
|
+
`,Object.entries(n.variables).forEach(([e,i])=>{r+=`- \`${e}\`${i.description?`: ${i.description}`:""}
|
|
31
|
+
`,r+=i.default?`Default: ${JSON.stringify(i.default)}
|
|
32
|
+
`:"",r+=i.enum?`Enum: ${i.enum.map(o=>JSON.stringify(o)).join(", ")}
|
|
33
|
+
`:""}),r+=`
|
|
34
|
+
`)}),r}return""}async function ee({info:s,staticData:c,relativePath:t,pageName:r,headingLevel:n,config:e}){const i=_(c.props?.outdir||"",Y,Z(t,".yaml")),o=e.access?.rbac,a=e.access?.requiresLogin;if(B(i,o??{},a??!1,{isAuthenticated:!1,teams:[H]})){let d=`${n} Download OpenAPI description
|
|
35
35
|
|
|
36
|
-
`;return
|
|
36
|
+
`;return d+=M({title:s.title||r||"OpenAPI definition",description:void 0,slug:i}),d}return""}function ne({parser:s,headingLevel:c}){if(!s.definition.components?.securitySchemes)return"";let t=`${c} Security
|
|
37
37
|
|
|
38
|
-
`;const{securitySchemes:
|
|
38
|
+
`;const{securitySchemes:r}=s.definition.components;return Object.keys(r).forEach(n=>{const e=r[n];e&&(t+=`${c}# ${n}
|
|
39
39
|
|
|
40
40
|
`,t+=e.description?`${e.description}
|
|
41
41
|
|
|
@@ -47,46 +47,46 @@ ${n.url}
|
|
|
47
47
|
`),e.bearerFormat&&(t+=`Bearer Format: ${e.bearerFormat}
|
|
48
48
|
`),e.flows?.implicit?.authorizationUrl&&(t+=`Authorization URL: ${e.flows.implicit?.authorizationUrl}
|
|
49
49
|
`),e.flows?.implicit?.scopes&&(t+=`Scopes:
|
|
50
|
-
`,Object.entries(e.flows?.implicit?.scopes||{}).forEach(([
|
|
50
|
+
`,Object.entries(e.flows?.implicit?.scopes||{}).forEach(([i,o])=>{t+=`- \`${i}\`: ${o}
|
|
51
51
|
`})),e.flows?.password?.tokenUrl&&(t+=`Token URL: ${e.flows.password?.tokenUrl}
|
|
52
52
|
`),e.flows?.password?.scopes&&(t+=`Scopes:
|
|
53
|
-
`,Object.entries(e.flows?.password?.scopes||{}).forEach(([
|
|
53
|
+
`,Object.entries(e.flows?.password?.scopes||{}).forEach(([i,o])=>{t+=`- \`${i}\`: ${o}
|
|
54
54
|
`})),t+=`
|
|
55
|
-
`)}),t}function
|
|
55
|
+
`)}),t}function te({title:s,security:c,document:t,version:r,headingLevel:n,operation:e}){const{text:i,httpMethod:o,httpPath:a,deprecated:d}=t,u=re(t.parameters||[],`${n}#`),m=se(`${n}#`,t.parameters,e);let l=s?`${n} ${s}${d?" (deprecated)":""}
|
|
56
56
|
|
|
57
|
-
`:"";return l+=
|
|
57
|
+
`:"";return l+=i?`${i}
|
|
58
58
|
|
|
59
59
|
`:"",l+=`Endpoint: ${o?.toUpperCase()} ${a}
|
|
60
|
-
`,l+=
|
|
60
|
+
`,l+=r?`Version: ${r}
|
|
61
61
|
`:"",l+=t.security?.length?`Security: ${t.security.join(", ")}
|
|
62
|
-
`:c?.length?`Security: ${c.map(
|
|
62
|
+
`:c?.length?`Security: ${c.map(j=>j.id).join(", ")}
|
|
63
63
|
`:"",l+=`
|
|
64
64
|
`,l+=u?`${u}
|
|
65
65
|
`:"",l+=`
|
|
66
66
|
`,l+=`${m.join(`
|
|
67
|
-
`)}`,l}function
|
|
67
|
+
`)}`,l}function ce({title:s,name:c,xMcpConfig:t,headingLevel:r}){const n=t?.tools.find(i=>i.name===c);if(!n)return"";let e=`${r} ${s}
|
|
68
68
|
|
|
69
69
|
`;return e+=n.description?`${n.description}
|
|
70
70
|
|
|
71
|
-
`:"",e+=`${
|
|
71
|
+
`:"",e+=`${r}# Input schema:
|
|
72
72
|
|
|
73
73
|
`,e+=`\`\`\`json
|
|
74
74
|
${JSON.stringify(n.inputSchema,null,2)}
|
|
75
75
|
\`\`\`
|
|
76
76
|
|
|
77
|
-
`,n.outputSchema&&(e+=`${
|
|
77
|
+
`,n.outputSchema&&(e+=`${r}# Output schema:
|
|
78
78
|
|
|
79
79
|
`,e+=`\`\`\`json
|
|
80
80
|
${JSON.stringify(n.outputSchema,null,2)}
|
|
81
81
|
\`\`\`
|
|
82
82
|
|
|
83
|
-
`),e}function
|
|
84
|
-
`)}function
|
|
83
|
+
`),e}function se(s,c,t){return!c&&!t||!t?.responses?[]:t?.responses.filter(n=>!n.content?.mediaTypes[0]?.schema).map(n=>`${s} ${R(`response ${n.code} fields`)}
|
|
84
|
+
`)}function re(s,c){const t={};for(const n of s){const e=`${n.place}${n.mediaType?` (${n.mediaType})`:""}`;t[e]=[...t[e]||[],n]}return Object.entries(t).map(([n,e])=>{const i=e.map(o=>{const a=" ",d=[...o.path||[],o.name],u=Array.isArray(o.description)?o.description.join(" "):o.description;let m=` - \`${d.join(".")}\` (${o.type}${o.required?", required":""})
|
|
85
85
|
`;return m+=u?`${a}${u.trim()}
|
|
86
86
|
`:"",o.enum?m+=`${a}Enum: ${o.enum.map(l=>JSON.stringify(l)).join(", ")}
|
|
87
87
|
`:o.example&&(m+=`${a}Example: ${o.example}
|
|
88
|
-
`),m});return`${c} ${
|
|
88
|
+
`),m});return`${c} ${R(n)}:
|
|
89
89
|
|
|
90
|
-
${
|
|
90
|
+
${i.join(`
|
|
91
91
|
`)}`}).join(`
|
|
92
|
-
`)}function
|
|
92
|
+
`)}function ie(s,c,t){const r=[],n=[];return s.forEach((e,i)=>{const o=[],a=[];e.forEach(d=>{const u=c.addItem(d);u&&(o.push(u),N({[w]:d[w],slug:u.url},t)&&a.push(u))}),r.push([i,o]),n.push([i,a])}),{all:r,publiclyAccessible:n}}function oe(s,c,t){const r=[],n=[];return s.forEach(e=>{const i=c.addItem(e);i&&(r.push(i),N({[w]:e[w],slug:i.url},t)&&n.push(i))}),{all:r,publiclyAccessible:n}}function R(s){return s.charAt(0).toUpperCase()+s.slice(1)}function N(s,c){return c.access?.requiresLogin?!0:V(s,c)}export{we as getAiDocumentsStore};
|
package/dist/server/plugins/scorecards/database/repositories/scorecards-config-repository.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { DatabaseClient } from '../../../../providers/database/client.js';
|
|
2
2
|
import type { DatabaseScorecardsConfig, DatabaseScorecardsConfigDto } from '../../../../providers/database/databases/sqlite-db/schemas/scorecards-config-table.js';
|
|
3
|
+
import type { RepositoryInstanceOptions } from '../../../../providers/database/types.js';
|
|
3
4
|
export declare class ScorecardsConfigRepository {
|
|
4
5
|
#private;
|
|
5
6
|
constructor(db: DatabaseClient);
|
|
7
|
+
static create(options: RepositoryInstanceOptions): Promise<ScorecardsConfigRepository>;
|
|
8
|
+
sync(): Promise<void>;
|
|
9
|
+
close(): Promise<void>;
|
|
6
10
|
findActiveConfigByKey(key: string): Promise<DatabaseScorecardsConfig | null>;
|
|
7
11
|
findAllActiveConfigs(): Promise<DatabaseScorecardsConfig[]>;
|
|
8
12
|
insertConfig(config: DatabaseScorecardsConfigDto): Promise<DatabaseScorecardsConfig>;
|
package/dist/server/plugins/scorecards/database/repositories/scorecards-config-repository.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{and as
|
|
1
|
+
import{and as a,eq as n,isNull as c}from"drizzle-orm";import{scorecardsConfigTable as r}from"../../../../providers/database/databases/sqlite-db/schemas/scorecards-config-table.js";import{DatabaseConnectionFactory as s}from"../../../../providers/database/database-connection-factory.js";class o{#t;constructor(t){this.#t=t}static async create(t){const e=await s.create(t);if(!e)throw new Error("Failed to create db connection for scorecards config repository");return new o(e.client)}async sync(){await this.#t.sync()}async close(){await this.#t.close()}async findActiveConfigByKey(t){return(await this.#t.client.select().from(r).where(a(n(r.key,t),c(r.archivedAt))).limit(1))[0]??null}async findAllActiveConfigs(){return await this.#t.client.select().from(r).where(c(r.archivedAt))}async insertConfig(t){const e=await this.#t.client.insert(r).values(t).returning();if(!e[0])throw new Error(`Failed to insert scorecard config with key: ${t.key}`);return e[0]}async updateConfigById(t,e){const i=await this.#t.client.update(r).set(e).where(n(r.id,t)).returning();if(!i[0])throw new Error(`Failed to update scorecard config with id: ${t}`);return i[0]}async archiveConfigById(t,e){const i=await this.#t.client.update(r).set({archivedAt:e}).where(n(r.id,t)).returning();if(!i[0])throw new Error(`Failed to archive scorecard config with id: ${t}`);return i[0]}}export{o as ScorecardsConfigRepository};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ScorecardsConfig } from '@redocly/config';
|
|
2
2
|
import type { ServiceInstanceOptions } from '../../../providers/database/types.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export declare class ScorecardsConfigService extends
|
|
3
|
+
import { BaseService } from '../../../providers/database/base-service.js';
|
|
4
|
+
import { ScorecardsConfigRepository } from './repositories/scorecards-config-repository.js';
|
|
5
|
+
export declare class ScorecardsConfigService extends BaseService<ScorecardsConfigRepository> {
|
|
6
6
|
#private;
|
|
7
|
-
constructor(
|
|
7
|
+
constructor(repository: ScorecardsConfigRepository, options?: ServiceInstanceOptions);
|
|
8
8
|
static getInstance(options: ServiceInstanceOptions): Promise<ScorecardsConfigService>;
|
|
9
9
|
syncConfig(scorecardsConfig: ScorecardsConfig, onConfigChange?: (key: string) => Promise<void>): Promise<void>;
|
|
10
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ulid as
|
|
1
|
+
import{ulid as l}from"ulid";import{logger as s}from"../../../tools/notifiers/logger.js";import{BaseService as h}from"../../../providers/database/base-service.js";import{InstanceCacheResolver as y}from"../../../providers/database/instance-cache-resolver.js";import{shaHex as m}from"../../../utils/crypto/sha-hex.js";import{slug as v}from"../../../../utils/slugger.js";import{withTimestamp as f}from"../../../utils/time/with-timestamp.js";import{ScorecardsConfigRepository as g}from"./repositories/scorecards-config-repository.js";class c extends h{static#e=new y(async e=>new c(await g.create(e),e));constructor(e,r){super(r,{repository:e,createRepository:g.create})}static async getInstance(e){return c.#e.get(e)}async syncConfig(e,r){const n=new Set;(!Array.isArray(e)||e.length===0)&&s.verbose("No scorecard configs to sync"),s.verbose(`Starting scorecard config sync for ${e.length} config(s)`);for(const t of e)try{const i=t.key;if(!/^[a-z0-9-]+$/i.test(i)){s.error(`Skipping invalid scorecard config item: key "${i}" does not match kebab-case format (letters, numbers, and dashes only)`,{scorecard:t});continue}n.add(i);const o=this.#i(t),a=await this.runRead(d=>d.findActiveConfigByKey(i));if(a){if(a.configHash===o){s.verbose(`Config "${i}" unchanged, skipping update`);continue}s.verbose(`Updating config "${i}"`),await this.#r(a.id,t,o)}else s.verbose(`Inserting new config "${i}"`),await this.#t(i,t,o);r&&await r(i)}catch(i){s.error("Error processing scorecard config item:",{error:i.message??i,scorecard:t})}await this.#s(n),s.verbose("Sync scorecard configuration: success")}#i(e){const r=JSON.stringify({entities:e.entities,levels:e.levels});return m(r)}async#t(e,r,n){await this.runWrite(t=>t.insertConfig(f({id:`sc_${l()}`,key:e,slug:v(e),name:r.name,description:r.description??null,entitiesFilter:JSON.stringify(r.entities),levels:JSON.stringify(r.levels),configHash:n,archivedAt:null})))}async#r(e,r,n){const t=f({entitiesFilter:JSON.stringify(r.entities),levels:JSON.stringify(r.levels),configHash:n,archivedAt:null},{fields:["updatedAt"]});await this.runWrite(i=>i.updateConfigById(e,t))}async#s(e){const r=await this.runRead(t=>t.findAllActiveConfigs()),n=new Date().toISOString();for(const t of r)if(!e.has(t.key)){s.verbose(`Archiving removed config "${t.key}"`);try{await this.runWrite(i=>i.archiveConfigById(t.id,n))}catch(i){s.error(`Error archiving config item "${t.key}":`,i.message??i)}}}}export{c as ScorecardsConfigService};
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import p from"node:path";import{existsSync as
|
|
1
|
+
import p from"node:path";import{existsSync as X}from"node:fs";import{writeFile as D,access as N,rm as k,constants as B}from"fs/promises";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import U from"picomatch";import{combineUrls as j}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as E}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as G}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as H}from"../../../constants/common.js";import{envConfig as C}from"../../../config/env-config.js";import{logger as a}from"../../../tools/notifiers/logger.js";import{shaHexShort as Y}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as P}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as K}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{buildAgentFeedbackLlmsFooter as J}from"../../../utils/llmstxt/agent-feedback-llms-footer.js";import{validateLLMsTxtConfig as V,generateLLMsTxt as W}from"../llmstxt/index.js";import{ensureDir as F}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as q,extractTeamsFromScopeItems as z,getRbacTeamsListForResource as Q}from"../../../utils/rbac.js";const w=20,S="llms.txt:";async function Dt(t,i,{embeddingsEnabled:o,llmstxtEnabled:n}){const c=p.join(t.outdir,H);if(!n){try{await N(c,B.W_OK),await k(c)}catch{}if(!o)return}o&&a.info("Preparing semantic documents..."),n&&a.info(`${S} Generating llms.txt files...`);const T=a.startTiming(),l=a.startTiming(),m=t.getGlobalConfig("seo"),f=m?.llmstxt,d=C.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED??!1,M=p.resolve(t.outdir,G),u=t.getConfig(),O=u.access?.rbac??{},b=t.getAllRoutes(),y=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||E,I=(f?.excludeFiles||[]).map(e=>U(e)),R=[];if(await P(b,w,async e=>{if(e.excludeFromSearch)return;const v=await Z(e,t),x=await tt(e,v,i,t);if(x){if(n)for(const s of await x.getLLMsTxts()){if(I.some($=>$(s.fsPath)))continue;const g=K(s.slug),r=p.join(t.outdir,g);F(r);const L=d?J(m,s.slug):void 0,A=L?`
|
|
2
|
+
|
|
3
|
+
${L}`:"";await D(r,`${s.content}${A}`),t.setResourceResponseHeaders(g,[{name:"X-Robots-Tag",value:"noindex, follow"},...u.seo?.siteUrl?[{name:"Link",value:`<${j(u.seo.siteUrl,s.slug)}>; rel="canonical"`}]:[]]),s.includeInLLMsTxt&&q(e,u)&&R.push(s)}if(o&&C.isBuildMode){const s=await x.getSearchDocuments();if(!s.length)return;const g=et(e,O),r=e.versions?.find(({active:A})=>A),L=r&&{folder:r.folderId,label:r.label,default:r.default};await ot(s,e.fsPath,g,M,y,L)}}}),o&&a.infoTime(l,"Semantic search documents prepared"),R.length)try{V(f);const e=await W(R,f,{title:m?.title,description:m?.description},i);F(c),await D(c,e),a.infoTime(T,`${S} files generated`)}catch(e){a.error(`${S} Failed to generate llms.txt file. ${e.message}`)}}async function Z(t,i){return t.getStaticData?t.getStaticData(t,i):{}}async function tt(t,i,o,n){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[h]:t[h],[_]:t[_]},o,n)}function et(t,i){const o=z(t?.[h]);return o?.length?o:Q(t,i)}async function ot(t,i,o,n,c,T){await P(t,w,async l=>{const m=`${Y(i+l.content)}.json`,f=F(p.join(n,m)),d=l.locale===E?c:l.locale;X(f)||await D(f,JSON.stringify({...l,rbacTeams:o||[],version:T,locale:d}),"utf-8")})}export{Dt as prepareSemanticDocuments};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ServiceInstanceOptions } from './types.js';
|
|
2
|
+
type SyncableRepository = {
|
|
3
|
+
sync: () => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
type RunOptions<T> = {
|
|
6
|
+
onRepositoryMissing?: () => Promise<T> | T;
|
|
7
|
+
skipSync?: boolean;
|
|
8
|
+
};
|
|
9
|
+
type BaseServiceConfig<R extends SyncableRepository | null> = {
|
|
10
|
+
repository: NonNullable<R>;
|
|
11
|
+
createRepository?: (options: ServiceInstanceOptions) => Promise<NonNullable<R>>;
|
|
12
|
+
};
|
|
13
|
+
export declare abstract class BaseService<R extends SyncableRepository | null> {
|
|
14
|
+
#private;
|
|
15
|
+
protected constructor(options: ServiceInstanceOptions | undefined, config: BaseServiceConfig<R>);
|
|
16
|
+
protected get isLocalDbMode(): boolean;
|
|
17
|
+
protected getRepository(): R;
|
|
18
|
+
protected setRepository(repository: NonNullable<R>): void;
|
|
19
|
+
protected recreateRepository(): Promise<NonNullable<R> | null>;
|
|
20
|
+
protected syncRepositoryIfNeeded(): Promise<void>;
|
|
21
|
+
protected runRead<T>(run: (repo: NonNullable<R>) => Promise<T>, options?: RunOptions<T>): Promise<T>;
|
|
22
|
+
protected runWrite<T>(run: (repo: NonNullable<R>) => Promise<T>, options?: RunOptions<T>): Promise<T>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=base-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{envConfig as a}from"../../config/env-config.js";import{logger as n}from"../../tools/notifiers/logger.js";import{SQLD_REMOTE_DATABASE_URL_NO_DEPLOYMENT_YET_VAR as p}from"../../constants/plugins/catalog-entities.js";import{HTTP_TRANSIENT_RETRY as o,describeTransientError as c,isTransientSqldError as R,withTransientErrorRetry as s}from"./transient-sqld-error.js";class w{#i;#r;#o=null;#s;constructor(t,r){this.#i=t,this.#r=l(t)==="local",this.#o=r.repository,this.#s=r.createRepository}get isLocalDbMode(){return this.#r}getRepository(){return this.#o}setRepository(t){this.#o=t}async recreateRepository(){return!this.#s||!this.#i?null:this.#s(this.#i)}async syncRepositoryIfNeeded(){if(this.#r)return;const t=this.getRepository();t&&await s(()=>t.sync(),o)}async runRead(t,r){if(r?.skipSync||await this.syncRepositoryIfNeeded(),this.#r)try{return await this.#t(t,r)}catch(e){throw this.#e("read",e),e}try{return await s(()=>this.#t(t,r),o)}catch(e){throw this.#e("read",e),e}}async runWrite(t,r){if(this.#r)try{return await this.#t(t,r)}catch(e){throw this.#e("write",e),e}try{return await s(async()=>{try{return await this.#t(t,r)}catch(e){throw await this.#a(e),e}},o)}catch(e){throw this.#e("write",e),e}}async#t(t,r){const e=this.getRepository();if(!e){if(r?.onRepositoryMissing)return await r.onRepositoryMissing();throw new Error("Database repository is not initialized")}return t(e)}async#a(t){if(R(t))try{const r=await this.recreateRepository();r&&this.setRepository(r)}catch(r){n.warn(`Reconnect attempt failed, letting original error propagate: ${c(r)}`)}}#e(t,r){const e=this.constructor.name,h=r instanceof Error?c(r):String(r),y=this.#r?"local-no-retry":"remote-retry-enabled";n.error(`[${e}] ${t} operation failed (${y}): ${h}`,r)}}function l(i){if(i?.databaseType)return i.databaseType;const t=a.SQLD_REMOTE_DATABASE_URL||i?.sqldRemoteDatabaseUrl,r=a.SQLD_REMOTE_DATABASE_AUTH_TOKEN||i?.sqldRemoteDatabaseAuthToken;return t&&t!==p&&r?"remote":"local"}export{w as BaseService};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{logger as o}from"../../tools/notifiers/logger.js";import{envConfig as
|
|
1
|
+
import{logger as o}from"../../tools/notifiers/logger.js";import{envConfig as r}from"../../config/env-config.js";import{DatabaseConnectionFactory as i}from"./database-connection-factory.js";class e{static#e=!1;static async init(t){if(!(r.REDOCLY_INTERNAL_DEV||r.CI||r.isDevelopMode)&&!e.#e)try{await e.#t(t)==="PRECONNECTED"&&(e.#e=!0)}catch(a){o.error("Failed to preconnect to sqld remote database",a)}}static#t=async t=>await i.create({baseDbDir:t,databaseType:"remote"})?(o.info("Sqld remote database preconnected"),"PRECONNECTED"):(o.warn("Sqld remote database preconnect failed"),"NOT_PRECONNECTED")}export{e as DatabasePreconnectService};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DatabaseConnection, RepositoryInstanceOptions } from './types.js';
|
|
2
|
+
type WithRemoveExisting = {
|
|
3
|
+
removeExisting?: boolean;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Caches a single async-created instance (a database repository, or a service that
|
|
7
|
+
* wraps one) and reuses it across calls.
|
|
8
|
+
*
|
|
9
|
+
* A new instance is created only when none exists yet, or when the creation options
|
|
10
|
+
* change.
|
|
11
|
+
*/
|
|
12
|
+
export declare class InstanceCacheResolver<TInstance, TOptions extends WithRemoveExisting> {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(create: (options: TOptions) => Promise<TInstance>);
|
|
15
|
+
get(options: TOptions): Promise<TInstance>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createDatabaseRepositoryInstance<TRepository>(options: RepositoryInstanceOptions, repositoryName: string, repositoryClass: new (dbConnection: DatabaseConnection) => TRepository): Promise<TRepository>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=instance-cache-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{deepStrictEqual as o}from"node:assert";import{DatabaseConnectionFactory as i}from"./database-connection-factory.js";class h{#t;#e;#n;constructor(e){this.#n=e}async get(e){const n=a(e);return this.#t&&!s(this.#e,n)?this.#t:(this.#t=await this.#n(n),this.#e=n,this.#t)}}async function u(t,e,n){const r=await i.create(t);if(!r)throw new Error(`Failed to create db connection for ${e} repository`);return new n(r)}function a(t){return{...t,removeExisting:t.removeExisting??!1}}function s(t,e){if(!t)return!1;try{return o(t,e),!1}catch{return!0}}export{h as InstanceCacheResolver,u as createDatabaseRepositoryInstance};
|