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

Function addSpec

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

Source from the content-addressed store, hash-verified

806 });
807
808 const addSpec = (config: OpenApiSpecConfig) =>
809 Effect.gen(function* () {
810 yield* ctx.core.integrations.authorizeWrite();
811 // Resolve URL → text and parse BEFORE opening a transaction. Holding
812 // `BEGIN` across a network fetch is the Hyperdrive deadlock path.
813 const resolved = yield* resolveSpecForInput(config, httpClientLayer);
814 const compiled = resolved.keepPathItem
815 ? undefined
816 : yield* compileOpenApiSpec(resolved.specText);
817 const adapter = yield* resolveSpecFormatAdapter(
818 options?.specFormats ?? [],
819 config.specFormat,
820 config.spec.kind === "url" ? config.spec.url : undefined,
821 );
822 const derivedIdentity =
823 adapter?.deriveIdentity && resolved.document
824 ? adapter.deriveIdentity(resolved.document)
825 : null;
826 const resolvedSlug = config.slug?.trim() || derivedIdentity?.slug;
827 if (!resolvedSlug) {
828 return yield* new OpenApiParseError({
829 message: "OpenAPI integration slug is required",
830 });
831 }
832
833 // Defaults the add page derives from its preview, applied here so
834 // headless callers (MCP, API) get the same integration the UI's
835 // add flow would produce - see e2e/scenarios/connect-handoff.test.ts:
836 // - effectiveBaseUrl: the spec's first server, used to anchor the
837 // derived auth template's absolute URLs. It is NOT stored as the
838 // connection baseUrl - the request host is resolved per call from
839 // the operation's extracted `servers`.
840 // - authenticationTemplate: the spec's declared security schemes
841 // (else the Add-connection modal is a dead "No authentication"
842 // end with nowhere to paste a credential)
843 // An explicit input always wins; for auth, an explicit EMPTY array
844 // means "no auth methods" and suppresses the derivation.
845 const explicitBaseUrl = config.baseUrl ?? resolved.baseUrl;
846 const needsDerivedBaseUrl = explicitBaseUrl == null;
847 const needsDerivedAuth = config.authenticationTemplate == null;
848 // Spec-format selections (resolved.keepPathItem) preview via the
849 // streaming path: the whole-document parse of a Graph-sized source is
850 // the measured isolate OOM. The OAuth-discovery enrich re-parses the
851 // full text for the same reason, and an adapter spec declares its
852 // auth (or the adapter supplies the template), so it is skipped.
853 const preview =
854 needsDerivedBaseUrl || needsDerivedAuth
855 ? resolved.keepPathItem
856 ? yield* previewSpecTextStreaming(resolved.specText, resolved.keepPathItem)
857 : yield* previewSpecText(resolved.specText).pipe(
858 Effect.flatMap((rawPreview) =>
859 enrichPreviewWithDiscoveredOAuth({
860 specText: resolved.specText,
861 preview: rawPreview,
862 specUrl: resolved.specUrl ?? specInputToSpecUrl(config.spec),
863 baseUrl: explicitBaseUrl,
864 }),
865 ),

Callers

nothing calls this directly

Calls 13

compileOpenApiSpecFunction · 0.90
resolveSpecFormatAdapterFunction · 0.90
firstBaseUrlForPreviewFunction · 0.90
sha256HexFunction · 0.90
resolveSpecForInputFunction · 0.85
specInputToSpecUrlFunction · 0.85
getMethod · 0.65

Tested by

no test coverage detected