connectors 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/CONNECTORS_FRAMEWORK.md +54 -99
  4. data/MCP_CLIENT.md +5 -5
  5. data/README.md +5 -3
  6. data/app/connectors/gmail/api.rb +6 -14
  7. data/app/connectors/gmail/connector.rb +11 -24
  8. data/app/connectors/gmail/mime_builder.rb +0 -3
  9. data/app/connectors/gmail/mime_parser.rb +1 -2
  10. data/app/connectors/gmail/polling.rb +7 -14
  11. data/app/connectors/resend/connector.rb +2 -4
  12. data/app/controllers/connectors/actions_controller.rb +0 -6
  13. data/app/controllers/connectors/credentials_controller.rb +10 -23
  14. data/app/controllers/connectors/grants_controller.rb +6 -11
  15. data/app/controllers/connectors/types_controller.rb +18 -45
  16. data/app/controllers/connectors/webhooks_controller.rb +2 -4
  17. data/app/jobs/connectors/deliver_webhook_job.rb +2 -4
  18. data/app/models/connectors/credential_share.rb +3 -10
  19. data/app/models/connectors/grant.rb +2 -4
  20. data/config/routes.rb +6 -13
  21. data/db/migrate/20260518210324_create_connectors_grants.rb +4 -11
  22. data/db/migrate/20260521140000_create_connectors_credential_shares.rb +2 -8
  23. data/docs/releasing.md +4 -4
  24. data/lib/connectors/action.rb +4 -7
  25. data/lib/connectors/action_builder.rb +5 -12
  26. data/lib/connectors/action_runner.rb +5 -11
  27. data/lib/connectors/auth_injection.rb +7 -18
  28. data/lib/connectors/client_builder.rb +4 -10
  29. data/lib/connectors/configuration.rb +9 -39
  30. data/lib/connectors/connector.rb +31 -83
  31. data/lib/connectors/credential_schema.rb +12 -29
  32. data/lib/connectors/credential_tester.rb +3 -4
  33. data/lib/connectors/credential_type_registry.rb +9 -20
  34. data/lib/connectors/credential_types/http_auth.rb +18 -55
  35. data/lib/connectors/engine.rb +3 -6
  36. data/lib/connectors/errors.rb +2 -5
  37. data/lib/connectors/middleware/authenticate_generic.rb +4 -14
  38. data/lib/connectors/middleware/pre_authentication.rb +2 -13
  39. data/lib/connectors/oauth/authorize_url.rb +3 -9
  40. data/lib/connectors/oauth/client_credentials.rb +0 -4
  41. data/lib/connectors/oauth/pkce.rb +3 -9
  42. data/lib/connectors/oauth/revoke.rb +2 -6
  43. data/lib/connectors/oauth1.rb +4 -8
  44. data/lib/connectors/permission_check.rb +2 -4
  45. data/lib/connectors/poll_runner.rb +1 -5
  46. data/lib/connectors/pre_authentication_helpers.rb +4 -9
  47. data/lib/connectors/version.rb +1 -1
  48. data/lib/connectors/webhook_context.rb +8 -18
  49. data/lib/connectors/webhook_lifecycle.rb +1 -8
  50. data/lib/connectors/webhook_methods.rb +2 -6
  51. data/openapi.yaml +16 -16
  52. metadata +21 -1
@@ -32,11 +32,9 @@ module Connectors
32
32
  initializer :connectors_register_credential_types do
33
33
  reg = ::Connectors::CredentialTypeRegistry
34
34
  reg.register(:oauth2, reg::OAUTH2)
35
- # Phase 4 — n8n's `OAuth1Api` base type
36
- # (packages/nodes-base/credentials/OAuth1Api.credentials.ts:1-72).
35
+ # Register the OAuth1 base credential schema.
37
36
  reg.register(:oauth1_api, reg::OAUTH1)
38
- # Phase 2 — n8n's generic HTTP auth credential types
39
- # (packages/nodes-base/credentials/Http*Auth.credentials.ts).
37
+ # Register reusable HTTP authentication schemas.
40
38
  reg.register(:http_basic_auth, ::Connectors::CredentialTypes::HTTP_BASIC_AUTH)
