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

Function updateSpec

packages/plugins/openapi/src/sdk/plugin.ts:935–1077  ·  view source on GitHub ↗
(rawSlug: string, input?: OpenApiUpdateSpecInput)

Source from the content-addressed store, hash-verified

933 // the curated description, connections, and policies are all untouched -
934 // this is the "spec changed upstream" path, not a re-add.
935 const updateSpec = (rawSlug: string, input?: OpenApiUpdateSpecInput) =>
936 Effect.gen(function* () {
937 const slug = IntegrationSlug.make(rawSlug);
938 const record = yield* ctx.core.integrations.get(slug);
939 const current = record ? decodeOpenApiIntegrationConfig(record.config) : null;
940 if (!record || !current) {
941 return yield* new IntegrationNotFoundError({ slug });
942 }
943
944 // The new spec source: explicit input wins; otherwise re-fetch from
945 // where the spec originally came from. A pasted-blob integration has
946 // no origin, so updating it requires a new input.
947 const nextOverrides = input?.specOverrides ?? current.specOverrides ?? [];
948 const storedSourceHash = current.sourceSpecHash ?? current.specHash;
949 const storedSourceText =
950 input?.spec === undefined && !current.specUrl && input?.specOverrides !== undefined
951 ? storedSourceHash
952 ? yield* ctx.storage.getSpec(storedSourceHash)
953 : null
954 : null;
955 const specInput: OpenApiSpecInput | null =
956 input?.spec ??
957 (current.specUrl
958 ? { kind: "url", url: current.specUrl }
959 : storedSourceText
960 ? { kind: "blob", value: storedSourceText }
961 : null);
962 if (specInput === null) {
963 return yield* new OpenApiParseError({
964 message:
965 "This integration's spec was pasted inline and has no source URL to re-fetch. Provide the updated spec content.",
966 });
967 }
968
969 // Resolve + compile BEFORE the transaction (same Hyperdrive-deadlock
970 // rule as addSpec: never hold BEGIN across a network fetch).
971 const resolved = yield* resolveSpecForInput(
972 {
973 spec: specInput,
974 specFormat: current.specFormat,
975 specOverrides: nextOverrides,
976 headers: current.headers,
977 queryParams: current.queryParams,
978 baseUrl: current.baseUrl,
979 },
980 httpClientLayer,
981 );
982 const compiled = resolved.keepPathItem
983 ? undefined
984 : yield* compileOpenApiSpec(resolved.specText);
985
986 const previousOperations = yield* ctx.storage.listOperations(rawSlug);
987 const previousNames = new Set(previousOperations.map((op) => op.toolName));
988
989 // The resolved spec text lives in the plugin blob store keyed by its
990 // content hash (`spec/<hash>`); the config carries only the hash. Put
991 // the blob outside the transaction - re-puts are idempotent and an
992 // aborted config update just leaves an unreferenced blob.

Callers

nothing calls this directly

Calls 11

compileOpenApiSpecFunction · 0.90
sha256HexFunction · 0.90
resolveSpecForInputFunction · 0.85
specInputToSpecUrlFunction · 0.85
getMethod · 0.65
transactionMethod · 0.65
updateMethod · 0.65
listMethod · 0.65

Tested by

no test coverage detected