MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / addSpec

Function addSpec

packages/plugins/openapi/src/sdk/plugin.ts:647–755  ·  view source on GitHub ↗
(config: OpenApiSpecConfig)

Source from the content-addressed store, hash-verified

645 });
646
647 const addSpec = (config: OpenApiSpecConfig) =>
648 Effect.gen(function* () {
649 // Resolve URL → text and parse BEFORE opening a transaction. Holding
650 // `BEGIN` across a network fetch is the Hyperdrive deadlock path.
651 const resolved = yield* resolveSpecForInput(config.spec, httpClientLayer);
652 const compiled = yield* compileOpenApiSpec(resolved.specText);
653
654 // Defaults the add page derives from its preview, applied here so
655 // headless callers (MCP, API) get the same integration the UI's
656 // add flow would produce - see e2e/scenarios/connect-handoff.test.ts:
657 // - effectiveBaseUrl: the spec's first server, used to anchor the
658 // derived auth template's absolute URLs. It is NOT stored as the
659 // connection baseUrl - the request host is resolved per call from
660 // the operation's extracted `servers`.
661 // - authenticationTemplate: the spec's declared security schemes
662 // (else the Add-connection modal is a dead "No authentication"
663 // end with nowhere to paste a credential)
664 // An explicit input always wins; for auth, an explicit EMPTY array
665 // means "no auth methods" and suppresses the derivation.
666 const explicitBaseUrl = config.baseUrl;
667 const needsDerivedBaseUrl = explicitBaseUrl == null;
668 const needsDerivedAuth = config.authenticationTemplate == null;
669 const preview =
670 needsDerivedBaseUrl || needsDerivedAuth
671 ? yield* previewSpecText(resolved.specText).pipe(
672 Effect.flatMap((rawPreview) =>
673 enrichPreviewWithDiscoveredOAuth({
674 specText: resolved.specText,
675 preview: rawPreview,
676 sourceUrl: specInputToSourceUrl(config.spec),
677 baseUrl: config.baseUrl,
678 }),
679 ),
680 )
681 : undefined;
682 const derivedBaseUrl =
683 needsDerivedBaseUrl && preview ? firstBaseUrlForPreview(preview) : undefined;
684 const effectiveBaseUrl = explicitBaseUrl ?? (derivedBaseUrl || undefined);
685 const derivedAuthenticationTemplate =
686 needsDerivedAuth && preview
687 ? deriveAuthenticationTemplateFromPreview(preview, effectiveBaseUrl)
688 : undefined;
689
690 const slug = IntegrationSlug.make(config.slug);
691
692 // Block re-adding an existing slug. The core `integrations.register`
693 // primitive upserts (so boot re-registration is idempotent), but an
694 // explicit add must NOT silently clobber an existing integration's
695 // tools, connections, and policies. To add more auth, update the
696 // existing integration instead.
697 const existing = yield* ctx.core.integrations.get(slug);
698 if (existing) {
699 return yield* new IntegrationAlreadyExistsError({ slug });
700 }
701
702 const specHash = yield* sha256Hex(resolved.specText);
703
704 const integrationConfig: OpenApiIntegrationConfig = {

Callers

nothing calls this directly

Calls 11

compileOpenApiSpecFunction · 0.90
firstBaseUrlForPreviewFunction · 0.90
sha256HexFunction · 0.90
resolveSpecForInputFunction · 0.85
specInputToSourceUrlFunction · 0.85
transactionMethod · 0.80
getMethod · 0.65

Tested by

no test coverage detected