(
pluginId: string,
input: RegisterIntegrationInput,
)
| 3267 | config.onIntegrationChange ? afterCommit(config.onIntegrationChange(event)) : Effect.void; |
| 3268 | |
| 3269 | const integrationsRegister = ( |
| 3270 | pluginId: string, |
| 3271 | input: RegisterIntegrationInput, |
| 3272 | ): Effect.Effect<void, OrgWriteDeniedError | StorageFailure> => |
| 3273 | transaction( |
| 3274 | Effect.gen(function* () { |
| 3275 | const now = new Date(); |
| 3276 | const existing = yield* findIntegrationRow(input.slug); |
| 3277 | const config = input.config === undefined ? null : input.config; |
| 3278 | if (existing) { |
| 3279 | // Extension methods also run for subjectless boot/system executors, |
| 3280 | // which must be able to converge existing catalog rows. A bound |
| 3281 | // subject is an end-user principal, so its replacement is the same |
| 3282 | // workspace mutation as creation and requires the live role guard. |
| 3283 | if (subject !== null) yield* guardOrgWrite(); |
| 3284 | yield* core.updateMany("integration", { |
| 3285 | where: (b: AnyCb) => b("slug", "=", String(input.slug)), |
| 3286 | set: { |
| 3287 | plugin_id: pluginId, |
| 3288 | name: input.name ?? existing.name ?? null, |
| 3289 | description: input.description, |
| 3290 | config, |
| 3291 | can_remove: input.canRemove ?? Boolean(existing.can_remove), |
| 3292 | can_refresh: input.canRefresh ?? Boolean(existing.can_refresh), |
| 3293 | updated_at: now, |
| 3294 | }, |
| 3295 | }); |
| 3296 | return false; |
| 3297 | } |
| 3298 | // A NEW catalog row is always user intent (the add-integration |
| 3299 | // flows), including from a subjectless executor. |
| 3300 | yield* guardOrgWrite(); |
| 3301 | yield* core.create("integration", { |
| 3302 | tenant, |
| 3303 | slug: String(input.slug), |
| 3304 | plugin_id: pluginId, |
| 3305 | name: input.name ?? null, |
| 3306 | description: input.description, |
| 3307 | config, |
| 3308 | can_remove: input.canRemove ?? true, |
| 3309 | can_refresh: input.canRefresh ?? false, |
| 3310 | created_at: now, |
| 3311 | updated_at: now, |
| 3312 | }); |
| 3313 | return true; |
| 3314 | }), |
| 3315 | ).pipe( |
| 3316 | Effect.tap((created) => |
| 3317 | created |
| 3318 | ? notifyIntegrationChange({ |
| 3319 | kind: "added", |
| 3320 | pluginKey: pluginId, |
| 3321 | slug: input.slug, |
| 3322 | }) |
| 3323 | : Effect.void, |
| 3324 | ), |
| 3325 | Effect.asVoid, |
| 3326 | ); |
no test coverage detected