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

Function updateSpec

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

Source from the content-addressed store, hash-verified

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