View Source Lightning.AdaptorService (Lightning v0.11.0)

The Adaptor Service is use to query and install adaptors in order to run jobs.

On startup, it queries the filesystem for package.json files and builds up a list of available adaptors.


The service requires at least :adaptors_path, which is used to both query which adaptors are installed and when to install new adaptors.

Another optional setting is: :repo, which must point at a module that will be used to do the querying and installing.

Installing Adaptors

Using the install/2 function an adaptor can be installed, which will also add it to the list of available adaptors.

The adaptor is marked as :installing, to allow for conditional behaviour elsewhere such as delaying or rejecting processing until the adaptor becomes available.

Looking up adaptors

The module leans on Elixir's built-in Version module to provide version lookups.

When looking up an adaptor, either a string or a tuple can be used. In the case of requesting the latest version, any one of these will return the latest version the service is aware of.

  • @openfn/language-http
  • @openfn/language-http@latest
  • {"@openfn/language-http", nil}
  • {"@openfn/language-http", "latest"}
  • {~r/language-http/, "latest"}

You can also request a specific version, or use a range specification:

  • @openfn/language-http@1.2.3
  • {"@openfn/language-http", "~> 1.2.0"}
  • {"@openfn/language-http", "< 2.0.0"}

NOTE More complex npm style install strings like: ">=0.1.0 <0.2.0" are not supported. Generally the tuple style is preferred when using range specifications as the npm style strings have a simplistic regex splitter.

See Version for more details on matching versions.



@type package_spec() :: {name :: String.t() | Regex.t(), version :: String.t() | nil}


Turns a package name and version into a string for NPM.

Since multiple versions of the same package can be installed, it's important to rely on npms built-in package aliasing.

E.g. @openfn/language-http@1.2.8 turns into:


Which is pretty long winded but necessary for the reason above.

If using this module as a base, it's likely you would need to adaptor this to suit your particular naming strategy.

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

find_adaptor(agent, package)

View Source
@spec find_adaptor(Agent.agent(), package :: String.t()) ::
  Lightning.AdaptorService.Adaptor.t() | nil
@spec find_adaptor(Agent.agent(), package_spec()) ::
  Lightning.AdaptorService.Adaptor.t() | nil
@spec install(Agent.agent(), binary()) ::
  {:ok, Lightning.AdaptorService.Adaptor.t()}
  | {:error, {Collectable.t(), exit_status :: non_neg_integer()}}
@spec install(Agent.agent(), package_spec()) ::
  {:ok, Lightning.AdaptorService.Adaptor.t()}
  | {:error, {Collectable.t(), exit_status :: non_neg_integer()}}
Link to this function

install!(agent, package_spec)

View Source
@spec install!(Agent.agent(), package_spec()) ::
  {:ok, Lightning.AdaptorService.Adaptor.t()}
  | {:error, {Collectable.t(), exit_status :: non_neg_integer()}}
Link to this function

installed?(agent, package_spec)

View Source
Link to this function


View Source