41
39
  reg.register(:http_bearer_auth, ::Connectors::CredentialTypes::HTTP_BEARER_AUTH)
42
40
  reg.register(:http_header_auth, ::Connectors::CredentialTypes::HTTP_HEADER_AUTH)
@@ -54,8 +52,7 @@ module Connectors
54
52
  #
55
53
  # Walks every Engine root (including the host's main app) and globs each
56
54
  # one's `app/connectors/` — the union covers shipped connectors here in
57
- # the engine, plus host-app overrides under flow-api's own
58
- # `app/connectors/` (if/when the host decides to ship its own).
55
+ # the engine and connectors defined in the host's app/connectors directory.
59
56
  config.to_prepare do
60
57
  ::Rails::Engine.subclasses.map(&:instance).push(::Rails.application).uniq.each do |engine|
61
58
  dir = engine.root.join("app/connectors")
@@ -32,11 +32,8 @@ module Connectors
32
32
  class AuthenticationFailed < ApiError; end
33
33
  class Forbidden < ApiError; end
34
34
 
35
- # A credential was used with a node that's not on its `supported_nodes`
36
- # allowlist, OR the credential is marked generic_auth-only and the caller
37
- # is a non-HTTP-Request node. Mirrors the visibility gate n8n applies via
38
- # the credential's `supportedNodes` field (interfaces.ts:381) and
39
- # `genericAuth` flag (interfaces.ts:379).
35
+ # Raised when a credential does not permit the requested node type
36
+ # under its supported_nodes and generic_auth settings.
40
37
  class CredentialNotPermitted < Error
41
38
  def initialize(connector_key, node_type, reason: nil)
42
39
  msg = "credential #{connector_key.inspect} is not permitted for node #{node_type.inspect}"
@@ -2,17 +2,9 @@ require "base64"
2
2
 
3
3
  module Connectors
4
4
  module Middleware
5
- # Faraday middleware that applies a connector's declarative
6
- # `authenticate type: :generic, properties: {...}` block to every
7
- # outgoing request, mirroring n8n's `IAuthenticateGeneric` runtime
8
- # (n8n source: packages/workflow/src/interfaces.ts:278-288 + the
9
- # request-helpers consumer at
10
- # packages/core/src/node-execute-functions.ts).
11
- #
12
- # The Grant's credentials hash supplies values for the
13
- # `={{$credentials.x}}` templates inside `properties`. Resolution runs
14
- # per-request so credentials that rotate between requests (e.g. after a
15
- # `preAuthentication` hook lands in Phase 3) are reflected immediately.
5
+ # Apply resolved authentication properties to each outgoing request.
6
+ # Credential templates are evaluated per request so rotated values,
7
+ # including values from pre_authentication, take effect immediately.
16
8
  class AuthenticateGeneric < Faraday::Middleware
17
9
  def initialize(app, grant:, authenticate_config:)
18
10
  super(app)
@@ -63,9 +55,7 @@ module Connectors
63
55
  body.each { |k, v| env.body[k.to_s] = v }
64
56
  end
65
57
 
66
- # n8n's `IRequestOptionsSimplifiedAuth.auth` shortcut for HTTP Basic
67
- # (interfaces.ts:198-202). Sets the `Authorization: Basic ...` header
68
- # directly so we don't double-handle.
58
+ # Set the HTTP Basic Authorization header from username and password.
69
59
  def apply_basic_auth(env, auth)
70
60
  return if auth.nil?
71
61
  username = auth[:username] || auth["username"]
@@ -1,18 +1,7 @@
1
1
  module Connectors
2
2
  module Middleware
