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

Function connectionsCreate

packages/core/sdk/src/executor.ts:3542–4046  ·  view source on GitHub ↗
(
      input: CreateConnectionInput,
    )

Source from the content-addressed store, hash-verified

3540 // ------------------------------------------------------------------
3541
3542 const connectionsCreate = (
3543 input: CreateConnectionInput,
3544 ): Effect.Effect<
3545 Connection,
3546 | IntegrationNotFoundError
3547 | ConnectionAlreadyExistsError
3548 | CredentialProviderNotRegisteredError
3549 | InvalidConnectionInputError
3550 | StorageFailure
3551 > =>
3552 Effect.gen(function* () {
3553 const name = connectionIdentifier(String(input.name));
3554 // Typed (not StorageError) so the HTTP edge can answer 400 with the
3555 // reason instead of an opaque 500 — callers can act on it.
3556 if (input.owner === "user" && subject == null) {
3557 return yield* new InvalidConnectionInputError({
3558 message:
3559 'Cannot create a personal connection: this context has no user subject. Create it with owner "org", or connect as a signed-in user.',
3560 });
3561 }
3562 const integrationRow = yield* findIntegrationRow(input.integration);
3563 if (!integrationRow) {
3564 return yield* new IntegrationNotFoundError({
3565 slug: input.integration,
3566 });
3567 }
3568
3569 // Create is never a replace. This early check answers the common case
3570 // with a typed 409 before any other work, but it is NOT the guard
3571 // against concurrent creates — the row insert below is: the
3572 // transaction re-checks, the primary key breaks the tie, and the
3573 // provider write happens only after the insert wins.
3574 const duplicate = yield* findConnectionRow({
3575 owner: input.owner,
3576 integration: input.integration,
3577 name,
3578 });
3579 if (duplicate) {
3580 return yield* new ConnectionAlreadyExistsError({
3581 owner: input.owner,
3582 integration: input.integration,
3583 name,
3584 });
3585 }
3586
3587 // Resolve the value origin(s) → one provider + an item_ids map (one entry
3588 // per named input). All of a connection's inputs share a single provider:
3589 // pasted inputs go to the default writable store, external `from` inputs to
3590 // their provider. Mixing pasted + external, or two external providers, is
3591 // rejected (the connection row carries one `provider`).
3592 const inputs = normalizeConnectionInputs(input);
3593 const pasted = inputs.filter((i) => "value" in i.origin);
3594 const external = inputs.filter((i) => "from" in i.origin);
3595 // A credentialed connection is born wired: it must reference at least
3596 // one credential input. An empty binding (no inputs at all — e.g. an
3597 // empty `values`/`inputs` map) is a credential with no credential: it
3598 // would persist, produce a full tool catalog, and then fail every
3599 // invocation with `connection_value_missing`. Reject it here — EXCEPT

Callers 1

createExecutorFunction · 0.85

Calls 15

connectionIdentifierFunction · 0.90
touchSubjectFunction · 0.90
findIntegrationRowFunction · 0.85
findConnectionRowFunction · 0.85
defaultWritableProviderFunction · 0.85
ownedKeysFunction · 0.85
rowIdOfFunction · 0.85
byOwnerFunction · 0.85
produceConnectionToolsFunction · 0.85
rowToConnectionFunction · 0.85

Tested by

no test coverage detected