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

Function updateSpec

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

Source from the content-addressed store, hash-verified

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

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