3
- # Runs the connector's `pre_authentication` block (Phase 3) before each
4
- # outgoing request — but only when the cached credentials look stale.
5
- # Mirrors n8n's contract at packages/workflow/src/interfaces.ts:374-377;
6
- # n8n's runtime gates re-runs on `credentialsExpired: boolean` (see
7
- # `ICredentialsHelper.runPreAuthentication` at :232-238). We use the
8
- # same conceptual signal: if the credentials hash carries an
9
- # `expires_at` (unix seconds) and it's in the past — OR no expires_at
10
- # has ever been set — the hook fires and its return value is merged
11
- # into the grant's credentials before the AuthenticateGeneric step.
12
- #
13
- # Reference impl: CrowdStrikeOAuth2Api.credentials.ts:62-76 — fetches
14
- # an access token from `/oauth2/token` using client_id + client_secret,
15
- # returns `{ sessionToken }` which feeds `authenticate.headers.Authorization`.
3
+ # Run pre_authentication when expires_at is absent or in the past.
4
+ # Merge returned credentials before AuthenticateGeneric injects them.
16
5
  class PreAuthentication < Faraday::Middleware
17
6
  def initialize(app, grant:, pre_auth_block:)
18
7
  super(app)
@@ -16,11 +16,8 @@ module Connectors
16
16
  @secrets = Connectors.configuration.oauth_credentials_for(connector_class.connector_key)
17
17
  end
18
18
 
19
- # The connector declares a DEFAULT scope set; callers can override it
20
- # per request via the `scope:` argument (multi-tenant hosts often
21
- # need a wider or narrower scope than the connector's baseline).
22
- # n8n's `Gmail OAuth2 API.credentials.ts` does the same thing — the
23
- # node ships defaults, the workflow editor can ask for more.
19
+ # The declared scopes are defaults; callers can override them
20
+ # per authorization request through the scope argument.
24
21
  def build(owner:, return_to: nil, scope: nil, name: nil, grant: nil)
25
22
  pkce = pkce_params if @config[:grant_type].to_s == "pkce"
26
23
 
@@ -66,10 +63,7 @@ module Connectors
66
63
  Connectors::OAuth::Pkce.generate
67
64
  end
68
65
 
69
- # Reads from Connectors.configuration.app_callback_url when the host
70
- # has wired a separate frontend callback page (Activepieces-style split
71
- # frontend/backend); otherwise falls back to the engine's own
72
- # `/<connector>/callback` route (n8n-style monolithic).
66
+ # Use a configured frontend callback or the mounted engine callback.
73
67
  def redirect_uri
74
68
  Connectors.configuration.resolved_app_callback_url(@connector_class.connector_key)
75
69
  end
@@ -7,10 +7,6 @@ module Connectors
7
7
  # `grant_type=client_credentials` + `client_id`/`client_secret` to the
8
8
  # provider's token endpoint and returns a normalized token hash that the
9
9
  # OAuthController writes to a new or explicitly selected Grant.
10
- #
11
- # n8n parity: `OAuth2Api.credentials.ts:1-45` declares the `grantType`
12
- # field with `clientCredentials` as one option; the runtime branch lives
13
- # at `oauth.service.ts:783-789`.
14
10
  class ClientCredentials
15
11
  def self.exchange(connector_class)
16
12
  new(connector_class).exchange
@@ -4,15 +4,9 @@ require "base64"
4
4
 
5
5
  module Connectors
6
6
  module OAuth
7
- # RFC 7636 — Proof Key for Code Exchange. We generate a random
8
- # `code_verifier`, derive `code_challenge = BASE64URL(SHA256(verifier))`
9
- # (method `S256`), and embed the verifier in the signed OAuth state
10
- # token so the callback can include it in the token exchange.
11
- #
12
- # n8n parity: `oauth.service.ts:578-586` — same `S256` derivation,
13
- # verifier stashed in encrypted credential data until callback. We use
14
- # the signed state token instead of a DB write so the flow stays
15
- # stateless on the engine side.
7
+ # RFC 7636 PKCE using S256. Generate a random verifier and derive
8
+ # BASE64URL(SHA256(verifier)). Store the verifier in authenticated, encrypted
9
+ # OAuth state for use during the callback token exchange.
16
10
  module Pkce
17
11
  module_function
18
12
 
