(rawSlug: string, input?: GoogleUpdateInput)
| 238 | }); |
| 239 | |
| 240 | const updateBundle = (rawSlug: string, input?: GoogleUpdateInput) => |
| 241 | Effect.gen(function* () { |
| 242 | const slug = IntegrationSlug.make(rawSlug); |
| 243 | const record = yield* ctx.core.integrations.get(slug); |
| 244 | const current = record ? decodeGoogleIntegrationConfig(record.config) : null; |
| 245 | if (!record || !current) { |
| 246 | return yield* new IntegrationNotFoundError({ slug }); |
| 247 | } |
| 248 | |
| 249 | const urls = uniqueUrls(input?.urls ?? current.googleDiscoveryUrls ?? []); |
| 250 | const conversion = yield* fetchGoogleBundleConversion(urls, httpClientLayer); |
| 251 | const compiled = yield* compileOpenApiSpec(conversion.specText); |
| 252 | |
| 253 | const previousOperations = yield* ctx.storage.listOperations(rawSlug); |
| 254 | const previousNames = new Set(previousOperations.map((op) => op.toolName)); |
| 255 | const nextNames = new Set(compiled.definitions.map((def) => def.toolPath)); |
| 256 | |
| 257 | const specHash = yield* sha256Hex(conversion.specText); |
| 258 | yield* ctx.storage.putSpec(specHash, conversion.specText); |
| 259 | yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs)); |
| 260 | |
| 261 | const nextConfig: GoogleIntegrationConfig = { |
| 262 | ...current, |
| 263 | specHash, |
| 264 | googleDiscoveryUrls: urls, |
| 265 | }; |
| 266 | |
| 267 | yield* ctx.transaction( |
| 268 | Effect.gen(function* () { |
| 269 | yield* ctx.core.integrations.update(slug, { |
| 270 | config: nextConfig satisfies GoogleIntegrationConfig as IntegrationConfig, |
| 271 | }); |
| 272 | yield* ctx.storage.putOperations( |
| 273 | rawSlug, |
| 274 | openApiStoredOperationsFromCompiled(rawSlug, compiled), |
| 275 | ); |
| 276 | }), |
| 277 | ); |
| 278 | |
| 279 | const connections = yield* ctx.connections.list({ integration: slug }); |
| 280 | yield* Effect.forEach( |
| 281 | connections, |
| 282 | (connection) => |
| 283 | ctx.connections |
| 284 | .refresh({ |
| 285 | owner: connection.owner, |
| 286 | integration: connection.integration, |
| 287 | name: connection.name, |
| 288 | }) |
| 289 | .pipe(Effect.catchTag("ConnectionNotFoundError", () => Effect.succeed([]))), |
| 290 | { discard: true }, |
| 291 | ).pipe(Effect.catchTag("IntegrationNotFoundError", () => Effect.void)); |
| 292 | |
| 293 | return { |
| 294 | slug, |
| 295 | toolCount: compiled.definitions.length, |
| 296 | addedTools: [...nextNames].filter((name) => !previousNames.has(name)).sort(), |
| 297 | removedTools: [...previousNames].filter((name) => !nextNames.has(name)).sort(), |
nothing calls this directly
no test coverage detected