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

Function updateSpec

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

Source from the content-addressed store, hash-verified

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