@@ -9,13 +9,9 @@ module Connectors
9
9
  # request shape (Google's revoke is `?token=`, etc.), so a connector
10
10
  # can also override the whole call with a block:
11
11
  #
12
- # revoke_token do |connector, grant|
13
- # connector.client.delete("oauth/tokens/#{grant.credentials_hash['access_token']}")
12
+ # revoke_token do |grant|
13
+ # client.delete("oauth/tokens/#{grant.credentials_hash['access_token']}")
14
14
  # end
15
- #
16
- # n8n parity: per-provider, no centralized contract — n8n's oauth
17
- # service implements it ad-hoc on a per-credential basis. We give
18
- # connectors a single uniform DSL.
19
15
  class Revoke
20
16
  def self.call(connector_class, grant)
21
17
  new(connector_class, grant).call
@@ -5,12 +5,8 @@ require "uri"
5
5
  require "faraday"
6
6
 
7
7
  module Connectors
8
- # OAuth1.0a — RFC 5849. Two-leg request-token / access-token flow with
9
- # HMAC-SHA1/SHA256/SHA512 request signing. n8n parity:
10
- # `oauth.service.ts:601-700` (request-token leg) +
11
- # `oauth1-credential.controller.ts:43-101` (callback / access-token leg).
12
- # n8n uses the `oauth-1.0a` npm package; we implement the signing inline
13
- # to keep the engine dependency-free.
8
+ # OAuth1.0a (RFC 5849) request-token and access-token exchanges
9
+ # with HMAC-SHA1, HMAC-SHA256 or HMAC-SHA512 signing.
14
10
  module OAuth1
15
11
  module_function
16
12
 
@@ -20,7 +16,7 @@ module Connectors
20
16
  "HMAC-SHA512" => "SHA512"
21
17
  }.freeze
22
18
 
23
- # Phase 1 of the flow: request the unauthorized request token. Sends an
19
+ # Request-token step: request the unauthorized request token. Sends an
24
20
  # OAuth1-signed POST to `requestTokenUrl`. Provider returns
25
21
  # `oauth_token` + `oauth_token_secret` (URL-encoded form). We need both
26
22
  # to (a) build the authorize URL the owner is redirected to and (b)
@@ -60,7 +56,7 @@ module Connectors
60
56
  }
61
57
  end
62
58
 
63
- # Phase 2: trade the verifier + token for the long-lived access token.
59
+ # Exchange the verifier and request token for an access token.
64
60
  def exchange_access_token(connector_class, oauth_token:, oauth_verifier:, oauth_token_secret:)
65
61
  config = connector_class.oauth1_config or
66
62
  raise Connectors::Error.new("#{connector_class}: oauth1 ... DSL not declared")
@@ -1,8 +1,6 @@
1
1
  module Connectors
2
- # Visibility gate for credentials. Mirrors n8n's two-pronged check
3
- # (interfaces.ts:379 + :381) — `genericAuth: true` lets the generic
4
- # HTTP-Request node use any credential, and `supportedNodes: [...]`
5
- # restricts a credential to a specific node allowlist when set.
2
+ # Enforce supported_nodes restrictions, including generic_auth permission
3
+ # for :http_request. An empty allowlist permits every node type.
6
4
  #
7
5
  # Call from inside a node's execution wrapper before it touches the grant:
8
6
  #
@@ -3,11 +3,7 @@ module Connectors
3
3
  # and filters even when consumers share credentials. Omitting the key keeps
4
4
  # the legacy, per-grant cursor for existing single-consumer integrations.
5
5
  #
6
- # n8n parity: `INodeType#poll(this: IPollFunctions)` (interfaces.ts:2060),
7
- # cursor persistence via `getWorkflowStaticData('node')`
8
- # (interfaces.ts:1257-1274). The scheduler that decides *when* to fire
9
- # this is a workflow-roadmap concern; this primitive just exposes the
10
- # one-shot contract.
6
+ # The host schedules calls and delivers returned items.
11
7
  class PollRunner
12
8
  GROUP = "polling".freeze
