(config: GoogleBundleConfig)
| 184 | const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer; |
| 185 | |
| 186 | const addBundle = (config: GoogleBundleConfig) => |
| 187 | Effect.gen(function* () { |
| 188 | const urls = uniqueUrls(config.urls); |
| 189 | const conversion = yield* fetchGoogleBundleConversion(urls, httpClientLayer); |
| 190 | const compiled = yield* compileOpenApiSpec(conversion.specText); |
| 191 | const slug = IntegrationSlug.make(config.slug?.trim() || DEFAULT_GOOGLE_SLUG); |
| 192 | |
| 193 | const existing = yield* ctx.core.integrations.get(slug); |
| 194 | if (existing) { |
| 195 | return yield* new IntegrationAlreadyExistsError({ slug }); |
| 196 | } |
| 197 | |
| 198 | const specHash = yield* sha256Hex(conversion.specText); |
| 199 | const integrationConfig: GoogleIntegrationConfig = { |
| 200 | specHash, |
| 201 | googleDiscoveryUrls: urls, |
| 202 | ...(config.baseUrl ? { baseUrl: config.baseUrl } : {}), |
| 203 | ...(conversion.authenticationTemplate |
| 204 | ? { authenticationTemplate: conversion.authenticationTemplate } |
| 205 | : {}), |
| 206 | }; |
| 207 | |
| 208 | yield* ctx.storage.putSpec(specHash, conversion.specText); |
| 209 | yield* ctx.storage.putDefs(specHash, JSON.stringify(compiled.hoistedDefs)); |
| 210 | |
| 211 | yield* ctx.transaction( |
| 212 | Effect.gen(function* () { |
| 213 | yield* ctx.core.integrations.register({ |
| 214 | slug, |
| 215 | name: config.name?.trim() || "Google", |
| 216 | description: config.description ?? "Google APIs", |
| 217 | config: integrationConfig satisfies GoogleIntegrationConfig as IntegrationConfig, |
| 218 | canRemove: true, |
| 219 | canRefresh: true, |
| 220 | }); |
| 221 | yield* ctx.storage.putOperations( |
| 222 | String(slug), |
| 223 | openApiStoredOperationsFromCompiled(String(slug), compiled), |
| 224 | ); |
| 225 | }), |
| 226 | ); |
| 227 | |
| 228 | // Default the health check to the People API identity call (`people.get` |
| 229 | // with `resourceName=people/me`) when the bundle includes the People API, |
| 230 | // so connections report alive/expired + identity out of the box. Declared |
| 231 | // through core's own storage; the user can adjust it via the editor. |
| 232 | const defaultHealthCheck = defaultGoogleHealthCheck(urls, compiled.definitions); |
| 233 | if (defaultHealthCheck) { |
| 234 | yield* ctx.core.integrations.setHealthCheck(slug, defaultHealthCheck); |
| 235 | } |
| 236 | |
| 237 | return { slug, toolCount: compiled.definitions.length }; |
| 238 | }); |
| 239 | |
| 240 | const updateBundle = (rawSlug: string, input?: GoogleUpdateInput) => |
| 241 | Effect.gen(function* () { |
nothing calls this directly
no test coverage detected