13
9
 
@@ -1,10 +1,6 @@
1
1
  module Connectors
2
- # Helpers passed to a connector's `pre_authentication` block — mirrors
3
- # n8n's `IHttpRequestHelper.helpers` surface (n8n source:
4
- # packages/workflow/src/interfaces.ts:210-212). The block uses this to
5
- # fetch a fresh token from an arbitrary endpoint without needing the
6
- # full connector client (which itself depends on credentials that may
7
- # not exist yet on first auth).
2
+ # HTTP helper for pre_authentication. Fetches credentials independently
3
+ # of the connector client, whose authentication may not yet be available.
8
4
  #
9
5
  # pre_authentication do |credentials, helpers|
10
6
  # response = helpers.http_request(
@@ -44,9 +40,8 @@ module Connectors
44
40
  req.body = body if body
45
41
  end
46
42
 
47
- # Match n8n's `helpers.httpRequest` default: non-2xx becomes an error
48
- # the pre_authentication hook can catch. Keeps "auth endpoint
49
- # exploded" failures visible instead of silently merging a nil token.
43
+ # Raise on non-2xx responses so the hook cannot silently merge
44
+ # an unsuccessful token response into credentials.
50
45
  if response.status >= 400
51
46
  body_preview = response.body.is_a?(String) ? response.body.byteslice(0, 200) : response.body.inspect
52
47
  raise Connectors::ApiError.new(
@@ -1,3 +1,3 @@
1
1
  module Connectors
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -1,13 +1,7 @@
1
1
  module Connectors
2
- # Rich context object passed to `Connector#handle_webhook`. Mirrors n8n's
3
- # `IWebhookFunctions` (packages/workflow/src/interfaces.ts:1327-1350): the
4
- # handler gets the parsed body AND headers AND query AND a stable
5
- # `webhook_name` for multi-webhook providers, without having to thread
6
- # `event.request_object.foo` through everywhere.
7
- #
8
- # Forwards a small set of methods to the underlying `WebhookEvent` so
9
- # legacy handlers written against `event.payload_hash` keep working — see
10
- # `Connector#handle_webhook` arity detection in `DeliverWebhookJob`.
2
+ # Request context passed to Connector#handle_webhook. Exposes parsed and
3
+ # raw body, headers, query and webhook group. Delegates payload aliases
4
+ # and exposes the persisted WebhookEvent for existing handlers.
11
5
  class WebhookContext
12
6
  attr_reader :event
13
7
 
@@ -15,33 +9,29 @@ module Connectors
15
9
  @event = event
16
10
  end
17
11
 
18
- # Parsed body (n8n: `getBodyData()`). Always a Hash — falls back to {}.
12
+ # Parsed body, with an empty hash fallback.
19
13
  def body
20
14
  @event.payload_hash
21
15
  end
22
16
  alias payload body
23
17
  alias payload_hash body
24
18
 
25
- # Raw (untouched) request body string. nil when the controller couldn't
26
- # capture it (form-encoded payloads where Rails consumed the stream).
27
- # n8n: `getRequestObject().rawBody`.
19
+ # Raw request body captured on the persisted event, when available.
28
20
  def raw_body
29
21
  @event.raw_body
30
22
  end
31
23
 
32
- # All request headers (n8n: `getHeaderData()`). Lowercased keys — same
33
- # normalization n8n applies via `req.headers`.
24
+ # Request headers with lowercase keys.
34
25
  def headers
35
26
  @event.headers || {}
36
27
  end
37
28
 
38
- # Query string parameters (n8n: `getQueryData()`).
29
+ # Query string parameters.
39
30
  def query
40
31
  @event.query || {}
41
32
  end
42
33
 
43
- # Webhook group name that the request hit — `:default` / `:setup` / etc.
44
- # n8n: `getWebhookName()`.
34
+ # Named webhook group, defaulting to :default.
45
35
  def webhook_name
46
36
  (@event.webhook_name || "default").to_sym
47
37
  end
@@ -2,12 +2,6 @@ module Connectors
2
2
  # Runs a connector's webhook_methods callbacks: subscribe = run create
3
3
  # (skipping when check_exists already returns true), unsubscribe = run
4
4
  # delete. State is persisted into `grant.static_data[group_name]`.
5
- #
6
- # n8n parity: this is the per-trigger activation orchestration that
7
- # `cli/src/active-workflow-runner.ts` performs around each
8
- # `INodeType#webhookMethods.default.*` call. We provide it as a connector-
9
- # side primitive so the eventual workflow-side activation manager can
10
- # call into it without re-implementing the gating.
11
5
  class WebhookLifecycle
12
6
  def self.subscribe(grant, hook_url:, webhook_name: :default)
13
7
  new(grant, webhook_name).subscribe(hook_url: hook_url)
@@ -27,8 +21,7 @@ module Connectors
27
21
  )
28
22
  end
29
23
 
30
- # Mirrors n8n: if checkExists returns true, skip create — provider
31
- # already has an equivalent subscription. Otherwise run create.
24
+ # Skip creation when check_exists finds an existing subscription.
32
25
  def subscribe(hook_url:)
33
26
  result = nil
34
27
  @grant.update_static_data!(@webhook_name) do |sub|
@@ -1,8 +1,5 @@
1
1
  module Connectors
2
- # Declarative webhook subscription lifecycle. Mirrors n8n's
3
- # `INodeType.webhookMethods.default.{checkExists, create, delete}`
4
- # (interfaces.ts:2017, 2091-2095; reference impl in
5
- # `packages/nodes-base/nodes/Postmark/PostmarkTrigger.node.ts:114-247`).
2
+ # Declarative webhook subscription callbacks.
6
3
  #
7
4
  # Provider-specific contract:
8
5
  #
@@ -28,8 +25,7 @@ module Connectors
28
25
  # end
29
26
  #
30
27
  # Multi-webhook providers (Slack has separate `default` event-delivery
31
- # group + `setup` URL-verification group — n8n's `webhooks: IWebhookDescription[]`
32
- # at interfaces.ts:2600) declare additional named groups:
28
+ # group + `setup` URL-verification group) declare additional named groups:
33
29
  #
34
30
  # webhook_methods :setup do ... end
35
31
  # webhook_methods :default do ... end
data/openapi.yaml CHANGED
@@ -1,23 +1,23 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: Connectors Engine API
4
- version: "0.1.0"
4
+ version: "0.1.1"
5
5
  description: |
6
- Rails engine exposing n8n's connections / credentials layer as a host-mountable API.
6
+ Rails engine for encrypted credentials, provider authorization, actions, webhooks, polling and remote MCP tools.
7
7
  Every endpoint is namespaced under the engine's mount path (default `/connectors`).
8
8
 
9
9
  **Auth model.** The engine itself doesn't authenticate requests — the host wires
10
10
  `Connectors.configuration.current_owner_resolver` to extract the requester from the
11
11
  controller (session, JWT, API key — host's choice). Endpoints that mutate
12
12
  credentials require an `Owner` to be resolvable; those that read enforce
13
- role-based visibility via `principal_resolver` (Phase 9).
13
+ role-based visibility via `principal_resolver`.
14
14
 
15
15
  **Source of truth.** This document is hand-maintained alongside the engine.
16
- Cross-check against `connectors/config/routes.rb` and the controller files —
16
+ Cross-check against `config/routes.rb` and the controller files —
17
17
  they are the implementation.
18
18
 
19
- **Mount path.** The host picks where the engine lives. Reference deployment
20
- (flow-api) uses `/api/v1/connectors`. The engine introspects its actual
19
+ **Mount path.** The host chooses the engine mount, such as `/connectors`
20
+ or `/api/v1/connectors`. The engine introspects its actual
21
21
  mount via `Connectors::Engine.mount_path`, so OAuth callback URLs and
22
22
  webhook subscribe URLs in responses always reflect reality.
23
23
  contact:
@@ -32,7 +32,7 @@ servers:
32
32
  default: "http://localhost:3000"
33
33
  description: Scheme + host of the host application
34
34
  mount:
35
- default: "/api/v1/connectors"
35
+ default: "/connectors"
36
36
  description: Path where the host mounts Connectors::Engine
37
37
 
38
38
  tags:
@@ -281,7 +281,7 @@ paths:
281
281
  type: { type: string, description: "connector key" }
282
282
  name: { type: string }
283
283
  data: { type: object, additionalProperties: true, description: "credential values" }
284
- external_ref: { type: string, description: "vault reference (Phase 10)" }
284
+ external_ref: { type: string, description: "vault reference" }
285
285
  is_managed: { type: boolean, default: false }
286
286
  responses:
287
287
  "201":
@@ -804,7 +804,7 @@ paths:
804
804
  - { name: webhook_name, in: path, required: true, schema: { type: string } }
805
805
  post:
806
806
  tags: [Webhooks]
807
- summary: App-level named-group webhook (Phase 7)
807
+ summary: App-level named-group webhook
808
808
  operationId: receiveAppWebhookNamed
809
809
  requestBody:
810
810
  required: true
@@ -888,12 +888,12 @@ components:
888
888
  extends: { type: array, items: { type: string }, description: "base credential types inherited from" }
889
889
  properties:
890
890
  type: array
891
- description: "n8n INodeProperties array"
891
+ description: "Credential form field descriptors"
892
892
  items: { $ref: "#/components/schemas/Field" }
893
893
  authenticate:
894
894
  type: object
895
895
  nullable: true
896
- description: "n8n IAuthenticateGeneric"
896
+ description: "Declarative credential injection properties"
897
897
  properties:
898
898
  type: { type: string, enum: [generic] }
899
899
  properties: { type: object, additionalProperties: true }
@@ -960,7 +960,7 @@ components:
960
960
 
961
961
  Action:
962
962
  type: object
963
- description: "one thing a connector can DO with a credential (n8n operation / Activepieces action)"
963
+ description: "A provider operation exposed by a connector"
964
964
  properties:
965
965
  name: { type: string, description: "machine key, e.g. send_email" }
966
966
  display_name: { type: string }
@@ -973,12 +973,12 @@ components:
973
973
  items: { $ref: "#/components/schemas/Field" }
974
974
  output:
975
975
  type: array
976
- description: "shape of the value the action returns (Activepieces returns: …)"
976
+ description: "Schema of the action result"
977
977
  items: { $ref: "#/components/schemas/Field" }
978
978
 
979
979
  Field:
980
980
  type: object
981
- description: "n8n INodeProperties — frontend renders the form from this"
981
+ description: "Input field descriptor used to render a form"
982
982
  properties:
983
983
  name: { type: string }
984
984
  displayName: { type: string }
@@ -1011,7 +1011,7 @@ components:
1011
1011
  displayOptions:
1012
1012
  type: object
1013
1013
  additionalProperties: true
1014
- description: "show/hide rules with _cnd predicates (n8n IDisplayOptions)"
1014
+ description: "Field visibility rules with _cnd predicates"
1015
1015
  options:
1016
1016
  type: array
1017
1017
  items: { type: object, additionalProperties: true }
@@ -1020,7 +1020,7 @@ components:
1020
1020
  type: object
1021
1021
  properties:
1022
1022
  id: { type: string, format: uuid }
1023
- type: { type: string, description: "connector key (n8n vocabulary)" }
1023
+ type: { type: string, description: "Connector key" }
1024
1024
  connector_key: { type: string, deprecated: true }
1025
1025
  name: { type: string, description: "display name" }
1026
1026
  external_account_id: { type: string, nullable: true }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: connectors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jackson Helio
@@ -23,6 +23,26 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: 8.1.3
26
+ - !ruby/object:Gem::Dependency
27
+ name: json
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '2.3'
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '3'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '2.3'
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '3'
26
46
  - !ruby/object:Gem::Dependency
27
47
  name: faraday
28
48
  requirement: !ruby/object:Gem::Requirement