diff --git a/for-developers/module-development/module-debugging.md b/for-developers/module-development/module-debugging.md
index a68984e..717fdfc 100644
--- a/for-developers/module-development/module-debugging.md
+++ b/for-developers/module-development/module-debugging.md
@@ -5,26 +5,36 @@ sidebar_position: 7
description: How to debug your Companion module during development.
---
-Once you've started coding, debugging the code will become essential to your success. We consider it
-important enough that we're covering it here before you dive into the details in the following sections.
+Once you've started coding, debugging the code will become essential to your
+success. We consider it important enough that we're covering it here before you
+dive into the details in the following sections.
-There are three main routes to debugging: log through the API, console.log, interactive debugging
+There are three main routes to debugging: log through the API, console.log,
+interactive debugging
## Log through the API
-Companion provides individual log pages for each module that are different from the main Companion log page.
+Companion provides individual log pages for each module that are different from
+the main Companion log page.
-You can open the module-specific log view from the connections page by clicking the ⋮ button and selecting "View logs":
+You can open the module-specific log view from the connections page by clicking
+the ⋮
+button and selecting "View logs":

-The module InstanceBase class provides a logging function that allows you to specify the log-level as one of: `"info"`, `"warn"`, `"error"`, or `"debug"`. For example:
+The module InstanceBase class provides a logging function that allows you to
+specify the log-level as one of: `"info"`, `"warn"`, `"error"`, or `"debug"`.
+For example:
```ts
this.log('debug', 'My debug message.')
```
-These messages will show up in the module-specific log page and can be filtered by selecting/deselecting the "Debug" button (or whichever log-level you chose) in the top-left of the window:
+These messages will show up in the module-specific log page and can be filtered
+by selecting/deselecting the "Debug" button (or whichever log-level you chose)
+in the top-left of the window:
> 26.01.01 00:00:00 **Module**: My debug message.
@@ -36,7 +46,9 @@ The simplest debugging method is to log to the console.
`console.log('your data/message');`
-These messages will still show up in the module-specific log page and can be filtered by selecting/deselecting the "Console" button in the top-left of the window:
+These messages will still show up in the module-specific log page and can be
+filtered by selecting/deselecting the "Console" button in the top-left of the
+window:
> 26.01.01 00:00:00 **Console**: your data/message
@@ -44,33 +56,50 @@ These messages will still show up in the module-specific log page and can be fil
:::note
-Depending on buffering, several `console.log()` messages may be grouped together, so only the first will appear to have a timestamp. Use the API `this.log()` function described above, if seeing things reported in exactly the call order is important.
+Depending on buffering, several `console.log()` messages may be grouped
+together, so only the first will appear to have a timestamp. Use the API
+`this.log()` function described above, if seeing things reported in exactly the
+call order is important.
:::
## Attach a debugger
-Often it can be useful and more convenient to attach a debugger to your module so you can create breakpoints from which you can inspect its state while the module is running. This method also has the advantage of not requiring the addition of numerous logging statements.
+Often it can be useful and more convenient to attach a debugger to your module
+so you can create breakpoints from which you can inspect its state while the
+module is running. This method also has the advantage of not requiring the
+addition of numerous logging statements.
-To attach to your module's process, first add a file named `DEBUG-INSPECT` (no suffix) in the root of your module folder. The file can be empty or have a single number in it, which specifies the debugger port number. Next time you start Companion, it will launch your module with the remote debugging protocol enabled.
+To attach to your module's process, first add a file named `DEBUG-INSPECT` (no
+suffix) in the root of your module folder. The file can be empty or have a
+single number in it, which specifies the debugger port number. Next time you
+start Companion, it will launch your module with the remote debugging protocol
+enabled.
-By default Companion will pick and use a random port that will change each launch, alternatively, you can specify a port number inside the `DEBUG-INSPECT` file to use a fixed port for debugging.
+By default Companion will pick and use a random port that will change each
+launch, alternatively, you can specify a port number inside the `DEBUG-INSPECT`
+file to use a fixed port for debugging.
-You can use any compatible debugger such as the built-in VS Code debugger, or Chrome inspector to connect to your process.
+You can use any compatible debugger such as the built-in VS Code debugger, or
+Chrome inspector to connect to your process.
:::warning
-It may not be possible to debug the `init` method from your module with this, Companion still imposes the same launch timeout as usual here. But you can attach after this and see what is going on.
+It may not be possible to debug the `init` method from your module with this,
+Companion still imposes the same launch timeout as usual here. But you can
+attach after this and see what is going on.
:::
:::tip[VS Code]
-VS Code users can store a setup which allows you to use F5 to initiate debugging as follows:
+VS Code users can store a setup which allows you to use F5 to initiate debugging
+as follows:
1. Put a port number in `DEBUG-INSPECT` -- for this example it is 12345.
-2. Put the following into the file `.vscode/launch.json` (where the value of "port" matches the value in `DEBUG-INSPECT`).
+2. Put the following into the file `.vscode/launch.json` (where the value of
+ "port" matches the value in `DEBUG-INSPECT`).
```json
{
diff --git a/for-developers/module-development/module-development-101.md b/for-developers/module-development/module-development-101.md
index 7cf209e..54779c9 100644
--- a/for-developers/module-development/module-development-101.md
+++ b/for-developers/module-development/module-development-101.md
@@ -5,40 +5,88 @@ sidebar_position: 5
description: The essential overview of Companion module development.
---
-With your [local environment setup](./home.md), it is time to start looking at modules in greater detail. By now you should be familiar with Git and GitHub workflows, but if not, start by reading our [GitHub Crash Course](../git-workflows/git-crashcourse.md).
-
-The general lifecycle of a module starts when you create a local repository as described in the [Getting Started](./home.md) page. Next you fill in the code to control your device. Finally you release it for others to use. Once you have completed one cycle, you continue by maintaining and updating your codebase. The following guide outlines the tasks you will perform to build or contribute to a module:
+With your [local environment setup](./home.md), it is time to start looking at
+modules in greater detail. By now you should be familiar with Git and GitHub
+workflows, but if not, start by reading our
+[GitHub Crash Course](../git-workflows/git-crashcourse.md).
+
+The general lifecycle of a module starts when you create a local repository as
+described in the [Getting Started](./home.md) page. Next you fill in the code to
+control your device. Finally you release it for others to use. Once you have
+completed one cycle, you continue by maintaining and updating your codebase. The
+following guide outlines the tasks you will perform to build or contribute to a
+module:
## Name the module
-If you are creating a new module, then the very first thing you'll want to do is choose a name that conforms with Companion's naming convention: _companion-module-mymanufacturer-myproduct_ (replacing _mymanufacturer-myproduct_ with appropriate names). This name will be used to name the repository itself and to fill in information in the configuration files. See the [setup instructions](./home#clone-or-copy-a-module-from-github) for more details.
+If you are creating a new module, then the very first thing you'll want to do is
+choose a name that conforms with Companion's naming convention:
+_companion-module-mymanufacturer-myproduct_ (replacing
+_mymanufacturer-myproduct_ with appropriate names). This name will be used to
+name the repository itself and to fill in information in the configuration
+files. See the [setup instructions](./home#clone-or-copy-a-module-from-github)
+for more details.
## Configure the module
-There are a few files that make up every module. Please familiarize yourself with the basic structure described in our pages on [Module Configuration](module-setup/file-structure). In particular, _package.json_,
-[_companion/manifest.json_](./module-setup/manifest.json.md) and _companion/HELP.md_ define the identity of the module. Once these are defined, you will spend most of your time crafting the module source code.
+There are a few files that make up every module. Please familiarize yourself
+with the basic structure described in our pages on
+[Module Configuration](module-setup/file-structure). In particular,
+_package.json_, [_companion/manifest.json_](./module-setup/manifest.json.md) and
+_companion/HELP.md_ define the identity of the module. Once these are defined,
+you will spend most of your time crafting the module source code.
## Program the module
-While you can handle all your module's code in one big file, we strongly recommend splitting it across several files as illustrated in our [file structure overview](./module-setup/file-structure#file-structure).
+While you can handle all your module's code in one big file, we strongly
+recommend splitting it across several files as illustrated in our
+[file structure overview](./module-setup/file-structure#file-structure).
-To understand what is needed in a module it helps to understand how the code is used. Your module is presented to Companion as a class that extends the module base class. A user can add one or more _instances_ of your module to their Companion site. When Companion starts up, it initializes each instance of the module by starting a new process and passing configuration information, as described next.
+To understand what is needed in a module it helps to understand how the code is
+used. Your module is presented to Companion as a class that extends the module
+base class. A user can add one or more _instances_ of your module to their
+Companion site. When Companion starts up, it initializes each instance of the
+module by starting a new process and passing configuration information, as
+described next.
### The module class and entrypoint (Module base class, configs)
-In the [typical module structure](./module-setup/file-structure#file-structure), the entrypoint and module class are defined in _src/main.ts_. When your module is started, first the `constructor` of your module's class will be called, followed by your [upgrade scripts](./connection-basics/upgrade-scripts.md) and then the `init` method.
-
-Your constructor should only do some minimal class setup. It does not have access to the configuration information, so it should not be used to start doing things. Instead...
-
-The `init` method is passed any previously-stored user-config information. (The structure of the user-config is defined by you and used as the type of the generic base class.) Inside the `init` method you should initiate the connection to your device (but dont await it! Instead use the `updateStatus()` method to inform Companion asynchronously of the connection status). Here you also pass the module's actions, feedbacks, variables and presets to Companion for the first time.
-
-Once the module is running the `configUpdated` (but not `init`) method will be called if the user changes the config on the Connections page. (You can programmatically change the user config by calling `saveConfig()`, defined in the base class.) You can also update the action, feedback, etc. definitions at any time.
-
-When the module gets deleted or disabled the `destroy` function is called. here you should clean-up whatever you don't need anymore. Make sure to not leave timers running, as that can cause performance problems in companion as the leaked timers start piling up!
+In the [typical module structure](./module-setup/file-structure#file-structure),
+the entrypoint and module class are defined in _src/main.ts_. When your module
+is started, first the `constructor` of your module's class will be called,
+followed by your [upgrade scripts](./connection-basics/upgrade-scripts.md) and
+then the `init` method.
+
+Your constructor should only do some minimal class setup. It does not have
+access to the configuration information, so it should not be used to start doing
+things. Instead...
+
+The `init` method is passed any previously-stored user-config information. (The
+structure of the user-config is defined by you and used as the type of the
+generic base class.) Inside the `init` method you should initiate the connection
+to your device (but dont await it! Instead use the `updateStatus()` method to
+inform Companion asynchronously of the connection status). Here you also pass
+the module's actions, feedbacks, variables and presets to Companion for the
+first time.
+
+Once the module is running the `configUpdated` (but not `init`) method will be
+called if the user changes the config on the Connections page. (You can
+programmatically change the user config by calling `saveConfig()`, defined in
+the base class.) You can also update the action, feedback, etc. definitions at
+any time.
+
+When the module gets deleted or disabled the `destroy` function is called. here
+you should clean-up whatever you don't need anymore. Make sure to not leave
+timers running, as that can cause performance problems in companion as the
+leaked timers start piling up!
### The module functions (actions, feedback, variables, presets)
-Your module provides interaction with the user by defining user-configurations, actions, feedbacks, and variables. In addition you can define "preset" buttons that predefine combinations of common actions and feedbacks for the user's convenience. These presets can be dragged onto the button grid for "instant button configuration".
+Your module provides interaction with the user by defining user-configurations,
+actions, feedbacks, and variables. In addition you can define "preset" buttons
+that predefine combinations of common actions and feedbacks for the user's
+convenience. These presets can be dragged onto the button grid for "instant
+button configuration".
- [Module Setup](module-setup/file-structure.md)
- [Module Basics Overview](./connection-basics/overview.md)
@@ -50,26 +98,41 @@ Your module provides interaction with the user by defining user-configurations,
### Log module activity (optional)
-You might want to print some info or variables to the console or the in companion log both to aid in development and to help users identify what may have gone wrong
+You might want to print some info or variables to the console or the in
+companion log both to aid in development and to help users identify what may
+have gone wrong
For printing to the module debug log use:
- `console.log('your data/message');`
-And if you want it in the log in the web interface, see [the log method](https://bitfocus.github.io/companion-module-base/classes/InstanceBase.html#log).
+And if you want it in the log in the web interface, see
+[the log method](https://bitfocus.github.io/companion-module-base/classes/InstanceBase.html#log).
See also our instructions for [debugging your module](./module-debugging.md)
## Test the module
-In any case, your module should be tested throughout at different stages of its life.
-You should check the compatibility to the Companion core, especially to different versions of the configuration fields. Some users may not have used Companion in a long time and their configuration file might look different than what you expect.
-And last but not least you should check **all** your actions with **all** the options and feedbacks and whatever with the real device (as much as possible). Most bugs we find are typos, which would have easily been detected by complete testing. Also please don't rely solely on simulations where possible, often the real device reacts slightly differently than the simulator.
+In any case, your module should be tested throughout at different stages of its
+life. You should check the compatibility to the Companion core, especially to
+different versions of the configuration fields. Some users may not have used
+Companion in a long time and their configuration file might look different than
+what you expect. And last but not least you should check **all** your actions
+with **all** the options and feedbacks and whatever with the real device (as
+much as possible). Most bugs we find are typos, which would have easily been
+detected by complete testing. Also please don't rely solely on simulations where
+possible, often the real device reacts slightly differently than the simulator.
## Share your code
-The first step in sharing your code, whether to share privately or distribute through Companion is to [package your module](./module-lifecycle/module-packaging.md).
+The first step in sharing your code, whether to share privately or distribute
+through Companion is to
+[package your module](./module-lifecycle/module-packaging.md).
-Once your packaged module has passed your quality-control and you are ready to release it publicly, you will use the [BitFocus Developer Portal](https://developer.bitfocus.io/modules/companion-connection/discover) to list it with Companion. Please follow the guide for [releasing your module](./module-lifecycle/releasing-your-module.md).
+Once your packaged module has passed your quality-control and you are ready to
+release it publicly, you will use the
+[BitFocus Developer Portal](https://developer.bitfocus.io/modules/companion-connection/discover)
+to list it with Companion. Please follow the guide for
+[releasing your module](./module-lifecycle/releasing-your-module.md).
Questions? Reach out on [SLACK](https://l.companion.free/q/zYXXxnGyd)! :)
diff --git a/for-developers/module-development/module-lifecycle/companion-module-library.md b/for-developers/module-development/module-lifecycle/companion-module-library.md
index 4a71a7b..4d82c9a 100644
--- a/for-developers/module-development/module-lifecycle/companion-module-library.md
+++ b/for-developers/module-development/module-lifecycle/companion-module-library.md
@@ -5,49 +5,82 @@ sidebar_position: 1
description: Explanation of the companion module library.
---
-Since Companion version 3.0, we have used `@companion-module/base` and `@companion-module/tools` libraries as part of the module API.
+Since Companion version 3.0, we have used `@companion-module/base` and
+`@companion-module/tools` libraries as part of the module API.
-The libraries are available on [npm](https://www.npmjs.com/) and are installed automatically when you run `yarn install`.
+The libraries are available on [npm](https://www.npmjs.com/) and are installed
+automatically when you run `yarn install`.
## What is the purpose of each library?
### @companion-module/base
-This library is added as a regular dependency of your module. It contains various helpers and utilities that we think are useful to modules, as well as the main base class that your module should extend.
+This library is added as a regular dependency of your module. It contains
+various helpers and utilities that we think are useful to modules, as well as
+the main base class that your module should extend.
-If you have any suggestions for new utilities or helpers that would benefit many modules, let us know and we shall consider including it.
+If you have any suggestions for new utilities or helpers that would benefit many
+modules, let us know and we shall consider including it.
### @companion-module/tools
-This library should be added as a devDependency of your module. It contains various bits of tooling and commands needed during the development or distribution of modules.
+This library should be added as a devDependency of your module. It contains
+various bits of tooling and commands needed during the development or
+distribution of modules.
-For example, it contains a script to bundle your module for distribution and some eslint and typescript config presets that can be used.
+For example, it contains a script to bundle your module for distribution and
+some eslint and typescript config presets that can be used.
-We expect every module to use the build script provided from this, the rest is optional extras that you can choose to use if you like.
+We expect every module to use the build script provided from this, the rest is
+optional extras that you can choose to use if you like.
## When should I update them?
### @companion-module/base
-The version of this library determines the versions of Companion your module can be run with. See the [version compatibility table](https://github.com/bitfocus/companion-module-base#readme).
+The version of this library determines the versions of Companion your module can
+be run with. See the
+[version compatibility table](https://github.com/bitfocus/companion-module-base#readme).
-For example, modules targeting Companion 3.0 should use @companion-module/base v1.4.3 (or any 1.x release back to v1.0.0). Modules targeting Companion 3.1 should use v1.5. A module written for 3.0 will run on 3.1, but a module written for 3.1 may not be compatible with 3.0.
+For example, modules targeting Companion 3.0 should use @companion-module/base
+v1.4.3 (or any 1.x release back to v1.0.0). Modules targeting Companion 3.1
+should use v1.5. A module written for 3.0 will run on 3.1, but a module written
+for 3.1 may not be compatible with 3.0.
-We recommend targeting the previous stable release of Companion. This will allow users who have not yet updated Companion to use the latest version of your module. But of course, you may wish to use newer versions if there are features that your module will benefit from.
+We recommend targeting the previous stable release of Companion. This will allow
+users who have not yet updated Companion to use the latest version of your
+module. But of course, you may wish to use newer versions if there are features
+that your module will benefit from.
### @companion-module/tools
-This library is less picky about the version, and you will benefit by running an up to date version.
+This library is less picky about the version, and you will benefit by running an
+up to date version.
## Why were they created? - A bit of history
-Prior to Companion version 3, modules would pull various bits of code from the Companion code. This was problematic as it meant that modules had to live in one of a few specific locations to be able to access the code. In release builds, they had to be built in before Companion was packaged.
-
-This was the main issue that was blocking our ability to support adding newer versions of modules into already released versions.
-
-Everything that modules need to access Companion is now located inside of `@companion-module/base`. Some things have not been made available, as they were determined to not be appropriate and alternatives will be recommended to the few module authors who utilised them.
-
-Another benefit of this separation is that it allows us to better isolate modules from being tied to specific versions of Companion. The `@companion-module/base` acts as a stable barrier between the two. It has intentionally been kept separate from the rest of the Companion code, so that changes made here get an extra level of scrutiny, as we want to guarantee backwards compatibility as much as possible. For example, in Companion version 2.x changes made to the module API occasionally required fixes to be applied to multiple modules. By having this barrier, we can avoid such problems for as long as possible, and can more easily create compatibility layers as needed.
+Prior to Companion version 3, modules would pull various bits of code from the
+Companion code. This was problematic as it meant that modules had to live in one
+of a few specific locations to be able to access the code. In release builds,
+they had to be built in before Companion was packaged.
+
+This was the main issue that was blocking our ability to support adding newer
+versions of modules into already released versions.
+
+Everything that modules need to access Companion is now located inside of
+`@companion-module/base`. Some things have not been made available, as they were
+determined to not be appropriate and alternatives will be recommended to the few
+module authors who utilised them.
+
+Another benefit of this separation is that it allows us to better isolate
+modules from being tied to specific versions of Companion. The
+`@companion-module/base` acts as a stable barrier between the two. It has
+intentionally been kept separate from the rest of the Companion code, so that
+changes made here get an extra level of scrutiny, as we want to guarantee
+backwards compatibility as much as possible. For example, in Companion version
+2.x changes made to the module API occasionally required fixes to be applied to
+multiple modules. By having this barrier, we can avoid such problems for as long
+as possible, and can more easily create compatibility layers as needed.
## Further reading
diff --git a/for-developers/module-development/module-lifecycle/index.md b/for-developers/module-development/module-lifecycle/index.md
index 51294ab..8c03bae 100644
--- a/for-developers/module-development/module-lifecycle/index.md
+++ b/for-developers/module-development/module-lifecycle/index.md
@@ -1,7 +1,9 @@
---
title: 'Module Development Lifecycle: Release and Maintenance'
-description: The task necessary to release, maintain and upgrade a module repository over time.
+description: The task necessary to release, maintain and upgrade a module repository over
+ time.
auto_toc: 2
---
-This section describes the task necessary to package, deliver, maintain and upgrade a module repository over time.
+This section describes the task necessary to package, deliver, maintain and
+upgrade a module repository over time.
diff --git a/for-developers/module-development/module-lifecycle/module-packaging.md b/for-developers/module-development/module-lifecycle/module-packaging.md
index db10cbf..97f68a3 100644
--- a/for-developers/module-development/module-lifecycle/module-packaging.md
+++ b/for-developers/module-development/module-lifecycle/module-packaging.md
@@ -7,64 +7,103 @@ description: How to package your module for delivery to others.
## Background
-Starting with Companion 3.0, modules must be packaged with some special tooling. This is done to reduce the number and total size of files in your module. Combining your module into just a few files can often reduce the size from multiple MB, to a few hundred KB, and lead to much shorter load times.
+Starting with Companion 3.0, modules must be packaged with some special tooling.
+This is done to reduce the number and total size of files in your module.
+Combining your module into just a few files can often reduce the size from
+multiple MB, to a few hundred KB, and lead to much shorter load times.
:::warning
-Sometimes the build process introduces or reveals issues that prevent the module from running, so be sure to test it before distributing. In our experience, issues often occur when working with files from disk, or introducing a new dependency that doesn't play nice.
+Sometimes the build process introduces or reveals issues that prevent the module
+from running, so be sure to test it before distributing. In our experience,
+issues often occur when working with files from disk, or introducing a new
+dependency that doesn't play nice.
:::
## Packaging for testing
-If you are using one of our [recommended module templates](../module-setup/file-structure.md) you can package your module for distribution by running
+If you are using one of our
+[recommended module templates](../module-setup/file-structure.md) you can
+package your module for distribution by running
```bash
yarn companion-module-build
```
-If successful, there will now be a `pkg/` folder at your module root folder a `-.tgz` file in the root folder. The module name and version are taken from your _package.json_ file, so for example, if the module is named 'generic-animation' and the version number in _package.json_ is 0.7.0, then the file will be named _generic-animation-0.7.0.tgz_.
+If successful, there will now be a `pkg/` folder at your module root folder a
+`-.tgz` file in the root folder. The module name and
+version are taken from your _package.json_ file, so for example, if the module
+is named 'generic-animation' and the version number in _package.json_ is 0.7.0,
+then the file will be named _generic-animation-0.7.0.tgz_.
-If you need to debug the package code rather than the dev code, create an empty file `DEBUG-PACKAGED` in your module folder. Companion will read the code from `pkg` instead of your source folders.
+If you need to debug the package code rather than the dev code, create an empty
+file `DEBUG-PACKAGED` in your module folder. Companion will read the code from
+`pkg` instead of your source folders.
-You probably don't need to do a very thorough test, as long as it starts and connects to your device and a couple of actions work it should be fine.
+You probably don't need to do a very thorough test, as long as it starts and
+connects to your device and a couple of actions work it should be fine.
:::tip
-Due to how the packaging is done, it can result in some errors producing unreadable stack traces, or for a wall of code to be shown in the log making it unreadable. While using `DEBUG-PACKAGED`, if you run `yarn companion-module-build --dev` (the `--dev` parameter is key here) it will produce a larger build of your module that will retain original line numbers and formatting, making it much easier to read any output.
+Due to how the packaging is done, it can result in some errors producing
+unreadable stack traces, or for a wall of code to be shown in the log making it
+unreadable. While using `DEBUG-PACKAGED`, if you run
+`yarn companion-module-build --dev` (the `--dev` parameter is key here) it will
+produce a larger build of your module that will retain original line numbers and
+formatting, making it much easier to read any output.
:::
-If you need help, don't hesitate to reach out on the Module Developer's [Slack channel](https://bfoc.us/ke7e9dqgaz) and we will be happy to assist you.
+If you need help, don't hesitate to reach out on the Module Developer's
+[Slack channel](https://bfoc.us/ke7e9dqgaz) and we will be happy to assist you.
## Packaging for distribution
-When you run `yarn companion-module-build` (without the --dev), it produces the _.tgz_ file described above. This file contains everything a user needs to be able to run your module. A `tgz` file is like a `zip` file, but different encoding. You, or your users, can load it from the Companion Modules page and Companion will be able to run it the same as if the module came from the store.
+When you run `yarn companion-module-build` (without the --dev), it produces the
+_.tgz_ file described above. This file contains everything a user needs to be
+able to run your module. A `tgz` file is like a `zip` file, but different
+encoding. You, or your users, can load it from the Companion Modules page and
+Companion will be able to run it the same as if the module came from the store.
## Customising the packaging
-For more complex modules, it is possible to adjust some settings in the packaging process.
+For more complex modules, it is possible to adjust some settings in the
+packaging process.
-Be careful when using these, as changing these settings are advanced features that can cause the build process to fail.
+Be careful when using these, as changing these settings are advanced features
+that can cause the build process to fail.
-To start off, create a file `build-config.cjs` in your module folder, with the contents `module.exports = {}`. Each of these customisation sections will add some data to this file.
+To start off, create a file `build-config.cjs` in your module folder, with the
+contents `module.exports = {}`. Each of these customisation sections will add
+some data to this file.
### Changing `__dirname`
-Webpack has a few options for how `__dirname` behaves in packaged code. By default it gets replaced with `/` which makes everything relative to the bundled main file. Alternatively, you can set `useOriginalStructureDirname: true` and the original paths will be preserved.
+Webpack has a few options for how `__dirname` behaves in packaged code. By
+default it gets replaced with `/` which makes everything relative to the bundled
+main file. Alternatively, you can set `useOriginalStructureDirname: true` and
+the original paths will be preserved.
### Including extra data files
:::tip
-Since [API 1.12](../api-changes/v1.12.md), your module by default has read-only access to just your module folder, and not the whole filesystem.
-You can [opt into more permissions](../connection-advanced/permissions.md) if you need it, but this will require permission from the user in the future.
+Since [API 1.12](../api-changes/v1.12.md), your module by default has read-only
+access to just your module folder, and not the whole filesystem. You can
+[opt into more permissions](../connection-advanced/permissions.md) if you need
+it, but this will require permission from the user in the future.
:::
-Sometimes it can be useful to store some extra data as text files, or other formats on disk. Once your module is packaged, it wont have access to any files, from the repository unless they are JavaScript which gets included in the bundle or the files are explicitly copied. You will need to do this to allow any `fs.readFile()` or similar calls to work.
+Sometimes it can be useful to store some extra data as text files, or other
+formats on disk. Once your module is packaged, it wont have access to any files,
+from the repository unless they are JavaScript which gets included in the bundle
+or the files are explicitly copied. You will need to do this to allow any
+`fs.readFile()` or similar calls to work.
-You can include these files by adding something like the following to your `build-config.cjs`:
+You can include these files by adding something like the following to your
+`build-config.cjs`:
```js
module.exports = {
@@ -72,29 +111,46 @@ module.exports = {
}
```
-You can use any glob pattern to define files to be copied.
-All files will be copied to the root folder of the package, which is the same folder where the packaged main script is in. Make sure that there are no name conflicts when copying files from different folders.
-Make sure you don't copy files you don't need, as these files will be included in the installation for all users of Companion.
+You can use any glob pattern to define files to be copied. All files will be
+copied to the root folder of the package, which is the same folder where the
+packaged main script is in. Make sure that there are no name conflicts when
+copying files from different folders. Make sure you don't copy files you don't
+need, as these files will be included in the installation for all users of
+Companion.
### Using native dependencies
:::tip
-Since [API 1.12](../api-changes/v1.12.md), you have to mark in your manifest.json that you need to do this. In the future we will use this as information for the user.
-Read more about [permissions](../connection-advanced/permissions.md).
+Since [API 1.12](../api-changes/v1.12.md), you have to mark in your
+manifest.json that you need to do this. In the future we will use this as
+information for the user. Read more about
+[permissions](../connection-advanced/permissions.md).
:::
-Native dependencies are not possible to bundle in the same way as js ones. So to support these requires a bit of extra work on your part.
+Native dependencies are not possible to bundle in the same way as js ones. So to
+support these requires a bit of extra work on your part.
-It is not yet possible to use all native dependencies. We only support ones that publish prebuilt binaries as part of their npm package.
-This means that some libraries are not possible to use. Reach out if you are affected by this, we would appreciate some input, and can work with you to find or fix a library to be compatible
+It is not yet possible to use all native dependencies. We only support ones that
+publish prebuilt binaries as part of their npm package. This means that some
+libraries are not possible to use. Reach out if you are affected by this, we
+would appreciate some input, and can work with you to find or fix a library to
+be compatible
-To support these modules, you should make one of two changes to your build-config.cjs, depending on how the library works.
+To support these modules, you should make one of two changes to your
+build-config.cjs, depending on how the library works.
-If the library is using [`prebuild-install`](https://www.npmjs.com/package/prebuild-install), then it will not work. With `prebuild-install` it is only possible to have the binaries for one platform installed, which isn't compatible with our bundling process. If you need one of these libraries, let us know and we can try to get this working with you.
+If the library is using
+[`prebuild-install`](https://www.npmjs.com/package/prebuild-install), then it
+will not work. With `prebuild-install` it is only possible to have the binaries
+for one platform installed, which isn't compatible with our bundling process. If
+you need one of these libraries, let us know and we can try to get this working
+with you.
-If the library is using [`pkg-prebuilds`](https://www.npmjs.com/package/pkg-prebuilds) for loading the prebuilt binaries, then you can use the following syntax.
+If the library is using
+[`pkg-prebuilds`](https://www.npmjs.com/package/pkg-prebuilds) for loading the
+prebuilt binaries, then you can use the following syntax.
```js
module.exports = {
@@ -103,9 +159,12 @@ module.exports = {
```
If the library is using `node-gyp-build`, then there are a couple of options.
-The preferred method is to set `useOriginalStructureDirname: true` in `build-config.cjs`. This changes the value of `__dirname` in your built module, and allows `node-gyp-build` to find its prebuilds.
+The preferred method is to set `useOriginalStructureDirname: true` in
+`build-config.cjs`. This changes the value of `__dirname` in your built module,
+and allows `node-gyp-build` to find its prebuilds.
-If you are not able to use `useOriginalStructureDirname: true`, then you can instead mark the dependency as an external:
+If you are not able to use `useOriginalStructureDirname: true`, then you can
+instead mark the dependency as an external:
```js
module.exports = {
@@ -117,15 +176,22 @@ module.exports = {
}
```
-This isn't the most efficient solution, as it still results in a lot of files on disk. We are looking into whether we can package them more efficiently, but are currently blocked on how most of these dependencies locate the native portion of themselves to load.
+This isn't the most efficient solution, as it still results in a lot of files on
+disk. We are looking into whether we can package them more efficiently, but are
+currently blocked on how most of these dependencies locate the native portion of
+themselves to load.
-If the library is using something else, let us know which of these approaches works, and we can update this page to include it.
+If the library is using something else, let us know which of these approaches
+works, and we can update this page to include it.
### Using extra plugins
-Sometimes the standard webpack functionality is not enough to produce working modules for the node runtime, but there is a [webpack plugin](https://webpack.js.org/plugins/) which tackles your problem.
+Sometimes the standard webpack functionality is not enough to produce working
+modules for the node runtime, but there is a
+[webpack plugin](https://webpack.js.org/plugins/) which tackles your problem.
-You can include additional plugins by adding something like the following to your `build-config.cjs`:
+You can include additional plugins by adding something like the following to
+your `build-config.cjs`:
```js
module.exports = {
@@ -135,7 +201,8 @@ module.exports = {
### Disabling minification
-Some libraries can break when minified, if they are relying on names of objects in a way that webpack doesn't expect. This can lead to cryptic runtime errors.
+Some libraries can break when minified, if they are relying on names of objects
+in a way that webpack doesn't expect. This can lead to cryptic runtime errors.
You can disable minification (module-tools >=v1.4) with:
@@ -145,17 +212,24 @@ module.exports = {
}
```
-Alternatively, if you are having issues with error reports from users that have unreadable stack traces due to this minification, it can be disabled. We would prefer it to remain on for all modules to avoid bloating the install size (it can triple the size of a module), we do not mind modules enabling it if they have a reason to.
+Alternatively, if you are having issues with error reports from users that have
+unreadable stack traces due to this minification, it can be disabled. We would
+prefer it to remain on for all modules to avoid bloating the install size (it
+can triple the size of a module), we do not mind modules enabling it if they
+have a reason to.
### Using worker threads
-Worker threads need their own entrypoints, and so need their own built file to execute.
+Worker threads need their own entrypoints, and so need their own built file to
+execute.
-We need to investigate how to handle this correctly. Reach out if you have ideas.
+We need to investigate how to handle this correctly. Reach out if you have
+ideas.
## Common issues
-This process can often introduce some unexpected issues, here are some of the more common ones and solutions:
+This process can often introduce some unexpected issues, here are some of the
+more common ones and solutions:
_TODO_
diff --git a/for-developers/module-development/module-lifecycle/releasing-your-module.md b/for-developers/module-development/module-lifecycle/releasing-your-module.md
index 074fd97..a2de0d1 100644
--- a/for-developers/module-development/module-lifecycle/releasing-your-module.md
+++ b/for-developers/module-development/module-lifecycle/releasing-your-module.md
@@ -2,46 +2,65 @@
title: 'Releasing a Companion Module'
sidebar_label: 'Release a module'
sidebar_position: 3
-description: How to release your module for delivery to others using Companion's "web store".
+description: How to release your module for delivery to others using Companion's "web
+ store".
---
-Since Companion 4.0, modules get installed on demand from our API. This allows new updates to your module to get into users hands much quicker than before, as long as your module uses a compatible version of the module API.
+Since Companion 4.0, modules get installed on demand from our API. This allows
+new updates to your module to get into users hands much quicker than before, as
+long as your module uses a compatible version of the module API.
## First Release
-If this is the first release of your module, you will need to request the repository on [Slack](https://bfoc.us/ke7e9dqgaz).
+If this is the first release of your module, you will need to request the
+repository on [Slack](https://bfoc.us/ke7e9dqgaz).
-Please post a message in the `#module-development` channel the includes your GitHub username and the desired name of your module in the `manufacturer-product` format.
+Please post a message in the `#module-development` channel the includes your
+GitHub username and the desired name of your module in the
+`manufacturer-product` format.
-Once you have a repository, and have pushed your code, you can [release a new version](#releasing-a-new-version)
+Once you have a repository, and have pushed your code, you can
+[release a new version](#releasing-a-new-version)
## Releasing a New Version
-When a new version of your module has been tested and is ready for distribution, use the following guide to submit it for review:
+When a new version of your module has been tested and is ready for distribution,
+use the following guide to submit it for review:
1. **Update `package.json` version**
- Use the `major.minor.patch` format (e.g., `1.2.3`).
- - Refer to the [Versioning of Modules guide](../../git-workflows/versioning.md#version-of-modules) for details.
+ - Refer to the
+ [Versioning of Modules guide](../../git-workflows/versioning.md#version-of-modules)
+ for details.
2. **(Optional) Update `companion/manifest.json` version**
- - This is not required; the build process will override this value with the version from the `package.json`.
+ - This is not required; the build process will override this value with the
+ version from the `package.json`.
3. **Create a Git tag**
- Prefix the version number with `v` (e.g., `v1.2.3`).
- You can create the tag by either:
- - [Creating a release on GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release), or
- - [Creating a local tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) and pushing it to the repository.
+ - [Creating a release on GitHub](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release),
+ or
+ - [Creating a local tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging)
+ and pushing it to the repository.
-4. **Submit the new version in the [Bitfocus Developer Portal](https://developer.bitfocus.io/)** (login with GitHub).
+4. **Submit the new version in the
+ [Bitfocus Developer Portal](https://developer.bitfocus.io/)** (login with
+ GitHub).
- In the sidebar, go to **My Connections** and select the module.
- Click **Submit Version** (bottom of page).
- Choose the Git Tag to submit.
- (Optional) Check **Is Prerelease** if this is a beta release.
- - Click **Submit** to send for review. The version status should show "Pending" after this.
+ - Click **Submit** to send for review. The version status should show
+ "Pending" after this.
**Notes about the review process:**
- Only versions submitted to the developer portal will be reviewed.
-- Reviews are done by volunteers, so review time depends on member availability and the complexity of code changes to be reviewed.
-- If adjustments are needed, you'll receive feedback through the developer portal.
-- Once approved, the new version of the module becomes immediately available to download for users on Companion v4.0.0+.
+- Reviews are done by volunteers, so review time depends on member availability
+ and the complexity of code changes to be reviewed.
+- If adjustments are needed, you'll receive feedback through the developer
+ portal.
+- Once approved, the new version of the module becomes immediately available to
+ download for users on Companion v4.0.0+.
diff --git a/for-developers/module-development/module-lifecycle/renaming-your-module.md b/for-developers/module-development/module-lifecycle/renaming-your-module.md
index 5d1a78e..ac1d16c 100644
--- a/for-developers/module-development/module-lifecycle/renaming-your-module.md
+++ b/for-developers/module-development/module-lifecycle/renaming-your-module.md
@@ -5,22 +5,32 @@ sidebar_position: 4
description: How to rename your module after having released it.
---
-Occasionally you will need to rename a module, perhaps for example, to make the name more inclusive as you add more devices, or the manufacturer releases a new device.
+Occasionally you will need to rename a module, perhaps for example, to make the
+name more inclusive as you add more devices, or the manufacturer releases a new
+device.
-1. Ask in the module-development slack for approval on the new name
- This is so that we can be sure the new name conforms to our standard structure of `companion-module-manufacturer-product` (or `companion-module-manufacturer-protocol`).
+1. Ask in the module-development slack for approval on the new name This is so
+ that we can be sure the new name conforms to our standard structure of
+ `companion-module-manufacturer-product` (or
+ `companion-module-manufacturer-protocol`).
2. Once approved, the team will be able to rename the GitHub repository for you.
-3. Some additional changes need to be made. This might be done for you, or might be left for you to do:
+3. Some additional changes need to be made. This might be done for you, or might
+ be left for you to do:
- Update the `name` and any urls in the `package.json`
- Update the `name` and related fields in `companion/manifest.json`
- - Add the old name to the `legacyIds` array in `companion/manifest.json`. This lets Companion know of the rename, so that existing users will be migrated across.
+ - Add the old name to the `legacyIds` array in `companion/manifest.json`.
+ This lets Companion know of the rename, so that existing users will be
+ migrated across.
-4. Once everything is updated, you will want to publish a new version and submit that for inclusion
+4. Once everything is updated, you will want to publish a new version and submit
+ that for inclusion
:::tip
-When renaming a module like this, you must not decrease the number of upgrade scripts. The count will continue from the old module name, so removing any upgrade scripts will cause new ones to be missed for many users.
+When renaming a module like this, you must not decrease the number of upgrade
+scripts. The count will continue from the old module name, so removing any
+upgrade scripts will cause new ones to be missed for many users.
:::
diff --git a/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md b/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
index fcee57b..7fd4b1b 100644
--- a/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
+++ b/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
@@ -2,27 +2,43 @@
title: 'Using a custom @companion-module/base library'
sidebar_label: 'Custom @companion-module/base'
sidebar_position: 8
-description: How to test and use your module with a non-release version of the companion modules.
+description: How to test and use your module with a non-release version of the companion
+ modules.
---
-Sometimes it may be useful to test or use an unreleased version of `@companion-module/base`. This commonly happens when new features are added to this library, before they are deemed ready for general use.
+Sometimes it may be useful to test or use an unreleased version of
+`@companion-module/base`. This commonly happens when new features are added to
+this library, before they are deemed ready for general use.
:::warning
-Modules using unreleased versions of `@companion-module/base` should not be distributed. There will often be subtle differences between the unreleased version and the final version that will cause bugs. Make sure to only use released versions in any distributed/published module versions.
+Modules using unreleased versions of `@companion-module/base` should not be
+distributed. There will often be subtle differences between the unreleased
+version and the final version that will cause bugs. Make sure to only use
+released versions in any distributed/published module versions.
:::
## Using an unreleased version
-This can sometimes be done against a normal build of companion, unless the changes to this library require changes in companion too.
+This can sometimes be done against a normal build of companion, unless the
+changes to this library require changes in companion too.
-1. clone this repository somewhere on your computer if you havent already `git clone https://github.com/bitfocus/companion-module-base.git`
+1. clone this repository somewhere on your computer if you havent already
+ `git clone https://github.com/bitfocus/companion-module-base.git`
2. cd into the cloned folder `cd companion-module-base`
-3. If the version you want is a branch, checkout the branch, or main if you want the primary branch. eg `git checkout main`
+3. If the version you want is a branch, checkout the branch, or main if you want
+ the primary branch. eg `git checkout main`
4. Install dependencies `yarn install`
-5. Build the library `yarn build`. If this step fails with an error, you will need to resolve this
-6. Make the library available through `yarn link` (if you have done this before, it can be skipped)
-7. Inside your module folder, link in the local version `yarn link @companion-module/base`. This may need to be repeated anytime you run add/install/remove any dependencies from your module.
-
-Note: be aware that the custom version will stay with your module as you switch branches. Once you are done, the best way to ensure you are using the version defined in your `package.json` is to delete your `node_modules` folder and run `yarn install` to regenerate it
+5. Build the library `yarn build`. If this step fails with an error, you will
+ need to resolve this
+6. Make the library available through `yarn link` (if you have done this before,
+ it can be skipped)
+7. Inside your module folder, link in the local version
+ `yarn link @companion-module/base`. This may need to be repeated anytime you
+ run add/install/remove any dependencies from your module.
+
+Note: be aware that the custom version will stay with your module as you switch
+branches. Once you are done, the best way to ensure you are using the version
+defined in your `package.json` is to delete your `node_modules` folder and run
+`yarn install` to regenerate it
diff --git a/for-developers/module-development/module-lifecycle/updating-nodejs.md b/for-developers/module-development/module-lifecycle/updating-nodejs.md
index 4782c62..8b1f308 100644
--- a/for-developers/module-development/module-lifecycle/updating-nodejs.md
+++ b/for-developers/module-development/module-lifecycle/updating-nodejs.md
@@ -5,28 +5,49 @@ sidebar_position: 5
description: How to update your module to use a newer version of Node.JS.
---
-Nodejs often makes new releases. In the major version jumps, these can include some breaking changes which could impact your module, so we don't want to do that without you being aware of it.
+Nodejs often makes new releases. In the major version jumps, these can include
+some breaking changes which could impact your module, so we don't want to do
+that without you being aware of it.
-Since Companion version 3.0, we've required modules to be compatible with Node.JS v18. Starting with @companion-module/base v1.11, Node.JS v22 has been supported.
+Since Companion version 3.0, we've required modules to be compatible with
+Node.JS v18. Starting with @companion-module/base v1.11, Node.JS v22 has been
+supported.
-When developing your module, you need to have a similar version of nodejs installed, for when you run `yarn`. Companion v4 supports both v18 and v22 for modules, but may provide a different minor version than you have used.
+When developing your module, you need to have a similar version of nodejs
+installed, for when you run `yarn`. Companion v4 supports both v18 and v22 for
+modules, but may provide a different minor version than you have used.
:::note
-Whenever Companion runs your module, it will do so with the version of nodejs that we distribute, not the one you have installed yourself.
+Whenever Companion runs your module, it will do so with the version of nodejs
+that we distribute, not the one you have installed yourself.
:::
-If you are using a node version manager, you can install an updated nodejs to your system, by doing something like `fnm install 22` and `fnm use 22`. See [our instructions here](../../setting-up-developer-environment.md).
+If you are using a node version manager, you can install an updated nodejs to
+your system, by doing something like `fnm install 22` and `fnm use 22`. See
+[our instructions here](../../setting-up-developer-environment.md).
### Changing your module's version of nodejs
-Companion knows what version of nodejs your module is compatible with by looking at the `companion/manifest.json` in your module. Inside the `runtime` object, is a property `type` which should be set to something like `node18` or `node22`. Currently these are the only valid values, others will be allowed in the future. If this is an unknown value, your module will fail to run when adding an instance inside Companion.
+Companion knows what version of nodejs your module is compatible with by looking
+at the `companion/manifest.json` in your module. Inside the `runtime` object, is
+a property `type` which should be set to something like `node18` or `node22`.
+Currently these are the only valid values, others will be allowed in the future.
+If this is an unknown value, your module will fail to run when adding an
+instance inside Companion.
-Make sure that your version of the `@companion-module/base` dependency is appropriate for the version of Companion too. A table of compatibility is listed in [the readme](https://github.com/bitfocus/companion-module-base#supported-versions-of-this-library)
+Make sure that your version of the `@companion-module/base` dependency is
+appropriate for the version of Companion too. A table of compatibility is listed
+in
+[the readme](https://github.com/bitfocus/companion-module-base#supported-versions-of-this-library)
-If you are using TypeScript, you should update your preset to have sensible `target` and `lib` values. The config presets in `@companion-module/tools`, have versions for each supported version of nodejs to make this easier for you.
+If you are using TypeScript, you should update your preset to have sensible
+`target` and `lib` values. The config presets in `@companion-module/tools`, have
+versions for each supported version of nodejs to make this easier for you.
-If your module has an `engines` field in the package.json, make sure that has a sensible value.
+If your module has an `engines` field in the package.json, make sure that has a
+sensible value.
-Once you have done this, give it a test in Companion and ensure everything is working as expected.
+Once you have done this, give it a test in Companion and ensure everything is
+working as expected.
diff --git a/for-developers/module-development/module-lifecycle/upgrading-a-module-built-for-companion-2.x.md b/for-developers/module-development/module-lifecycle/upgrading-a-module-built-for-companion-2.x.md
index 8f356d6..6c41c53 100644
--- a/for-developers/module-development/module-lifecycle/upgrading-a-module-built-for-companion-2.x.md
+++ b/for-developers/module-development/module-lifecycle/upgrading-a-module-built-for-companion-2.x.md
@@ -7,45 +7,82 @@ description: How to update a module that was built for Companion 2 or earlier.
:::danger
-This guide was written over 3 years ago for an earlier version of the module api.
-A majority of it will translate, but it will not be perfect match. You may want to follow this to update to the API 1.x format, then follow the newer upgrade docs for updating to the latest structure.
+This guide was written over 3 years ago for an earlier version of the module
+api. A majority of it will translate, but it will not be perfect match. You may
+want to follow this to update to the API 1.x format, then follow the newer
+upgrade docs for updating to the latest structure.
:::
## Background
-In Companion 3.0, we rewrote the module-api from scratch. We chose to do this because the old api had grown very organically over 5 years, and was starting to show various issues. The main issues was modules were running in the main companion thread, and method signatures were assuming various calls to be synchronous, and modules being able to access various internals of companion (and some making concerningly large use of that ability).
-Rather than trying to quickly fix up the api, it was decided to rethink it entirely.
-
-The general shape of the api should be familiar, but many methods names have been changed, and the whole api is written to rely on promises a lot more when before either callbacks were abused or methods would be synchronous.
-
-Technology has also evolved since many of the modules were written, with many of them using js syntax that was superseded in 2015! As part of this overhaul, we have imposed some minimum requirements for tooling and code style. This shouldnt be an issue, but if you run into any issues let us know on slack and we will help you out.
-
-Note: This guide is written assuming your module is an ES6 class (`class YourModule extends InstanceSkel {`). If it is not, then it would be best to convert it to that format first, to simplify this process. That can be done before starting this conversion for Companion 3.0, as it is supported in all older versions of companion
+In Companion 3.0, we rewrote the module-api from scratch. We chose to do this
+because the old api had grown very organically over 5 years, and was starting to
+show various issues. The main issues was modules were running in the main
+companion thread, and method signatures were assuming various calls to be
+synchronous, and modules being able to access various internals of companion
+(and some making concerningly large use of that ability). Rather than trying to
+quickly fix up the api, it was decided to rethink it entirely.
+
+The general shape of the api should be familiar, but many methods names have
+been changed, and the whole api is written to rely on promises a lot more when
+before either callbacks were abused or methods would be synchronous.
+
+Technology has also evolved since many of the modules were written, with many of
+them using js syntax that was superseded in 2015! As part of this overhaul, we
+have imposed some minimum requirements for tooling and code style. This shouldnt
+be an issue, but if you run into any issues let us know on slack and we will
+help you out.
+
+Note: This guide is written assuming your module is an ES6 class
+(`class YourModule extends InstanceSkel {`). If it is not, then it would be best
+to convert it to that format first, to simplify this process. That can be done
+before starting this conversion for Companion 3.0, as it is supported in all
+older versions of companion
## First steps
-You no longer need a developer version of companion to develop your module! It can now be done with the version you usually run, or you can keep to the old way if you prefer, but you shall have to refer to the main application development guides for getting that setup and running again.
+You no longer need a developer version of companion to develop your module! It
+can now be done with the version you usually run, or you can keep to the old way
+if you prefer, but you shall have to refer to the main application development
+guides for getting that setup and running again.
-Once you have the companion launcher open, click the cog in the top right. This will reveal a 'Developer modules path' field. Use this to select a `companion-module-dev` folder you created containing your modules code. See the page on [Setting up the Development Folder](../local-modules.md)
+Once you have the companion launcher open, click the cog in the top right. This
+will reveal a 'Developer modules path' field. Use this to select a
+`companion-module-dev` folder you created containing your modules code. See the
+page on [Setting up the Development Folder](../local-modules.md)
-Companion will load in any modules it finds from that folder when starting, and will restart itself whenever a file inside that folder is changed.
+Companion will load in any modules it finds from that folder when starting, and
+will restart itself whenever a file inside that folder is changed.
-You can now clone or move or existing clone into the folder you specified for development modules. Once you have done this, launch companion and it will report your module as crashing in its status, as your code needs updating.
+You can now clone or move or existing clone into the folder you specified for
+development modules. Once you have done this, launch companion and it will
+report your module as crashing in its status, as your code needs updating.
-While developing, you can view a log for an instance in the ui. This will show all messages written with `this.log()`, `this.updateStatus()` and anything written to the console. Some of this is omitted from other logs, this is the best place to see output from your module while it is running.
+While developing, you can view a log for an instance in the ui. This will show
+all messages written with `this.log()`, `this.updateStatus()` and anything
+written to the console. Some of this is omitted from other logs, this is the
+best place to see output from your module while it is running.

### 1) Add new dependencies
-To help with this new flow, any files you previously imported from companion itself (eg '../../../instance_skel') have been rewritten and are now located in a dedicated npm package. And there is a second package which provides some tooling to help with packaging your module for distribution.
+To help with this new flow, any files you previously imported from companion
+itself (eg '../../../instance_skel') have been rewritten and are now located in
+a dedicated npm package. And there is a second package which provides some
+tooling to help with packaging your module for distribution.
-You can add these to your module by running `yarn add @companion-module/base -T` and `yarn add --dev @companion-module/tools`
+You can add these to your module by running `yarn add @companion-module/base -T`
+and `yarn add --dev @companion-module/tools`
-Note: We recommend `@companion-module/base` to be installed as `~1.4` rather than `^1.4.1` as the version of this will dictate the versions of companion your module is compatible with. Read the documentation on module versioning if you want more details.
+Note: We recommend `@companion-module/base` to be installed as `~1.4` rather
+than `^1.4.1` as the version of this will dictate the versions of companion your
+module is compatible with. Read the documentation on module versioning if you
+want more details.
-Add a new file (if not exist already) : `.yarnrc.yml` and put the following code in:
+Add a new file (if not exist already) : `.yarnrc.yml` and put the following code
+in:
```yaml
nodeLinker: node-modules
@@ -60,17 +97,28 @@ You should also add the following to your `.gitignore` file:
### 2) Create the companion manifest
-Previously, Companion would read some special properties from your package.json file to know about your module. We have decided that we should instead be using our own file, so that we can avoid properties we do not need, and reduce ambiguation in the contents. This will also allow us to handle modules which are not node/npm based.
+Previously, Companion would read some special properties from your package.json
+file to know about your module. We have decided that we should instead be using
+our own file, so that we can avoid properties we do not need, and reduce
+ambiguation in the contents. This will also allow us to handle modules which are
+not node/npm based.
-To start, run the command `yarn companion-generate-manifest`. This will generate the `companion` folder based on your package.json.
+To start, run the command `yarn companion-generate-manifest`. This will generate
+the `companion` folder based on your package.json.
-As part of the process, you should notice that the `HELP.md` file has moved into the folder too. The `HELP.md` is also expected to be inside of this folder, as well as any images it uses.
+As part of the process, you should notice that the `HELP.md` file has moved into
+the folder too. The `HELP.md` is also expected to be inside of this folder, as
+well as any images it uses.
-Please give the manifest a read, it should be fairly self explanatory. You should verify that the `runtime.entrypoint` property is a relative path to your main JavaScript file. It should have been generated correctly, but be aware that you will need to change this if you move/rename the file it references.
+Please give the manifest a read, it should be fairly self explanatory. You
+should verify that the `runtime.entrypoint` property is a relative path to your
+main JavaScript file. It should have been generated correctly, but be aware that
+you will need to change this if you move/rename the file it references.
### 3) package.json cleanup
-Now that you have the new manifest, you can cleanup the old properties from your package.json.
+Now that you have the new manifest, you can cleanup the old properties from your
+package.json.
The following properties can be removed:
@@ -86,130 +134,245 @@ The following properties can be removed:
- author
- contributors
-Note: some of these are standard npm properties, but they are no longer necessary and are defined in the manifest.json
+Note: some of these are standard npm properties, but they are no longer
+necessary and are defined in the manifest.json
-If you have a `postinstall` script defined to build your module, that should now be removed.
+If you have a `postinstall` script defined to build your module, that should now
+be removed.
-If you are using typescript, you can move any `@types/*` packages from dependencies to devDependencies, but this is not required. The build script should be changed from `npx rimraf dist && npx typescript@~4.5 -p tsconfig.build.json` to `rimraf dist && yarn build:main`.
+If you are using typescript, you can move any `@types/*` packages from
+dependencies to devDependencies, but this is not required. The build script
+should be changed from
+`npx rimraf dist && npx typescript@~4.5 -p tsconfig.build.json` to
+`rimraf dist && yarn build:main`.
-As this is quite a large change, we should update the version number too. To make the size of the change here clear, we should increment the first number in the version. For example, `1.5.11` should become `2.0.0` or `3.0.1` should become `4.0.0`. This classes it as a breaking change. Make sure to change the number in package.json, as that is the master location for that. Refer to the [Versioning of Modules guide](../../git-workflows/versioning.md#version-of-modules) for details.
+As this is quite a large change, we should update the version number too. To
+make the size of the change here clear, we should increment the first number in
+the version. For example, `1.5.11` should become `2.0.0` or `3.0.1` should
+become `4.0.0`. This classes it as a breaking change. Make sure to change the
+number in package.json, as that is the master location for that. Refer to the
+[Versioning of Modules guide](../../git-workflows/versioning.md#version-of-modules)
+for details.
### 4) Prepare to update your code
-You are now ready to begin updating your code. Many properties and methods have been renamed, so this can take some time in larger modules. But the hope is that it provides a much more consistent and easier to understand api than before.
+You are now ready to begin updating your code. Many properties and methods have
+been renamed, so this can take some time in larger modules. But the hope is that
+it provides a much more consistent and easier to understand api than before.
-Because of the amount of changes, we recommend following our steps for what to do, then to test and debug it at the very end. If you attempt to run it part way through it will most likely produce weird errors or constantly crash.
+Because of the amount of changes, we recommend following our steps for what to
+do, then to test and debug it at the very end. If you attempt to run it part way
+through it will most likely produce weird errors or constantly crash.
-Before we begin, it is recommended that you ensure you have some understanding of async & Promises in nodejs. Previously the api was very synchronous, due to everything sharing a single thread, but some methods are now asynchronous as each instance of your module is run in its own thread. It is important to understand how to use promises, as you will need that to get any values from companion, and any promises left 'floating' will crash your module.
+Before we begin, it is recommended that you ensure you have some understanding
+of async & Promises in nodejs. Previously the api was very synchronous, due to
+everything sharing a single thread, but some methods are now asynchronous as
+each instance of your module is run in its own thread. It is important to
+understand how to use promises, as you will need that to get any values from
+companion, and any promises left 'floating' will crash your module.
TODO - write more about async or find some good tutorials/docs/examples
-If you are ever unsure on how something should look, we recommend looking at the following modules. This is a curated list of up-to-date and well maintained modules. If you are still unsure, then reach out in #module-development in slack.
+If you are ever unsure on how something should look, we recommend looking at the
+following modules. This is a curated list of up-to-date and well maintained
+modules. If you are still unsure, then reach out in #module-development in
+slack.
- [generic-osc](https://github.com/bitfocus/companion-module-generic-osc)
- [homeassistant-server](https://github.com/bitfocus/companion-module-homeassistant-server)
-Advanced users: You are now able to make your module be ESM if you wish. It is completely optional and should require no special configuration for companion.
+Advanced users: You are now able to make your module be ESM if you wish. It is
+completely optional and should require no special configuration for companion.
-Finally, look through your code and make sure that any dependencies you use are defined in your `package.json`. Many modules have been accidentally using the dependencies that companion defined, but in this new structure that is not possible. You may need to spend some time updating your code to work with the latest version of a library, but this is a good idea to do every now and then anyway.
+Finally, look through your code and make sure that any dependencies you use are
+defined in your `package.json`. Many modules have been accidentally using the
+dependencies that companion defined, but in this new structure that is not
+possible. You may need to spend some time updating your code to work with the
+latest version of a library, but this is a good idea to do every now and then
+anyway.
### 5) Update your actions
-If you are using typescript, `CompanionAction` and `CompanionActions` have been renamed to `CompanionActionDefinition` and `CompanionActionDefinitions` and should be imported from `'@companion-module/base'`.
+If you are using typescript, `CompanionAction` and `CompanionActions` have been
+renamed to `CompanionActionDefinition` and `CompanionActionDefinitions` and
+should be imported from `'@companion-module/base'`.
For the action definitions, the following changes have been made:
- `label` has been renamed to `name`
- `options` is required, but can be an empty array (`[]`)
-- `callback` is now required. This is the only way an action can be executed (more help is below)
-
-Tip: While you are making these changes, does the value of `name` still make sense? Perhaps you could set a `description` for the action too?
-
-Some changes to `options` may be required, but we shall cover those in a later step, as the same changes will need to be done for feedbacks and config_fields.
-
-If you aren't already aware, there are some other properties you can implement if you need then.
-You can find the typescript definitions as well as descriptions of each property you can set [in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/action.ts). Do let us know if anything needs more explanation/clarification.
-
-The `callback` property is the only way for an action to be executed. In previous versions it was possible to do this by implementing the `action()` function in the main class too. We found that using this callback made modules more maintainable as everything for an action was better grouped together, especially when the other methods are implemented.
-If you need help figuring out how to convert your code from the old `action` method to these callbacks then reach out on slack.
-
-The parameters supplied to the `callback` or `action` function have been restructured too:
-
-- The second parameter has been merged into the first, with some utility methods provided in the second parameter.
-- `action` has been renamed to `actionId` to be more consistent with elsewhere. This is the `id` you gave your actionDefinition.
-- `deviceId` is no longer provided as we don't see a use case for why this is useful. Let us know if you have one and we shall consider re-adding it
-- `bank` and `page` are no longer provided. These have been replaced by `controlId`. Actions can reside in a trigger rather than on a bank, and controlId lets us express that better. `controlId` is a unique identifier that will be the same for all actions & feedbacks on the same button or inside the same trigger, but its value should not be treated as meaningful. In a later version of companion the value of the `controlId` will change.
-- The new second parameter contains an implementation of `parseVariablesInString`, this has more purpose for feedbacks, and is provided to actions for consistency
-
-Note: there are some properties on the object with names starting with an underscore that are not mentioned here. You must not use these, as these are temporary properties. They will be removed without notice in a future version.
-
-If you are using `subscribe`, `unsubscribe` or `learn`, the object parameter has changed a little, and is a subset of the properties supplied to `callback`.
-
-Finally, to pass the action definitions to companion has changed. It is now `this.setActionDefinitions(actions)` instead of `this.setActions(actions)` or `self.system.emit('instance_actions', self.id, actions)`
+- `callback` is now required. This is the only way an action can be executed
+ (more help is below)
+
+Tip: While you are making these changes, does the value of `name` still make
+sense? Perhaps you could set a `description` for the action too?
+
+Some changes to `options` may be required, but we shall cover those in a later
+step, as the same changes will need to be done for feedbacks and config_fields.
+
+If you aren't already aware, there are some other properties you can implement
+if you need then. You can find the typescript definitions as well as
+descriptions of each property you can set
+[in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/action.ts).
+Do let us know if anything needs more explanation/clarification.
+
+The `callback` property is the only way for an action to be executed. In
+previous versions it was possible to do this by implementing the `action()`
+function in the main class too. We found that using this callback made modules
+more maintainable as everything for an action was better grouped together,
+especially when the other methods are implemented. If you need help figuring out
+how to convert your code from the old `action` method to these callbacks then
+reach out on slack.
+
+The parameters supplied to the `callback` or `action` function have been
+restructured too:
+
+- The second parameter has been merged into the first, with some utility methods
+ provided in the second parameter.
+- `action` has been renamed to `actionId` to be more consistent with elsewhere.
+ This is the `id` you gave your actionDefinition.
+- `deviceId` is no longer provided as we don't see a use case for why this is
+ useful. Let us know if you have one and we shall consider re-adding it
+- `bank` and `page` are no longer provided. These have been replaced by
+ `controlId`. Actions can reside in a trigger rather than on a bank, and
+ controlId lets us express that better. `controlId` is a unique identifier that
+ will be the same for all actions & feedbacks on the same button or inside the
+ same trigger, but its value should not be treated as meaningful. In a later
+ version of companion the value of the `controlId` will change.
+- The new second parameter contains an implementation of
+ `parseVariablesInString`, this has more purpose for feedbacks, and is provided
+ to actions for consistency
+
+Note: there are some properties on the object with names starting with an
+underscore that are not mentioned here. You must not use these, as these are
+temporary properties. They will be removed without notice in a future version.
+
+If you are using `subscribe`, `unsubscribe` or `learn`, the object parameter has
+changed a little, and is a subset of the properties supplied to `callback`.
+
+Finally, to pass the action definitions to companion has changed. It is now
+`this.setActionDefinitions(actions)` instead of `this.setActions(actions)` or
+`self.system.emit('instance_actions', self.id, actions)`
### 6) Updating your feedbacks
-If you are using typescript, `CompanionFeedback` and `CompanionFeedbacks` have been renamed to `CompanionFeedbackDefinition` and `CompanionFeedbackDefinitions` and should be imported from `'@companion-module/base'`.
+If you are using typescript, `CompanionFeedback` and `CompanionFeedbacks` have
+been renamed to `CompanionFeedbackDefinition` and `CompanionFeedbackDefinitions`
+and should be imported from `'@companion-module/base'`.
For the feedback definitions, the following changes have been made:
-- `type` is now required. If you don't have it set already, then it should be set to `'advanced'`
+- `type` is now required. If you don't have it set already, then it should be
+ set to `'advanced'`
- `label` has been renamed to `name`
- `options` is required, but can be an empty array (`[]`)
-- `callback` is now required. This is the only way an action can be executed (more help is below)
-- If your feedback is of `type: 'boolean'` then `style` has been renamed to `defaultStyle`
-
-Additionally, the `rgb` and `rgbRev` methods no longer exist on your instance class. They have been renamed to `combineRgb` and `splitRgb` and should be imported from `'@companion-module/base'`.
-
-Tip: While you are making these changes, does the value of `name` still make sense? Perhaps you could set a `description` for the action too?
-
-Some changes to `options` may be required, but we shall cover those in a later step, as the same changes will need to be done for feedbacks and config_fields.
-
-If you aren't already aware, there are some other properties you can implement if you need then.
-You can find the typescript definitions as well as descriptions of each property you can set [in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/feedback.ts). Do let us know if anything needs more explanation/clarification.
-
-The `callback` property is the only way for an feedback to be checked. In previous versions it was possible to do this by implementing the `feedback()` function in the main class too. We found that using this callback made modules more maintainable as everything for a feedback was better grouped together, especially when the other methods are implemented.
-If you need help figuring out how to convert your code from the old `feedback` method to these callbacks then reach out on slack.
-
-The parameters supplied to the `callback` or `feedback` function have been restructured too:
-
-- The parameters have been merged into one, with some utility methods provided in the second parameter.
-- `type` has been renamed to `feedbackId` to be more consistent with elsewhere. This is the `id` you gave your feedbackDefinition.
-- `bank` and `page` are no longer provided. These have been replaced by `controlId`. Feedbacks can reside in a trigger rather than on a bank, and controlId lets us express that better. `controlId` is a unique identifier that will be the same for all actions & feedbacks on the same button or inside the same trigger, but its value should not be treated as meaningful. In a later version of companion the value of the `controlId` will change.
-- It is no longer possible to get the complete 'bank' object that was provided before. Do let us know if you have a use case for it, we couldn't think of one.
-- For 'advanced' feedbacks, the `width` and `height` properties are now represented by a single `image` property. This helps clarify when they will be defined. Also note that these may not be present for all feedbacks in a future version.
-- The new second parameter contains an implementation of `parseVariablesInString`. You **must** use this instead of the similar method on the class, otherwise your feedback will not be rechecked when the variables change.
-
-Note: there are some properties on the object with names starting with an underscore that are not mentioned here. You must not use these, as these are temporary properties. They will be removed without notice in a future version.
-
-If you are using `subscribe`, `unsubscribe` or `learn`, the object parameter has changed a little, and is a subset of the properties supplied to `callback`.
+- `callback` is now required. This is the only way an action can be executed
+ (more help is below)
+- If your feedback is of `type: 'boolean'` then `style` has been renamed to
+ `defaultStyle`
+
+Additionally, the `rgb` and `rgbRev` methods no longer exist on your instance
+class. They have been renamed to `combineRgb` and `splitRgb` and should be
+imported from `'@companion-module/base'`.
+
+Tip: While you are making these changes, does the value of `name` still make
+sense? Perhaps you could set a `description` for the action too?
+
+Some changes to `options` may be required, but we shall cover those in a later
+step, as the same changes will need to be done for feedbacks and config_fields.
+
+If you aren't already aware, there are some other properties you can implement
+if you need then. You can find the typescript definitions as well as
+descriptions of each property you can set
+[in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/feedback.ts).
+Do let us know if anything needs more explanation/clarification.
+
+The `callback` property is the only way for an feedback to be checked. In
+previous versions it was possible to do this by implementing the `feedback()`
+function in the main class too. We found that using this callback made modules
+more maintainable as everything for a feedback was better grouped together,
+especially when the other methods are implemented. If you need help figuring out
+how to convert your code from the old `feedback` method to these callbacks then
+reach out on slack.
+
+The parameters supplied to the `callback` or `feedback` function have been
+restructured too:
+
+- The parameters have been merged into one, with some utility methods provided
+ in the second parameter.
+- `type` has been renamed to `feedbackId` to be more consistent with elsewhere.
+ This is the `id` you gave your feedbackDefinition.
+- `bank` and `page` are no longer provided. These have been replaced by
+ `controlId`. Feedbacks can reside in a trigger rather than on a bank, and
+ controlId lets us express that better. `controlId` is a unique identifier that
+ will be the same for all actions & feedbacks on the same button or inside the
+ same trigger, but its value should not be treated as meaningful. In a later
+ version of companion the value of the `controlId` will change.
+- It is no longer possible to get the complete 'bank' object that was provided
+ before. Do let us know if you have a use case for it, we couldn't think of
+ one.
+- For 'advanced' feedbacks, the `width` and `height` properties are now
+ represented by a single `image` property. This helps clarify when they will be
+ defined. Also note that these may not be present for all feedbacks in a future
+ version.
+- The new second parameter contains an implementation of
+ `parseVariablesInString`. You **must** use this instead of the similar method
+ on the class, otherwise your feedback will not be rechecked when the variables
+ change.
+
+Note: there are some properties on the object with names starting with an
+underscore that are not mentioned here. You must not use these, as these are
+temporary properties. They will be removed without notice in a future version.
+
+If you are using `subscribe`, `unsubscribe` or `learn`, the object parameter has
+changed a little, and is a subset of the properties supplied to `callback`.
### 7) Updating your presets
-If you are using typescript, `CompanionPreset` has been renamed to `CompanionButtonPresetDefinition`. There is also a `CompanionPresetDefinitions` defining a collection of these objects.
+If you are using typescript, `CompanionPreset` has been renamed to
+`CompanionButtonPresetDefinition`. There is also a `CompanionPresetDefinitions`
+defining a collection of these objects.
-The first change to be aware of, is that the `setPresetDefinitions()` function is now expecting an object of presets, rather than array. This is for better consistency with actions and feedbacks, and also provides a unique id for each preset.
+The first change to be aware of, is that the `setPresetDefinitions()` function
+is now expecting an object of presets, rather than array. This is for better
+consistency with actions and feedbacks, and also provides a unique id for each
+preset.
For the preset definitions, the following changes have been made for both types:
- `type` is a new property that must be `button`
- `label` has been renamed to `name`
-- `options` is a new property of some behavioural properties for the button. Its contents is explained below.
-- `bank` has been renamed to `style`. Additionally some properties have been moved out of this object, listed below.
+- `options` is a new property of some behavioural properties for the button. Its
+ contents is explained below.
+- `bank` has been renamed to `style`. Additionally some properties have been
+ moved out of this object, listed below.
- `bank.style` has been removed
- `bank.relative_delay` has been moved to `options.relativeDelay`
-- `bank.latch` has been removed. This will be handled below when changing the actions
-- `feedbacks` The objects inside this have changed slightly. The `type` property has been renamed to `feedbackId`, for better consistency.
-- `actions` and `release_actions` have been combined into `steps`, the exact structure is documented below.
-
-Note: Even when there are no actions or feedbacks, you would need to put those objects in : `feedbacks: []` & `steps: []`.
-
-Note: Remember that the `rgb` and `rgbRev` methods no longer exist on your instance class. They have been renamed to `combineRgb` and `splitRgb` and should be imported from `'@companion-module/base'`.
-
-The latch button mode has been replaced with a more flexible 'stepped' system. On each button, you can have as many steps as you wish, each with their own down/up/rotate actions. When releasing the button, it will by default automatically progress to the next step, or you can disable that and use an internal action to change the current step of a button.
-While is is wordier and more complex to make a latched button, this allows for much more complex flows, such as using another button as a 'shift' key, or having one 'go' button which runs the whole pre-programmed show.
-
-The `steps` property is an array of objects. Each object should be at a minimum `{ down: [], up: [] }` (`rotate_left` and `rotate_right` are also valid here).
+- `bank.latch` has been removed. This will be handled below when changing the
+ actions
+- `feedbacks` The objects inside this have changed slightly. The `type` property
+ has been renamed to `feedbackId`, for better consistency.
+- `actions` and `release_actions` have been combined into `steps`, the exact
+ structure is documented below.
+
+Note: Even when there are no actions or feedbacks, you would need to put those
+objects in : `feedbacks: []` & `steps: []`.
+
+Note: Remember that the `rgb` and `rgbRev` methods no longer exist on your
+instance class. They have been renamed to `combineRgb` and `splitRgb` and should
+be imported from `'@companion-module/base'`.
+
+The latch button mode has been replaced with a more flexible 'stepped' system.
+On each button, you can have as many steps as you wish, each with their own
+down/up/rotate actions. When releasing the button, it will by default
+automatically progress to the next step, or you can disable that and use an
+internal action to change the current step of a button. While is is wordier and
+more complex to make a latched button, this allows for much more complex flows,
+such as using another button as a 'shift' key, or having one 'go' button which
+runs the whole pre-programmed show.
+
+The `steps` property is an array of objects. Each object should be at a minimum
+`{ down: [], up: [] }` (`rotate_left` and `rotate_right` are also valid here).
For example, a normal button will only have one step:
@@ -239,17 +402,22 @@ steps: [
]
```
-For the action objects inside of each of these steps, the `action` property renamed to `actionId`, for better consistency with elsewhere.
+For the action objects inside of each of these steps, the `action` property
+renamed to `actionId`, for better consistency with elsewhere.
### 8) Updating options and config fields
-The options/input fields available to use as options for actions and feedbacks, as well as for your config fields has changed a little.
+The options/input fields available to use as options for actions and feedbacks,
+as well as for your config fields has changed a little.
-There may be additional new properties not listed here. You can check [the docs](../connection-basics/input-field-types.md) for full details on the available input fields.
+There may be additional new properties not listed here. You can check
+[the docs](../connection-basics/input-field-types.md) for full details on the
+available input fields.
#### common changes
-The optional `isVisible` function has changed, its parameter is now the options object for the action/feedback, not the whole action/feedback object
+The optional `isVisible` function has changed, its parameter is now the options
+object for the action/feedback, not the whole action/feedback object
#### text
@@ -257,7 +425,8 @@ The `text` type has been renamed to `static-text`
#### textinput & textwithvariables
-These have been combined into one `textinput`. With a new `useVariables` property to select the mode.
+These have been combined into one `textinput`. With a new `useVariables`
+property to select the mode.
#### dropdown
@@ -279,23 +448,30 @@ These are unchanged
#### Anything else
-That should be all of them, if you have something else then it has likely been forgotten/removed.
+That should be all of them, if you have something else then it has likely been
+forgotten/removed.
Either use a supported input type or let us know what we missed.
### 9) Updating variables
-If you are using typescript, `CompanionVariable` has been renamed to `CompanionVariableDefinition` and should be imported from `'@companion-module/base'`.
+If you are using typescript, `CompanionVariable` has been renamed to
+`CompanionVariableDefinition` and should be imported from
+`'@companion-module/base'`.
For the variable definitions, the following changes have been made:
- `name` has been renamed to `variableId`
- `label` has been renamed to `name`
-We acknowledge that this change is rather confusing, but it felt necessary for consistency with elsewhere
+We acknowledge that this change is rather confusing, but it felt necessary for
+consistency with elsewhere
-To set the value of variables, the `setVariables` method has been renamed to `setVariableValues`, and the `setVariable` method has been removed.
-This is to encourage multiple values to be set in the one call which will make companion more responsive by being able to process multiple changes at a time. Please try to combine calls to `setVariableValues` where possible.
+To set the value of variables, the `setVariables` method has been renamed to
+`setVariableValues`, and the `setVariable` method has been removed. This is to
+encourage multiple values to be set in the one call which will make companion
+more responsive by being able to process multiple changes at a time. Please try
+to combine calls to `setVariableValues` where possible.
For example, before:
@@ -317,14 +493,19 @@ this.setVariableValues({
### 10) Updating upgrade-scripts
-If you are using typescript, `CompanionStaticUpgradeScript` should be imported from `'@companion-module/base'`.
+If you are using typescript, `CompanionStaticUpgradeScript` should be imported
+from `'@companion-module/base'`.
-If you are using the `CreateConvertToBooleanFeedbackUpgradeScript` helper method on the InstanceSkel, this has moved and should be imported from `'@companion-module/base'`.
+If you are using the `CreateConvertToBooleanFeedbackUpgradeScript` helper method
+on the InstanceSkel, this has moved and should be imported from
+`'@companion-module/base'`.
-The upgrade script parameters and return value have been completely reworked, as the old functions did not fit into the new flow well.
+The upgrade script parameters and return value have been completely reworked, as
+the old functions did not fit into the new flow well.
-The first parameter (`context`) to the functions remains, but currently has no methods. We expect to add some methods in the future.
-The remaining parameters have been combined into a single `props` object.
+The first parameter (`context`) to the functions remains, but currently has no
+methods. We expect to add some methods in the future. The remaining parameters
+have been combined into a single `props` object.
This object is composed as
@@ -336,11 +517,14 @@ This object is composed as
}
```
-Tip: These upgrade scripts can be called at any time. They can be called to upgrade existing configuration, or when data is imported into companion.
+Tip: These upgrade scripts can be called at any time. They can be called to
+upgrade existing configuration, or when data is imported into companion.
-At times the config property will be null, if the config does not need updating. There may be no actions or no feedbacks, depending on what needs upgrading.
+At times the config property will be null, if the config does not need updating.
+There may be no actions or no feedbacks, depending on what needs upgrading.
-Previously, the return type was simply `boolean`, to state whether anything had changed. The return type is now expected to be an object of the format:
+Previously, the return type was simply `boolean`, to state whether anything had
+changed. The return type is now expected to be an object of the format:
```js
{
@@ -350,83 +534,135 @@ Previously, the return type was simply `boolean`, to state whether anything had
}
```
-If an action or feedback is not included in the output type, then it is assumed to not have been changed and any changes you have made to the object passed in will be lost.
-If `updatedConfig` is not set, then it is assumed that the config has not changed, and any changes will be lost.
+If an action or feedback is not included in the output type, then it is assumed
+to not have been changed and any changes you have made to the object passed in
+will be lost. If `updatedConfig` is not set, then it is assumed that the config
+has not changed, and any changes will be lost.
-This allows companion to better understand what has changed in an optimal way, and also allows you more flexibility in your code as you are no longer forced to update in place.
+This allows companion to better understand what has changed in an optimal way,
+and also allows you more flexibility in your code as you are no longer forced to
+update in place.
Tip: Make sure you don't change the id fields, or it won't track the changes!
-The config object is the same as you receive in the module, and is the same as before.
+The config object is the same as you receive in the module, and is the same as
+before.
-The action and feedback objects have a similar shape to how they are provided to their callbacks. You can see more about the exact structure of the objects [in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/upgrade.ts). This is harder to document the changes, and upgrade scripts are not that widely used.
+The action and feedback objects have a similar shape to how they are provided to
+their callbacks. You can see more about the exact structure of the objects
+[in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/src/module-api/upgrade.ts).
+This is harder to document the changes, and upgrade scripts are not that widely
+used.
-Finally, these are no longer provided via the static method. They will be passed into a function call later described later on. We suggest making them an array outside of the class that can be used later on.
+Finally, these are no longer provided via the static method. They will be passed
+into a function call later described later on. We suggest making them an array
+outside of the class that can be used later on.
### 11) Updating any uses of the TCP/UDP/Telnet helpers
-If you are importing the old socket helpers, you will need to make some changes to handle some changes that have been made to them.
+If you are importing the old socket helpers, you will need to make some changes
+to handle some changes that have been made to them.
#### UDP
-This should be imported as `UDPHelper` from `@companion-module/base` instead of the old path.
+This should be imported as `UDPHelper` from `@companion-module/base` instead of
+the old path.
Most usage of the class is the same, only the differences are documented:
-- The `addMembership` method has been removed. It was previously broken and appeared unused by any module. If you have need for it, it can be reimplemented
-- The `send` method no longer accepts a callback. Instead it returns a promise that must be handled.
-- The `status_change` event emits different statuses, to match how they have changed elsewhere. It now emits `'ok' | 'unknown_error'`
+- The `addMembership` method has been removed. It was previously broken and
+ appeared unused by any module. If you have need for it, it can be
+ reimplemented
+- The `send` method no longer accepts a callback. Instead it returns a promise
+ that must be handled.
+- The `status_change` event emits different statuses, to match how they have
+ changed elsewhere. It now emits `'ok' | 'unknown_error'`
- There are some new readonly properties added: `isDestroyed`
-- Any previously visible class members have been hidden. If you rely on any, let us know and we shall look at extending the wrapper or making things public again
+- Any previously visible class members have been hidden. If you rely on any, let
+ us know and we shall look at extending the wrapper or making things public
+ again
#### TCP
-This should be imported as `TCPHelper` from `@companion-module/base` instead of the old path.
+This should be imported as `TCPHelper` from `@companion-module/base` instead of
+the old path.
Most usage of the class is the same, only the differences are documented:
-- The `send` method no longer accepts a callback. Instead it returns a promise that must be handled.
-- The `status_change` event emits different statuses, to match how they have changed elsewhere. It now emits `'ok' | 'connecting' | 'disconnected' | 'unknown_error'`
-- There are some new readonly properties added: `isConnected`, `isConnecting` and `isDestroyed`
-- The `write` and `send` methods have been combined into a single `send` method. Behaviour is the same, just the name has changed
-- Any previously visible class members have been hidden. If you rely on any, let us know and we shall look at extending the wrapper or making things public again
+- The `send` method no longer accepts a callback. Instead it returns a promise
+ that must be handled.
+- The `status_change` event emits different statuses, to match how they have
+ changed elsewhere. It now emits
+ `'ok' | 'connecting' | 'disconnected' | 'unknown_error'`
+- There are some new readonly properties added: `isConnected`, `isConnecting`
+ and `isDestroyed`
+- The `write` and `send` methods have been combined into a single `send` method.
+ Behaviour is the same, just the name has changed
+- Any previously visible class members have been hidden. If you rely on any, let
+ us know and we shall look at extending the wrapper or making things public
+ again
#### Telnet
-This should be imported as `TelnetHelper` from `@companion-module/base` instead of the old path.
+This should be imported as `TelnetHelper` from `@companion-module/base` instead
+of the old path.
Most usage of the class is the same, only the differences are documented:
-- The `send` method no longer accepts a callback. Instead it returns a promise that must be handled.
-- The `status_change` event emits different statuses, to match how they have changed elsewhere. It now emits `'ok' | 'connecting' | 'disconnected' | 'unknown_error'`
-- There are some new readonly properties added: `isConnected`, `isConnecting` and `isDestroyed`
-- The `write` and `send` methods have been combined into a single `send` method. Behaviour is the same, just the name has changed
-- Any previously visible class members have been hidden. If you rely on any, let us know and we shall look at extending the wrapper or making things public again
+- The `send` method no longer accepts a callback. Instead it returns a promise
+ that must be handled.
+- The `status_change` event emits different statuses, to match how they have
+ changed elsewhere. It now emits
+ `'ok' | 'connecting' | 'disconnected' | 'unknown_error'`
+- There are some new readonly properties added: `isConnected`, `isConnecting`
+ and `isDestroyed`
+- The `write` and `send` methods have been combined into a single `send` method.
+ Behaviour is the same, just the name has changed
+- Any previously visible class members have been hidden. If you rely on any, let
+ us know and we shall look at extending the wrapper or making things public
+ again
### 12) Updating your main class
Finally, we are ready to look at your main class.
-To start, you should change your class to extend `InstanceBase`, which can be imported from `@companion-module/base`.
-
-There are a few fundamental changes to `InstanceBase` compared to the old `InstanceSkel`.
-
-- You should be doing very little in the constructor. You do not have the config for the instance at this point, or the ability to call any companion methods here. The intention is to make sure various class properties are defined here, with the module truly starting to work in the `init()` method.
-- `this.config` is no longer provided for you by the base class. You are provided a new config object in `init()` and `updateConfig()`, it is up to you to to an `this.config = config` when receiving that, or to do something else with the config object.
-- `this.system` is no longer available. That was previously an internal api that too many modules were hooking into. This caused many of them to break at unexpected times, and is no longer possible in this new api. If we haven't exposed something you are using on system as a proper method on `InstanceBase`, then do let us know on slack or github, and we will either implement it or help you with an alternative.
-
-The constructor has changed to have a single parameter called `internal`. This is of typescript type `unknown`. You must not use this object for anything yourself, the value of this is an internal detail, and will change in unexpected ways without notice.
-You should start your constructor with the following
+To start, you should change your class to extend `InstanceBase`, which can be
+imported from `@companion-module/base`.
+
+There are a few fundamental changes to `InstanceBase` compared to the old
+`InstanceSkel`.
+
+- You should be doing very little in the constructor. You do not have the config
+ for the instance at this point, or the ability to call any companion methods
+ here. The intention is to make sure various class properties are defined here,
+ with the module truly starting to work in the `init()` method.
+- `this.config` is no longer provided for you by the base class. You are
+ provided a new config object in `init()` and `updateConfig()`, it is up to you
+ to to an `this.config = config` when receiving that, or to do something else
+ with the config object.
+- `this.system` is no longer available. That was previously an internal api that
+ too many modules were hooking into. This caused many of them to break at
+ unexpected times, and is no longer possible in this new api. If we haven't
+ exposed something you are using on system as a proper method on
+ `InstanceBase`, then do let us know on slack or github, and we will either
+ implement it or help you with an alternative.
+
+The constructor has changed to have a single parameter called `internal`. This
+is of typescript type `unknown`. You must not use this object for anything
+yourself, the value of this is an internal detail, and will change in unexpected
+ways without notice. You should start your constructor with the following
```js
constructor(internal) {
super(internal)
```
-Remember that you do not have access to the config here, you may need to move some stuff into `init()`
+Remember that you do not have access to the config here, you may need to move
+some stuff into `init()`
-Hopefully you have an understanding of async code, because we now need to start using it.
-It is expected that `init()` will return a Promise. The simplest way to do this is to mark it as async.
+Hopefully you have an understanding of async code, because we now need to start
+using it. It is expected that `init()` will return a Promise. The simplest way
+to do this is to mark it as async.
```js
async init(config) {
@@ -434,47 +670,76 @@ It is expected that `init()` will return a Promise. The simplest way to do this
`init()` also has a parameter, of your config object.
-Inside of init, you are free to do things as you wish. But make sure that any method returning a promise isn't left floating, so that errors propagate correctly.
-
-Tip: if you do a `this.checkFeedbacks()` inside of `init()`, you can remove that line
-
-The method `config_fields` should be renamed to `getConfigFields`.
-The method `updateConfig` should be renamed to `configUpdated`, it too is expected to return a Promise and should also be marked as async.
-The method `destroy` is expected to return a Promise and should also be marked as async.
-
-If you have a method called `action` or `feedback` still, make sure it has been migrated fully in the earlier steps, then remove it as it will no longer be called.
-
-Some other methods provided by companion have been changed.
-Any where the name starts with an underscore must not be used as they are internal methods that will change without notice.
-
-- The static method `CreateConvertToBooleanFeedbackUpgradeScript` has been removed and can be imported from `@companion-module/base` instead
-- The method `saveConfig` now expects a parameter of the config object to be saved
-- The method `setActions` has been renamed to `setActionDefinitions`, as explained earlier
-- The method `setPresetDefinitions` now expects an object of presets, as explained earlier
-- The method `setVariables` has been renamed to `setVariableValues`, as explained earlier
+Inside of init, you are free to do things as you wish. But make sure that any
+method returning a promise isn't left floating, so that errors propagate
+correctly.
+
+Tip: if you do a `this.checkFeedbacks()` inside of `init()`, you can remove that
+line
+
+The method `config_fields` should be renamed to `getConfigFields`. The method
+`updateConfig` should be renamed to `configUpdated`, it too is expected to
+return a Promise and should also be marked as async. The method `destroy` is
+expected to return a Promise and should also be marked as async.
+
+If you have a method called `action` or `feedback` still, make sure it has been
+migrated fully in the earlier steps, then remove it as it will no longer be
+called.
+
+Some other methods provided by companion have been changed. Any where the name
+starts with an underscore must not be used as they are internal methods that
+will change without notice.
+
+- The static method `CreateConvertToBooleanFeedbackUpgradeScript` has been
+ removed and can be imported from `@companion-module/base` instead
+- The method `saveConfig` now expects a parameter of the config object to be
+ saved
+- The method `setActions` has been renamed to `setActionDefinitions`, as
+ explained earlier
+- The method `setPresetDefinitions` now expects an object of presets, as
+ explained earlier
+- The method `setVariables` has been renamed to `setVariableValues`, as
+ explained earlier
- The method `setVariable` has been removed, as explained earlier
- The method `getVariable` has been renamed to `getVariableValue`.
-- The method `checkFeedbacks` now accepts multiple feedbacks to check. eg `this.checkFeedbacks('one', 'two', 'three')`
-- The method `parseVariables` has been renamed to `parseVariablesInString`. Note that this method returns a promise instead of accepting a callback.
+- The method `checkFeedbacks` now accepts multiple feedbacks to check. eg
+ `this.checkFeedbacks('one', 'two', 'three')`
+- The method `parseVariables` has been renamed to `parseVariablesInString`. Note
+ that this method returns a promise instead of accepting a callback.
- The method `getAllFeedbacks` has been removed, with no replacement
- The method `getAllActions` has been removed, with no replacement
- The method `oscSend` is unchanged
-- The method `status` has been renamed to `updateStatus`. Additionally, the first parameter has been changed and should be provided a string with one of the values from below. The second parameter remains as an optional string for more details. Note: calls to this also now add a log line when the status changes.
+- The method `status` has been renamed to `updateStatus`. Additionally, the
+ first parameter has been changed and should be provided a string with one of
+ the values from below. The second parameter remains as an optional string for
+ more details. Note: calls to this also now add a log line when the status
+ changes.
- The method `log` is unchanged.
- The method `debug` has been removed, use `log` instead
-- The methods `rgb` and `rgbRev` have been removed. They can be imported as `combineRgb` and `splitRgb` from `@companion-module/base` instead
+- The methods `rgb` and `rgbRev` have been removed. They can be imported as
+ `combineRgb` and `splitRgb` from `@companion-module/base` instead
- The `STATUS_*` properties have been removed, they are no longer useful
-- The `REGEX_*` properties have been removed. Instead you can import `Regex` from `@companion-module/base` and use them from there.
-- The method `defineConst` has been removed. Instead you can either define it as a constant variable outside your class `const YOUR_THING = value` (perhaps in a separate constants.js file?) or as a normal member variable `this.YOUR_THING = value`
+- The `REGEX_*` properties have been removed. Instead you can import `Regex`
+ from `@companion-module/base` and use them from there.
+- The method `defineConst` has been removed. Instead you can either define it as
+ a constant variable outside your class `const YOUR_THING = value` (perhaps in
+ a separate constants.js file?) or as a normal member variable
+ `this.YOUR_THING = value`
- Anything else? It has likely been removed or forgotten. Ask us on slack
-Possible values for status: 'ok', 'connecting', 'disconnected', 'connection_failure', 'bad_config', 'unknown_error', 'unknown_warning'
-Note: More will be added in the future, let us know if you have any ideas for common statuses.
+Possible values for status: 'ok', 'connecting', 'disconnected',
+'connection_failure', 'bad_config', 'unknown_error', 'unknown_warning' Note:
+More will be added in the future, let us know if you have any ideas for common
+statuses.
-Once you have made sure that any method calls to methods exposed on InstanceBase have been updated, there is only a little bit more.
+Once you have made sure that any method calls to methods exposed on InstanceBase
+have been updated, there is only a little bit more.
-At the bottom of your file you should find a line looking something like `export = MyInstance`.
-You should replace this line with `runEntrypoint(MyInstance, UpgradeScripts)`, making sure to pass your class as the first parameter, and your array of upgrade scripts to the second. If you have no upgrade scripts then make the second parameter be `[]`.
+At the bottom of your file you should find a line looking something like
+`export = MyInstance`. You should replace this line with
+`runEntrypoint(MyInstance, UpgradeScripts)`, making sure to pass your class as
+the first parameter, and your array of upgrade scripts to the second. If you
+have no upgrade scripts then make the second parameter be `[]`.
Congratulations. You have now converted all of your code!
@@ -482,44 +747,80 @@ It is time to take a break, as next we shall be running and testing it.
### 13) Run it and debug!
-Startup companion, and make sure you have it setup so that it will find your custom module.
+Startup companion, and make sure you have it setup so that it will find your
+custom module.
If all went well, then your module will run and connect to your device.
-If it does not, hopefully you can figure out what has broken. There are too many possibilities for us to document here, but we can try to document some common issues.
+If it does not, hopefully you can figure out what has broken. There are too many
+possibilities for us to document here, but we can try to document some common
+issues.
-Once it is running, make sure to test every action, feedback, variable and preset. It is easy to make a mistake during the upgrading process. Whatever bugs you find now means less to be found by other users.
+Once it is running, make sure to test every action, feedback, variable and
+preset. It is easy to make a mistake during the upgrading process. Whatever bugs
+you find now means less to be found by other users.
-When you are happy with it being stable enough for others to test, let us know and we shall include it in the beta builds.
+When you are happy with it being stable enough for others to test, let us know
+and we shall include it in the beta builds.
### 14) Package it and test
-For modules in this new format, we require them to be packaged with some special tooling. This is done to both reduce the number of files that your module spans on disk, and also the size. Loading code spread across hundreds of files is surprisingly slow on some OSes, any by combining it all into a few files, we can often reduce the size from multiple MB, to a few hundred KB.
-
-During the build process of the releases your module package will be generated automatically and bundled with the application, so you have to make sure that the final package is working. If you are developing with a complete dev environment, it is not sufficient if your module works in the dev environment.
-
-Sometimes once built there are issues that prevent a package from running, so it is mandatory to test it before distributing it. In our experience, issues often occur when working with files from disk, or introducing a new dependency that doesn't play nice. Once you have done this once, if you are just changing some internal logic you probably don't need to repeat this unless you want to be sure.
-
-You can build your module into this format with `yarn companion-module-build`. If this was successful, there should now be a `pkg` folder and a `pkg.tgz` file. These both contain the build version of your module!
-If you create an empty file `DEBUG-PACKAGED` in your module folder, then companion will read the code from `pkg` instead. This will let you test it.
-You probably don't need to do a very thorough test, as long as it starts and connects to your device and a couple of actions work it should be fine.
-
-Make sure to remove this `DEBUG-PACKAGED` file once you are done testing it, or next time you try to update your module it will keep loading the copy from `pkg`!
-
-If you encountered any issues in this process that you need help with, then have a look at the [Module packaging](./module-packaging.md) page for additional tips.
+For modules in this new format, we require them to be packaged with some special
+tooling. This is done to both reduce the number of files that your module spans
+on disk, and also the size. Loading code spread across hundreds of files is
+surprisingly slow on some OSes, any by combining it all into a few files, we can
+often reduce the size from multiple MB, to a few hundred KB.
+
+During the build process of the releases your module package will be generated
+automatically and bundled with the application, so you have to make sure that
+the final package is working. If you are developing with a complete dev
+environment, it is not sufficient if your module works in the dev environment.
+
+Sometimes once built there are issues that prevent a package from running, so it
+is mandatory to test it before distributing it. In our experience, issues often
+occur when working with files from disk, or introducing a new dependency that
+doesn't play nice. Once you have done this once, if you are just changing some
+internal logic you probably don't need to repeat this unless you want to be
+sure.
+
+You can build your module into this format with `yarn companion-module-build`.
+If this was successful, there should now be a `pkg` folder and a `pkg.tgz` file.
+These both contain the build version of your module! If you create an empty file
+`DEBUG-PACKAGED` in your module folder, then companion will read the code from
+`pkg` instead. This will let you test it. You probably don't need to do a very
+thorough test, as long as it starts and connects to your device and a couple of
+actions work it should be fine.
+
+Make sure to remove this `DEBUG-PACKAGED` file once you are done testing it, or
+next time you try to update your module it will keep loading the copy from
+`pkg`!
+
+If you encountered any issues in this process that you need help with, then have
+a look at the [Module packaging](./module-packaging.md) page for additional
+tips.
### 15) Feedback
-Have any thoughts/feedback on this process? Anything in the docs that should be improved? Do [let us know](https://github.com/bitfocus/companion-module-base/issues), we are interested in your feedback!
-We won't be able to cater to everything you dislike about the changes, as other modules are already using these new apis, but perhaps we can make the transition smoother?
+Have any thoughts/feedback on this process? Anything in the docs that should be
+improved? Do
+[let us know](https://github.com/bitfocus/companion-module-base/issues), we are
+interested in your feedback! We won't be able to cater to everything you dislike
+about the changes, as other modules are already using these new apis, but
+perhaps we can make the transition smoother?
-Have an idea of a new connection helper that would be beneficial to you? Or have some utility code that you are copying into multiple modules? We are interested to hear this. We are happy to add more to `@companion-module/base` if it will be useful to many modules and is unlikely to result in breaking changes.
+Have an idea of a new connection helper that would be beneficial to you? Or have
+some utility code that you are copying into multiple modules? We are interested
+to hear this. We are happy to add more to `@companion-module/base` if it will be
+useful to many modules and is unlikely to result in breaking changes.
-We appreciate that this update is throwing a lot of changes at you, but changes of this scale are a rare occurrence and shouldn't be necessary to repeat for at least another 5 years.
+We appreciate that this update is throwing a lot of changes at you, but changes
+of this scale are a rare occurrence and shouldn't be necessary to repeat for at
+least another 5 years.
### 16) Follow up recommendations
-There are some extra steps that we recommend modules take, but are completely optional.
+There are some extra steps that we recommend modules take, but are completely
+optional.
- [Setting up code formatting](../module-setup/code-quality.md)
- [Reusable TypeScript config](../module-setup/typescript-config.md)
diff --git a/for-developers/module-development/module-setup/code-quality.md b/for-developers/module-development/module-setup/code-quality.md
index 72755d2..1d6f1ef 100644
--- a/for-developers/module-development/module-setup/code-quality.md
+++ b/for-developers/module-development/module-setup/code-quality.md
@@ -5,21 +5,34 @@ sidebar_position: 4
description: Using prettier and a linter to prevent common bugs.
---
-We recommend using [eslint](https://eslint.org/) and [prettier](https://prettier.io/) to improve the readability and uniformity of your code and to prevent easily-overlooked coding errors. The two tools work together to enforce the formatting and coding rules. If you are using an IDE such as VS Code, we recommend installing the prettier plugin. In that plugin you can also enable 'format on save' to automate some of the formatting.
+We recommend using [eslint](https://eslint.org/) and
+[prettier](https://prettier.io/) to improve the readability and uniformity of
+your code and to prevent easily-overlooked coding errors. The two tools work
+together to enforce the formatting and coding rules. If you are using an IDE
+such as VS Code, we recommend installing the prettier plugin. In that plugin you
+can also enable 'format on save' to automate some of the formatting.
:::tip
-Our [recommended templates](./file-structure.md) come with eslint and prettier configuration files. The remainder of this page is only necessary for people who are setting up their repo manually or want to upgrade an older module's repo... or if you just want to gain a deeper understanding of the mechanics of these config files.
+Our [recommended templates](./file-structure.md) come with eslint and prettier
+configuration files. The remainder of this page is only necessary for people who
+are setting up their repo manually or want to upgrade an older module's repo...
+or if you just want to gain a deeper understanding of the mechanics of these
+config files.
:::
## Installation
-If you are _not_ using the [recommended templates](./file-structure.md), you can configure your module for prettier and eslint as follows:
+If you are _not_ using the [recommended templates](./file-structure.md), you can
+configure your module for prettier and eslint as follows:
-1. Run `yarn add --dev eslint prettier` in the root folder of your repo to install it as a dev dependency.
-2. If you are using TypeScript you will also need to `yarn add --dev typescript-eslint`.
-3. Add the line `"prettier": "@companion-module/tools/.prettierrc.json",` to your _package.json_ file.
+1. Run `yarn add --dev eslint prettier` in the root folder of your repo to
+ install it as a dev dependency.
+2. If you are using TypeScript you will also need to
+ `yarn add --dev typescript-eslint`.
+3. Add the line `"prettier": "@companion-module/tools/.prettierrc.json",` to
+ your _package.json_ file.
4. Add the `scripts` block in your `package.json` to include:
```json
@@ -37,7 +50,8 @@ package.json
pkg
```
-You can list other files/folders here that should be ignored. We want to ignore package.json as prettier and yarn disagree on how it should be formatted.
+You can list other files/folders here that should be ignored. We want to ignore
+package.json as prettier and yarn disagree on how it should be formatted.
## ESLint config
@@ -59,17 +73,23 @@ export default generateEslintConfig({
})
```
-You can now run `yarn lint` and see any linter errors. If you need any help understanding the errors or warnings you are given, the eslint docs are really helpful.
+You can now run `yarn lint` and see any linter errors. If you need any help
+understanding the errors or warnings you are given, the eslint docs are really
+helpful.
:::note
-If you have any suggestions on changes to make to this eslint config, do [open an issue](https://github.com/bitfocus/companion-module-tools/issues) to let us know. We hope that this set of rules will expand over time based on what is and isn't useful to module developers.
+If you have any suggestions on changes to make to this eslint config, do
+[open an issue](https://github.com/bitfocus/companion-module-tools/issues) to
+let us know. We hope that this set of rules will expand over time based on what
+is and isn't useful to module developers.
:::
### Enabling linting on commit
-You can set it up so that git runs the linter when you make a commit, so you can be sure that only good code is committed.
+You can set it up so that git runs the linter when you make a commit, so you can
+be sure that only good code is committed.
Install the needed tools `yarn add --dev lint-staged husky`.
@@ -98,9 +118,11 @@ Run `yarn husky` to ensure husky is initialised.
### Running the linter on push
-It is a good idea to setup a GitHub Actions workflow to run the linter, so that you don't get surprised by unexpected linter failures when running it locally.
+It is a good idea to setup a GitHub Actions workflow to run the linter, so that
+you don't get surprised by unexpected linter failures when running it locally.
-To do this, create a new file in the repository at `.github/workflows/lint.yaml`, with the content:
+To do this, create a new file in the repository at
+`.github/workflows/lint.yaml`, with the content:
```yaml
name: Lint
@@ -172,10 +194,14 @@ export default customConfig
## Upgrading to @companion-module/tools v2.x
-If you are upgrading your config from v1.x, you will need to reconfigure eslint, due to changes in both eslint and how the tools library provides config templates.
+If you are upgrading your config from v1.x, you will need to reconfigure eslint,
+due to changes in both eslint and how the tools library provides config
+templates.
-You can follow the steps for [ESLint Config](#eslint-config), with the following extra steps:
+You can follow the steps for [ESLint Config](#eslint-config), with the following
+extra steps:
-Removing any existing `.eslintrc.json` or `.eslintrc.cjs`, you may want to port any custom configuration across to the new config file
+Removing any existing `.eslintrc.json` or `.eslintrc.cjs`, you may want to port
+any custom configuration across to the new config file
That should be it!
diff --git a/for-developers/module-development/module-setup/file-structure.md b/for-developers/module-development/module-setup/file-structure.md
index 28cacdc..82a8733 100644
--- a/for-developers/module-development/module-setup/file-structure.md
+++ b/for-developers/module-development/module-setup/file-structure.md
@@ -5,24 +5,42 @@ sidebar_position: 1
description: Introduction to the file structure of a Companion module repository
---
-When creating a new module, we strongly recommend using our **[TypeScript module template](https://github.com/bitfocus/companion-module-template-ts)** as this will incorporate the latest module features and improvements. For those who prefer Javascript, we also have a [JavaScript template](https://github.com/bitfocus/companion-module-template). To get an idea of how a completed module looks, search for an existing module that may provide services similar to your equipment, or refer to reference modules such as [homeassistant-server](https://github.com/bitfocus/companion-module-homeassistant-server) (TypeScript) and [generic-osc](https://github.com/bitfocus/companion-module-generic-osc) (JavaScript).
-
-See the [setup instructions](../home#clone-or-copy-a-module-from-github) for more details on how to get started with the templates or another module.
-
-Below are the minimum files necessary to create a control module for Companion (aka Connection). You can add subfolders and other support files as needed.
+When creating a new module, we strongly recommend using our
+**[TypeScript module template](https://github.com/bitfocus/companion-module-template-ts)**
+as this will incorporate the latest module features and improvements. For those
+who prefer Javascript, we also have a
+[JavaScript template](https://github.com/bitfocus/companion-module-template). To
+get an idea of how a completed module looks, search for an existing module that
+may provide services similar to your equipment, or refer to reference modules
+such as
+[homeassistant-server](https://github.com/bitfocus/companion-module-homeassistant-server)
+(TypeScript) and
+[generic-osc](https://github.com/bitfocus/companion-module-generic-osc)
+(JavaScript).
+
+See the [setup instructions](../home#clone-or-copy-a-module-from-github) for
+more details on how to get started with the templates or another module.
+
+Below are the minimum files necessary to create a control module for Companion
+(aka Connection). You can add subfolders and other support files as needed.
:::tip
-All of these files, and more, are included in the templates mentioned above. Using the templates will save you time in setting
-things up and even more time by making sure the essential content has been included correctly -- especially for the package.json file!
+All of these files, and more, are included in the templates mentioned above.
+Using the templates will save you time in setting things up and even more time
+by making sure the essential content has been included correctly -- especially
+for the package.json file!
-The templates also include sample source code to get you started programming the module's functionality.
+The templates also include sample source code to get you started programming the
+module's functionality.
:::
### File Structure
-The essential repository structure includes the source code (in _src_ here), libraries that are automatically loaded by yarn (in _node_modules_) and a number of configuration files as follows:
+The essential repository structure includes the source code (in _src_ here),
+libraries that are automatically loaded by yarn (in _node_modules_) and a number
+of configuration files as follows:
```text
├───companion
@@ -45,73 +63,112 @@ The essential repository structure includes the source code (in _src_ here), lib
### companion/HELP.md
-A structured 'Help' document that Companion users will see when clicking on the module help icon in the Connections page.
+A structured 'Help' document that Companion users will see when clicking on the
+module help icon in the Connections page.
-Describe the module's capabilities and anything else they might need to know to use the module.
+Describe the module's capabilities and anything else they might need to know to
+use the module.
-Format the contents using [markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
+Format the contents using
+[markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
### companion/manifest.json
-Provides information to Companion about the module. See the [manifest.json](./manifest.json.md) page for full details. In particular,
-be sure to name your module with the Companion convention: _companion-module-mymanufacturer-myproduct_ (replacing _mymanufacturer-myproduct_ with appropriate names).
+Provides information to Companion about the module. See the
+[manifest.json](./manifest.json.md) page for full details. In particular, be
+sure to name your module with the Companion convention:
+_companion-module-mymanufacturer-myproduct_ (replacing
+_mymanufacturer-myproduct_ with appropriate names).
### node_modules folder
-When you run `yarn install`, yarn reads the _package.json_ file and installs or updates all of the listed dependencies into the _node_modules_ folder. (It will create this folder if it doesn't already exist.)
+When you run `yarn install`, yarn reads the _package.json_ file and installs or
+updates all of the listed dependencies into the _node_modules_ folder. (It will
+create this folder if it doesn't already exist.)
-At a minimum, for Companion modules, it should install @companion-module/base and @companion-module/tools
+At a minimum, for Companion modules, it should install @companion-module/base
+and @companion-module/tools
### src/main.ts (or main.js, for the JavaScript template)
-This main entrypoint for the module. The file and folder can be called something else, as long as the `"runtime": { "entrypoint": }` field in `companion/manifest.json` and the `"main":` field in `package.json` are updated to match. (Older JavaScript repos skip the subdirectory altogether, though this is no longer recommended.)
+This main entrypoint for the module. The file and folder can be called something
+else, as long as the `"runtime": { "entrypoint": }` field in
+`companion/manifest.json` and the `"main":` field in `package.json` are updated
+to match. (Older JavaScript repos skip the subdirectory altogether, though this
+is no longer recommended.)
-Generally you will create additional source-code files for each major module element: actions, feedback, presets, variables, user-configurations and upgrade scripts. (These files are already present in the template modules mentioned above.)
+Generally you will create additional source-code files for each major module
+element: actions, feedback, presets, variables, user-configurations and upgrade
+scripts. (These files are already present in the template modules mentioned
+above.)
:::note
-When TypeScript is "transpiled" into JavaScript, the code in `src/` is used to generate a `dist/` folder containing the corresponding JavaScript code. In a TypeScript repo, the manifest and package.json files therefore refer to the `dist/` folder even though your development code is in the `src/` folder. (But note that `dist/` is _not_ part of the git repository and must be listed in .gitignore file.)
+When TypeScript is "transpiled" into JavaScript, the code in `src/` is used to
+generate a `dist/` folder containing the corresponding JavaScript code. In a
+TypeScript repo, the manifest and package.json files therefore refer to the
+`dist/` folder even though your development code is in the `src/` folder. (But
+note that `dist/` is _not_ part of the git repository and must be listed in
+.gitignore file.)
:::
### .gitignore
-This is a standard Git file that lists files and folders to be excluded from Git version control. `node_modules/` should always be included in the `.gitignore` as should `dist/` in TypeScript modules.
+This is a standard Git file that lists files and folders to be excluded from Git
+version control. `node_modules/` should always be included in the `.gitignore`
+as should `dist/` in TypeScript modules.
### LICENSE
-Companion is an MIT licensed project. We recommend modules released with the project are also MIT, and are open to other licenses being used if there is a good reason for it.
+Companion is an MIT licensed project. We recommend modules released with the
+project are also MIT, and are open to other licenses being used if there is a
+good reason for it.
-In the future it might be possible to use different licenses for modules, but that is not yet certain.
+In the future it might be possible to use different licenses for modules, but
+that is not yet certain.
:::tip
-Consult the Companion team if you wish to incorporate a dependency that does not have an MIT license.
+Consult the Companion team if you wish to incorporate a dependency that does not
+have an MIT license.
:::
### package.json
-This is a standard node.js file to tell it about your project. It is required to be able to install dependencies to your module such as [@companion-module/base and @companion-module/tools](../module-lifecycle/companion-module-library.md).
+This is a standard node.js file to tell it about your project. It is required to
+be able to install dependencies to your module such as
+[@companion-module/base and @companion-module/tools](../module-lifecycle/companion-module-library.md).
### README.md
-This file should include any relevant developer documentation that the Companion Core and Module Development teams should be aware of, as well as any helpful information for people who wish to fork and contribute. It is only shown on github and when editing the module, so can be reasonably technical.
+This file should include any relevant developer documentation that the Companion
+Core and Module Development teams should be aware of, as well as any helpful
+information for people who wish to fork and contribute. It is only shown on
+github and when editing the module, so can be reasonably technical.
As with the HELP.md file, you can format it with markdown.
### Additional files for good practices
-In addition to the essential files we recommend several other files that help enforce good coding practices.
-These files are all included in the templates recommended above and are discussed on separate pages of this section.
+In addition to the essential files we recommend several other files that help
+enforce good coding practices. These files are all included in the templates
+recommended above and are discussed on separate pages of this section.
-- [Code Quality Enforcement](./code-quality.md): prettier and eslint configuration
-- [TypeScript configuration](./typescript-config.md) if you are using TypeScript (as recommended)
+- [Code Quality Enforcement](./code-quality.md): prettier and eslint
+ configuration
+- [TypeScript configuration](./typescript-config.md) if you are using TypeScript
+ (as recommended)
- [Unit Testing Setup](./unit-testing.md) (there's not much there..)
## Next steps
-- Set up your [_manifest.json_](./manifest.json.md) and _HELP.md_ files in the _companion/_ folder.
+- Set up your [_manifest.json_](./manifest.json.md) and _HELP.md_ files in the
+ _companion/_ folder.
- Look through the optional files mentioned above
-- Familiarize yourself with the [Companion Module Library](../module-lifecycle/companion-module-library.md) concept
-- Read through our introduction to module development: [Module Development 101](../module-development-101.md)
+- Familiarize yourself with the
+ [Companion Module Library](../module-lifecycle/companion-module-library.md)
+ concept
+- Read through our introduction to module development:
+ [Module Development 101](../module-development-101.md)
diff --git a/for-developers/module-development/module-setup/index.md b/for-developers/module-development/module-setup/index.md
index 2e0d24b..b743244 100644
--- a/for-developers/module-development/module-setup/index.md
+++ b/for-developers/module-development/module-setup/index.md
@@ -4,4 +4,5 @@ description: The files and file structure necessary to create a module repositor
auto_toc: 3
---
-This section describes the files and file structure necessary to create a module repository.
+This section describes the files and file structure necessary to create a module
+repository.
diff --git a/for-developers/module-development/module-setup/manifest.json.md b/for-developers/module-development/module-setup/manifest.json.md
index 7bf498b..f1515bd 100644
--- a/for-developers/module-development/module-setup/manifest.json.md
+++ b/for-developers/module-development/module-setup/manifest.json.md
@@ -5,15 +5,22 @@ sidebar_position: 2
description: Specification of the Companion manifest file
---
-Starting with Companion 3.0, Companion looks at the `companion/manifest.json` file for module information (before 3.0 it looked at `package.json`) This provides a companion specific and programming language agnostic manifest about your module. In the future this will allow us to do more powerful things!
+Starting with Companion 3.0, Companion looks at the `companion/manifest.json`
+file for module information (before 3.0 it looked at `package.json`) This
+provides a companion specific and programming language agnostic manifest about
+your module. In the future this will allow us to do more powerful things!
-Read the [auto-generated documentation for manifest.json](https://bitfocus.github.io/companion-module-base/interfaces/ModuleManifest.html) for more details.
+Read the
+[auto-generated documentation for manifest.json](https://bitfocus.github.io/companion-module-base/interfaces/ModuleManifest.html)
+for more details.
-Tip: At any point you can validate your `manifest.json` by running `yarn companion-module-check`.
+Tip: At any point you can validate your `manifest.json` by running
+`yarn companion-module-check`.
## Format
-If you are comfortable reading or working with JSON Schema, you can find the [formal definition in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/assets/manifest.schema.json)
+If you are comfortable reading or working with JSON Schema, you can find the
+[formal definition in the module-base repo](https://github.com/bitfocus/companion-module-base/blob/main/assets/manifest.schema.json)
A full manifest definition is:
@@ -48,24 +55,41 @@ A full manifest definition is:
## Properties
-- `id` unique id of your module. This has to match the repository name excluding the `companion-module-`
+- `id` unique id of your module. This has to match the repository name excluding
+ the `companion-module-`
- `name` ???
- `shortname` ???
- `description` ???
- `manufacturer` ???
-- `products` An array of strings with the names of the products supported by your module. Often there is only a single product or sometimes the name of a series of products is better known than the products itself, then it is also good to give the series name. Your module will be listed with all associated product names.
-- `keywords` Keywords to allow users to more easily find your module by searching, please do not repeat the manufacturer or product names here.
-- `version` Version of your module. This should be left as `0.0.0`, the build process populates with the value in your `package.json`
-- `license` License of your module code. This needs to be something MIT compatible to be allowed to be distributed with the official builds
+- `products` An array of strings with the names of the products supported by
+ your module. Often there is only a single product or sometimes the name of a
+ series of products is better known than the products itself, then it is also
+ good to give the series name. Your module will be listed with all associated
+ product names.
+- `keywords` Keywords to allow users to more easily find your module by
+ searching, please do not repeat the manufacturer or product names here.
+- `version` Version of your module. This should be left as `0.0.0`, the build
+ process populates with the value in your `package.json`
+- `license` License of your module code. This needs to be something MIT
+ compatible to be allowed to be distributed with the official builds
- `repository` Git URL to the repository
- `bugs` URL to the issue tracker. Users can follow this link to report bugs
- `maintainers` List of maintainers of this module.
-- `legacyIds` (Optional) List of old module ids. If the module has been renamed, the old names should be listed here to allow for seamless upgrading of old configs
-- `runtime` This defines the runtime requirements of your module. Described more below
+- `legacyIds` (Optional) List of old module ids. If the module has been renamed,
+ the old names should be listed here to allow for seamless upgrading of old
+ configs
+- `runtime` This defines the runtime requirements of your module. Described more
+ below
The runtime block is defined as:
-- `type` This can be either `node18` or `node22`, depending on the required version of Node.js. In the future this may allow for other languages to be used.
-- `api` This must be `nodejs-ipc`. It defines the protocol used between your module and Companion. In the future more options will be possible, to allow for other languages.
-- `apiVersion` This should be left as `0.0.0`, the build process populates with the correct value
-- `entrypoint` The main JavaScript file for your module. This is what companion will execute to start your module.
+- `type` This can be either `node18` or `node22`, depending on the required
+ version of Node.js. In the future this may allow for other languages to be
+ used.
+- `api` This must be `nodejs-ipc`. It defines the protocol used between your
+ module and Companion. In the future more options will be possible, to allow
+ for other languages.
+- `apiVersion` This should be left as `0.0.0`, the build process populates with
+ the correct value
+- `entrypoint` The main JavaScript file for your module. This is what companion
+ will execute to start your module.
diff --git a/for-developers/module-development/module-setup/typescript-config.md b/for-developers/module-development/module-setup/typescript-config.md
index ea5212f..1a65d95 100644
--- a/for-developers/module-development/module-setup/typescript-config.md
+++ b/for-developers/module-development/module-setup/typescript-config.md
@@ -7,12 +7,16 @@ description: Configuring the module to work with TypeScript.
:::tip
-This is an advanced topic. If you use the [recommended templates](./file-structure.md), a default typescript
-config file is included and you will generally not want to change it.
+This is an advanced topic. If you use the
+[recommended templates](./file-structure.md), a default typescript config file
+is included and you will generally not want to change it.
:::
-The [recommended templates](./file-structure.md) provide typescript config presets in _tsconfig.json_ that we believe to be best practice, but they can be configured to be too strict for some, or may need to be modified if you change the name of the source or destination directories.
+The [recommended templates](./file-structure.md) provide typescript config
+presets in _tsconfig.json_ that we believe to be best practice, but they can be
+configured to be too strict for some, or may need to be modified if you change
+the name of the source or destination directories.
A typical _tsconfig.json_ file looks like:
@@ -63,6 +67,9 @@ Our TypeScript template splits it into two files:
}
```
-You are free to override properties as you wish, this is only our recommendation after all.
+You are free to override properties as you wish, this is only our recommendation
+after all.
-If you have any suggestions on changes to make to this base tsconfig, do [open an issue](https://github.com/bitfocus/companion-module-tools/issues) to let us know. We hope to collect some alternate presets along with recommended.
+If you have any suggestions on changes to make to this base tsconfig, do
+[open an issue](https://github.com/bitfocus/companion-module-tools/issues) to
+let us know. We hope to collect some alternate presets along with recommended.
diff --git a/for-developers/module-development/module-setup/unit-testing.md b/for-developers/module-development/module-setup/unit-testing.md
index 1b07792..4ff4f20 100644
--- a/for-developers/module-development/module-setup/unit-testing.md
+++ b/for-developers/module-development/module-setup/unit-testing.md
@@ -5,11 +5,17 @@ sidebar_position: 6
description: Unit testing config and advice.
---
-If you choose to include unit tests in your module repo, you can choose a framework such as Vitest, Mocha or Jest. [Vitest](https://vitest.dev/) may be especially useful for its native support of TypeScript. However, unit testing of modules is not very common: We find it quite hard to test most modules as to do so requires mocking-up the device connection.
+If you choose to include unit tests in your module repo, you can choose a
+framework such as Vitest, Mocha or Jest. [Vitest](https://vitest.dev/) may be
+especially useful for its native support of TypeScript. However, unit testing of
+modules is not very common: We find it quite hard to test most modules as to do
+so requires mocking-up the device connection.
-For TypeScript repos, you may need to add information to `compilerOptions": {"types": [] }`.
+For TypeScript repos, you may need to add information to
+`compilerOptions": {"types": [] }`.
-If you have any suggestions on mocks, tooling or examples we should provide to make this easier, we are open to suggestions!
+If you have any suggestions on mocks, tooling or examples we should provide to
+make this easier, we are open to suggestions!
Some modules which are known to have some unit tests:
diff --git a/for-developers/setting-up-WSL.md b/for-developers/setting-up-WSL.md
index 77d74bb..1ea086e 100644
--- a/for-developers/setting-up-WSL.md
+++ b/for-developers/setting-up-WSL.md
@@ -5,41 +5,73 @@ sidebar_position: 1.1
description: How to set up Windows System for Linux (WSL) for Companion development
---
-For other platforms see: [Initial Setup](setting-up-developer-environment.md) instead.
+For other platforms see: [Initial Setup](setting-up-developer-environment.md)
+instead.
## Install WSL
-Although it is possible to develop directly in Windows, there are occasions when you might want to use a Linux environment under Windows. The key is to use Windows' Subsystem for Linux (WSL).
+Although it is possible to develop directly in Windows, there are occasions when
+you might want to use a Linux environment under Windows. The key is to use
+Windows' Subsystem for Linux (WSL).
-First install Windows Subsystem for Linux version 2 (WSL2),
-WSL is included with Windows but needs to be activated. Follow [Microsoft’s installation instructions](https://learn.microsoft.com/en-us/windows/wsl/setup/environment). Basically, open a command or powershell window and type:
+First install Windows Subsystem for Linux version 2 (WSL2), WSL is included with
+Windows but needs to be activated. Follow
+[Microsoft’s installation instructions](https://learn.microsoft.com/en-us/windows/wsl/setup/environment).
+Basically, open a command or powershell window and type:
```powershell
wsl --install
```
-After this completes, reboot your computer and WSL will automatically install the latest LTS version of Ubuntu. (24.04 at this time of writing).
+After this completes, reboot your computer and WSL will automatically install
+the latest LTS version of Ubuntu. (24.04 at this time of writing).
## Install the basic development tools
Once this is done continue through Microsoft’s instructions, especially
- `sudo apt update && sudo apt upgrade`,
-as well as the instructions to:
+`sudo apt update && sudo apt upgrade`, as well as the instructions to:
- Set up Windows terminal,
- Set up VS Code, and
- Set up Git.
-If you develop with Visual Studio Code, which we currently recommend, then you can do remote developing. That means VS Code runs on Windows but it opens a connection to the WSL virtual machine. It allows you to edit the files in the WSL file system. VS Code also has an integrated terminal so you can work on the WSL OS (typically Ubuntu). For that you should install the [WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) extension and follow [Microsoft’s instructions here](https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode). You will see the connection info on the bottom left of each window and you can connect there or by the command palette. You can debug using breakpoints etc. either by starting automatic debugging from the terminal or by attaching to the running Node.js process (though it may be hard to find: it should be the first one in the list when you type ctrl-shift-P and “Debug: Attach to Node Process” but isn't always so).
-
-You will need to install all the prerequisite tools on the WSL machine just like you would do on Linux, as described in the [Setting Up A Developer Environment](setting-up-developer-environment.md).
-
-When you are running Companion from a VS Code terminal, VS Code will know the network ports and create automatic port forwards for you. That means although Companion runs on the virtual machine, you'll be able to access the admin page from your Windows host by accessing localhost or 127.0.0.1 and the used port.
-That makes it quite convenient but you always have to remember that Companion runs on a virtual machine inside of your computer and that virtual machine has a different IP-address. When you want to access the API of software running on your Windows host, you can't use 127.0.0.1 like you would without WSL. 127.0.0.1 is the localhost of the WSL. WSL sets up a virtual network interface for you and to access your host OS, you have to use 172.28.96.1. Verify this using the command `ip route` in your Linux shell.
+If you develop with Visual Studio Code, which we currently recommend, then you
+can do remote developing. That means VS Code runs on Windows but it opens a
+connection to the WSL virtual machine. It allows you to edit the files in the
+WSL file system. VS Code also has an integrated terminal so you can work on the
+WSL OS (typically Ubuntu). For that you should install the
+[WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)
+extension and follow
+[Microsoft’s instructions here](https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode).
+You will see the connection info on the bottom left of each window and you can
+connect there or by the command palette. You can debug using breakpoints etc.
+either by starting automatic debugging from the terminal or by attaching to the
+running Node.js process (though it may be hard to find: it should be the first
+one in the list when you type ctrl-shift-P and “Debug: Attach to Node Process”
+but isn't always so).
+
+You will need to install all the prerequisite tools on the WSL machine just like
+you would do on Linux, as described in the
+[Setting Up A Developer Environment](setting-up-developer-environment.md).
+
+When you are running Companion from a VS Code terminal, VS Code will know the
+network ports and create automatic port forwards for you. That means although
+Companion runs on the virtual machine, you'll be able to access the admin page
+from your Windows host by accessing localhost or 127.0.0.1 and the used port.
+That makes it quite convenient but you always have to remember that Companion
+runs on a virtual machine inside of your computer and that virtual machine has a
+different IP-address. When you want to access the API of software running on
+your Windows host, you can't use 127.0.0.1 like you would without WSL. 127.0.0.1
+is the localhost of the WSL. WSL sets up a virtual network interface for you and
+to access your host OS, you have to use 172.28.96.1. Verify this using the
+command `ip route` in your Linux shell.
## Set Up Access to USB Ports
-If you want to use USB-devices in WSL, it gets complicated because WSL doesn't have built-in USB passthrough features. The solution is USB over IP software. That means you capture the USB packets at the host, transmit it to the virtual machine and then inject it to the USB system there. Here is how it's done:
+If you want to use USB-devices in WSL, it gets complicated because WSL doesn't
+have built-in USB passthrough features. The solution is USB over IP software.
+That means you capture the USB packets at the host, transmit it to the virtual
+machine and then inject it to the USB system there. Here is how it's done:
You may have to run the following in a Linux shell:
@@ -50,9 +82,12 @@ apt-get install -y libusb-1.0-0-dev libudev-dev libfontconfig1
Then:
-- On Windows install the [USB-IP driver](https://github.com/dorssel/usbipd-win/releases)
-- Optional but highly recommended install a GUI to control the USB connections: [WSL USB Manager](https://gitlab.com/alelec/wsl-usb-gui/-/releases)
-- Make sure your WSL kernel is at least version 5.15.150.1 (released Mar 2024) (`uname -a`). If not, update your kernel.
+- On Windows install the
+ [USB-IP driver](https://github.com/dorssel/usbipd-win/releases)
+- Optional but highly recommended install a GUI to control the USB connections:
+ [WSL USB Manager](https://gitlab.com/alelec/wsl-usb-gui/-/releases)
+- Make sure your WSL kernel is at least version 5.15.150.1 (released Mar 2024)
+ (`uname -a`). If not, update your kernel.
- Linux distributions need extra rules to make USB devices accessible to users:
- Copy the following code into a bash shell (terminal) to create the rules file:
@@ -63,11 +98,23 @@ EOF
```
-- Now reboot the Computer (It may be sufficient to type: `sudo udevadm control --reload-rules`.)
+- Now reboot the Computer (It may be sufficient to type:
+ `sudo udevadm control --reload-rules`.)
- Open the WSL USB Manager in Windows
-- Attach your USB device. You should see it popping up in the top pane of the manager.
-- Check the "bound" checkbox next to your USB device (usbip will now remember this permission; you won't have to do it again.)
-- Select the USB device by clicking on it and then press the "Attach" button. The device should now move from the top pane to the forwarded devices pane.
-- Optional: on the linux shell use `lsusb` to check if you find your device and remember the bus and device number.
-- Optional: In the linux shell use `cat /dev/bus/usb/001/003` to check if you have access to the device. Replace the numbers (/001/003) with the bus number and the device number that you have found with lsusb
-- _Note: most Companion's USB surfaces are handled as HID devices. WSL presents the HID interface through a separate “device” than shown by_ `lsusb` _Instead when an HID device is added via the usb-ip driver, it will set up_ `/dev/hidraw#` where # is an integer starting from 1. If permissions are incorrectly set, Companion will output an error message in the terminal. _You can also test it directly, as above._
+- Attach your USB device. You should see it popping up in the top pane of the
+ manager.
+- Check the "bound" checkbox next to your USB device (usbip will now remember
+ this permission; you won't have to do it again.)
+- Select the USB device by clicking on it and then press the "Attach" button.
+ The device should now move from the top pane to the forwarded devices pane.
+- Optional: on the linux shell use `lsusb` to check if you find your device and
+ remember the bus and device number.
+- Optional: In the linux shell use `cat /dev/bus/usb/001/003` to check if you
+ have access to the device. Replace the numbers (/001/003) with the bus number
+ and the device number that you have found with lsusb
+- _Note: most Companion's USB surfaces are handled as HID devices. WSL presents
+ the HID interface through a separate “device” than shown by_ `lsusb` _Instead
+ when an HID device is added via the usb-ip driver, it will set up_
+ `/dev/hidraw#` where # is an integer starting from 1. If permissions are
+ incorrectly set, Companion will output an error message in the terminal. _You
+ can also test it directly, as above._
diff --git a/for-developers/setting-up-developer-environment.md b/for-developers/setting-up-developer-environment.md
index 4d17bec..8499700 100644
--- a/for-developers/setting-up-developer-environment.md
+++ b/for-developers/setting-up-developer-environment.md
@@ -5,38 +5,57 @@ sidebar_position: 1
description: Setting up a Developer Environment
---
-import UserGuideLink from '@site/src/UserGuideLink';
+import UserGuideLink from '@site/src/UserGuideLink'
-Companion is written in Javascript/TypeScript and uses the [Node.js](https://nodejs.org/en/) runtime. In addition, all parts of Companion are organized and tracked using [Git](./git-workflows/installing-git.md). Here we will provide instructions for installing the development tools you will need for contributing to Companion, whether as a module or a part of core Companion.
+Companion is written in Javascript/TypeScript and uses the
+[Node.js](https://nodejs.org/en/) runtime. In addition, all parts of Companion
+are organized and tracked using [Git](./git-workflows/installing-git.md). Here
+we will provide instructions for installing the development tools you will need
+for contributing to Companion, whether as a module or a part of core Companion.
-Companion, Javascript and Node.js are platform independent, so you can develop on Windows, macOS or Linux and the code you write will be able to run on all three platforms.
+Companion, Javascript and Node.js are platform independent, so you can develop
+on Windows, macOS or Linux and the code you write will be able to run on all
+three platforms.
:::note
-For module development you may be able to skip step 5, below, "Enabling USB on Unix". Instead
-simply install Companion according to the instructions in the getting started guide.
+For module development you may be able to skip step 5, below, "Enabling USB on
+Unix". Instead simply install Companion according to the instructions in the
+getting started guide.
:::
## 1. Install Node.js manager (fnm)
-We strongly recommend using the [fnm](https://github.com/Schniz/fnm#installation) version manager to allow for easily updating and switching between Node.js versions. If you choose to install Node.js without fnm, you will still need to ensure you a running the right Node.js versions as Companion evolves.
+We strongly recommend using the
+[fnm](https://github.com/Schniz/fnm#installation) version manager to allow for
+easily updating and switching between Node.js versions. If you choose to install
+Node.js without fnm, you will still need to ensure you a running the right
+Node.js versions as Companion evolves.
### Installing fnm on Windows
:::note
-If you want to run in Linux Subsystem for Windows (aka WSL), please follow the [WSL Instructions page](setting-up-WSL.md) and then follow the instructions, below, in the [Linux section, below](#installing-fnm-on-linux-and-macos).
+If you want to run in Linux Subsystem for Windows (aka WSL), please follow the
+[WSL Instructions page](setting-up-WSL.md) and then follow the instructions,
+below, in the [Linux section, below](#installing-fnm-on-linux-and-macos).
:::
:::tip
-If PowerShell complains about unsigned apps, go to Settings, search for "developer settings" and enable "Change execution policy to allow local PowerShell scripts to run without signing". Alternatively, in a PowerShell with elevated permissions run: `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
+If PowerShell complains about unsigned apps, go to Settings, search for
+"developer settings" and enable "Change execution policy to allow local
+PowerShell scripts to run without signing". Alternatively, in a PowerShell with
+elevated permissions run:
+`Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`
:::
-If you are new to code development on Windows, the built-in `winget` command is probably the simplest way to install fnm. (Other popular package managers such as Chocolatey and Scoop work similarly.)
+If you are new to code development on Windows, the built-in `winget` command is
+probably the simplest way to install fnm. (Other popular package managers such
+as Chocolatey and Scoop work similarly.)
In Powershell (admin mode) type:
@@ -44,7 +63,9 @@ In Powershell (admin mode) type:
winget install Schniz.fnm
```
-Once it has loaded, configure PowerShell as described in the fnm GitHub repo. Briefly you need to add a line to the end of the powershell startup script (aka profile). The following opens the profile file in a text editor
+Once it has loaded, configure PowerShell as described in the fnm GitHub repo.
+Briefly you need to add a line to the end of the powershell startup script (aka
+profile). The following opens the profile file in a text editor
```powershell
if (-not (Test-Path $profile)) { New-Item $profile -Force }
@@ -59,7 +80,8 @@ fnm env --use-on-cd --corepack-enabled --version-file-strategy=recursive --shell
### Installing fnm on Linux and MacOS
-Use the following script (see [fnm instructions in GitHub](https://github.com/Schniz/fnm?tab=readme-ov-file#installation))
+Use the following script (see
+[fnm instructions in GitHub](https://github.com/Schniz/fnm?tab=readme-ov-file#installation))
```bash
curl -fsSL https://fnm.vercel.app/install | bash
@@ -67,7 +89,8 @@ curl -fsSL https://fnm.vercel.app/install | bash
:::note
-The install script requires unzip to be installed on your system. If it isn't, install it by typing:
+The install script requires unzip to be installed on your system. If it isn't,
+install it by typing:
```
sudo apt install unzip
@@ -77,7 +100,8 @@ sudo apt install unzip
**upgrading fnm**:
-on MacOS upgrade fnm using Homebrew: `brew upgrade fnm` (you can also install using manually using Homebrew)
+on MacOS upgrade fnm using Homebrew: `brew upgrade fnm` (you can also install
+using manually using Homebrew)
on other Linux systems upgrade using:
@@ -87,8 +111,9 @@ curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
## 2. Install Node.js using fnm
-Once you have installed fnm, execute the following in a terminal/PowerShell.
-To install Node.js v22 (the version required for Core Companion development at the time of writing) and make it the default.
+Once you have installed fnm, execute the following in a terminal/PowerShell. To
+install Node.js v22 (the version required for Core Companion development at the
+time of writing) and make it the default.
```bash
fnm install 22
@@ -97,33 +122,47 @@ fnm default 22
corepack enable
```
-(Note: `corepack enable` may not be needed in Windows if using PowerShell with the setup described above.)
+(Note: `corepack enable` may not be needed in Windows if using PowerShell with
+the setup described above.)
:::note
-Some older modules uses node v18 instead of v22, but are encouraged to update to v22. Sometimes updating the node version can introduce new bugs, but staying on older versions makes development harder as tools drop support for those versions. At some point, Companion will require modules to be node v22 (or perhaps a newer version).
+Some older modules uses node v18 instead of v22, but are encouraged to update to
+v22. Sometimes updating the node version can introduce new bugs, but staying on
+older versions makes development harder as tools drop support for those
+versions. At some point, Companion will require modules to be node v22 (or
+perhaps a newer version).
-With fnm you can install both v18 and v22 and quickly switch between versions as needed. fnm can be setup to do this automatically with the `--use-on-cd` switch (as recommended in the [Windows section](#installing-fnm-on-windows) above), or you can switch it manually with a command like `fnm use 22`. See the [fnm config](https://github.com/Schniz/fnm/blob/master/docs/configuration.md) docs for more information on `--use-on-cd` and the related `--resolve-engines` options.
+With fnm you can install both v18 and v22 and quickly switch between versions as
+needed. fnm can be setup to do this automatically with the `--use-on-cd` switch
+(as recommended in the [Windows section](#installing-fnm-on-windows) above), or
+you can switch it manually with a command like `fnm use 22`. See the
+[fnm config](https://github.com/Schniz/fnm/blob/master/docs/configuration.md)
+docs for more information on `--use-on-cd` and the related `--resolve-engines`
+options.
:::
:::warning
-Do not install yarn directly. Instead, let corepack ensure that the right version is installed
-when you run `yarn install`. If you have already installed
+Do not install yarn directly. Instead, let corepack ensure that the right
+version is installed when you run `yarn install`. If you have already installed
yarn globally and are having problems, consider removing the global install.
:::
## 3. Install and setup git
-See the [instructions for installing Git here](./git-workflows/installing-git.md).
+See the
+[instructions for installing Git here](./git-workflows/installing-git.md).
:::info[Windows Note]
As per [the windows note here](./git-workflows/installing-git.md#configure-git):
-In order for `git clone` to give you `lf` endings, this default needs to be overridden _**before you clone the companion repository**_. In a git bash window type:
+In order for `git clone` to give you `lf` endings, this default needs to be
+overridden _**before you clone the companion repository**_. In a git bash window
+type:
```bash
git config set --global core.autocrlf false
@@ -134,24 +173,30 @@ git config set --global core.eol lf
## 4. Enabling USB access on Linux Systems
-If you are using linux, you should follow the dependencies and udev rules steps as described in the README included in the release builds https://github.com/bitfocus/companion/tree/main/assets/linux.
+If you are using linux, you should follow the dependencies and udev rules steps
+as described in the README included in the release builds
+https://github.com/bitfocus/companion/tree/main/assets/linux.
For WSL, follow the [WSL setup instructions](setting-up-WSL.md) instead.
## 5. Editing Code / Integrated Development Environment (IDE)
-To edit the source code or write new code you can use any text editor you like, but there are many editors which are made especially for developing computer code or even better especially for JavaScript.
-If you have no prior experience, we recommend the [Visual Studio Code](https://code.visualstudio.com/) editor (VS Code).
+To edit the source code or write new code you can use any text editor you like,
+but there are many editors which are made especially for developing computer
+code or even better especially for JavaScript. If you have no prior experience,
+we recommend the [Visual Studio Code](https://code.visualstudio.com/) editor (VS
+Code).
:::tip
-We recommend installing the _ESLint_, _prettier_ and _typos_ plugins for VS Code.
+We recommend installing the _ESLint_, _prettier_ and _typos_ plugins for VS
+Code.
:::
:::note[Linux Note]
-If you want a simple windowing text-editor in Linux, you can try gedit. Install it with `sudo apt install gedit`
+If you want a simple windowing text-editor in Linux, you can try gedit. Install
+it with `sudo apt install gedit`
:::
-
From 1e4db86bf55fd108d6cab452122b222f214249fc Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Sat, 28 Feb 2026 21:54:32 -0800
Subject: [PATCH 05/12] fix: replace all generic image tags
Bonus: (not directly needed for this PR)
- Replace `![image]()` with a descriptive label.
---
for-developers/core-development/build-companion.md | 4 ++--
for-developers/git-workflows/github-workflow.md | 2 +-
.../connection-advanced/bonjour-device-discovery.md | 3 ++-
for-developers/module-development/local-modules.md | 4 ++--
4 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/for-developers/core-development/build-companion.md b/for-developers/core-development/build-companion.md
index eb05d2c..cf3a1f8 100644
--- a/for-developers/core-development/build-companion.md
+++ b/for-developers/core-development/build-companion.md
@@ -66,13 +66,13 @@ allow building Companion in Windows:
2. Turn on Developer Mode in Windows Settings. (Open Settings and search for
"developer"):
- 
+ 
3. Set a local policy in the “Local Security Policy” editor: Security Settings >
Local Policies > User Rights Assignment: Create symbolic links, to allow
yourself to create symlinks:
- 
+ 
:::
diff --git a/for-developers/git-workflows/github-workflow.md b/for-developers/git-workflows/github-workflow.md
index defe12c..c8ebd56 100644
--- a/for-developers/git-workflows/github-workflow.md
+++ b/for-developers/git-workflows/github-workflow.md
@@ -5,7 +5,7 @@ sidebar_position: 3
description: Introduction to git and github workflow for beginners
---
-
+
The following is the basic workflow for contributing to Companion (and many
other open-source repositories) on GitHub. The order of operations is a key to
diff --git a/for-developers/module-development/connection-advanced/bonjour-device-discovery.md b/for-developers/module-development/connection-advanced/bonjour-device-discovery.md
index ce5df16..24bd112 100644
--- a/for-developers/module-development/connection-advanced/bonjour-device-discovery.md
+++ b/for-developers/module-development/connection-advanced/bonjour-device-discovery.md
@@ -41,7 +41,8 @@ and in your `companion/manifest.json`:
These two structures are linked by the common id, in the future this will allow
us to automate device discovery further.
-In the UI, this field will look like: 
+In the UI, this field will look like:
+
The 'Manual' option is always shown, and must be handled to allow users to
manually specify an address for environments where Bonjour does not work. This
diff --git a/for-developers/module-development/local-modules.md b/for-developers/module-development/local-modules.md
index 7f1e7d0..06e3e00 100644
--- a/for-developers/module-development/local-modules.md
+++ b/for-developers/module-development/local-modules.md
@@ -29,12 +29,12 @@ corresponding to a different module.
- Check the section above on how to structure this folder
- Open/show the launcher window of Companion:
- 
+ 
- In the top right corner you will see a Cog. Click on it to show the **Advanced
Settings** window:
-
+
- In the **Developer** section click on _**Select**_ to specify the directory
where you have stored your developer modules.
From c1a0b37bb11ee2308b5b349c50fcc213a34e27f7 Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Sat, 28 Feb 2026 21:11:39 -0800
Subject: [PATCH 06/12] feat: center markdown images by default
This improves readability and simplifies some cases.
(A complete search of the repo did not reveal any cases in which this breaks the current text-flow, i.e. by breaking up a single line.)
Note a nice side-effect is that the image will always appear on its own line. (If you need to override this, it should be possible with inline html/style.)
Note: this is prelude to an internal reformat of for-developers (i.e. reformat the files with essentially no change to the built website)
---
src/css/custom.css | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/css/custom.css b/src/css/custom.css
index ef8c1a7..e972fd5 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -293,3 +293,9 @@
.markdown h3 {
font-size: 1.25em;
}
+
+.markdown img {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
From d7578bf4ac039006579dda0f0eedd05f40cdd369 Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Sat, 28 Feb 2026 22:57:19 -0800
Subject: [PATCH 07/12] fix main rabbit issues and rerun format
---
.prettierrc | 2 +-
for-developers/git-workflows/github-workflow.md | 8 +++++---
.../module-development/api-changes/v2.0.md | 3 ++-
.../module-development/module-lifecycle/index.md | 3 ++-
.../module-lifecycle/releasing-your-module.md | 3 ++-
...g-a-custom-version-of-@companion-module-base.md | 3 ++-
.../module-development/module-setup/index.md | 3 ++-
.../module-setup/typescript-config.md | 14 ++++++++++++--
.../module-setup/unit-testing.md | 2 +-
for-developers/setting-up-WSL.md | 3 ++-
for-developers/setting-up-developer-environment.md | 3 ++-
src/css/custom.css | 2 +-
12 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/.prettierrc b/.prettierrc
index d30dcc5..739f9a7 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -23,7 +23,7 @@
}
},
{
- "files": "for-developers/**/*.md, for-developers/**/*.mdx",
+ "files": ["for-developers/**/*.md", "for-developers/**/*.mdx"],
"options": {
"proseWrap": "always",
"printWidth": 80,
diff --git a/for-developers/git-workflows/github-workflow.md b/for-developers/git-workflows/github-workflow.md
index c8ebd56..60c4217 100644
--- a/for-developers/git-workflows/github-workflow.md
+++ b/for-developers/git-workflows/github-workflow.md
@@ -5,7 +5,7 @@ sidebar_position: 3
description: Introduction to git and github workflow for beginners
---
-
+
The following is the basic workflow for contributing to Companion (and many
other open-source repositories) on GitHub. The order of operations is a key to
@@ -29,7 +29,9 @@ bitfocus/companion-module-generic-http.)
you're contributing to an existing repository. Eventually you may get
write-access, for example if you become the maintainer of a Companion module,
in which case the flow can be simplified...but it's still good practice to
- develop new features on a new branch. :::
+ develop new features on a new branch.
+
+:::
:::note[Expert Note]
@@ -89,7 +91,7 @@ On the GitHub page for your new fork, copy the HTTPS link to your fork using the
green
**<> Code ▼** button. Then paste it on a line starting with
-`it remote add personal`. It should look like this (for core Companion):
+`git remote add personal`. It should look like this (for core Companion):
```bash
git remote add personal https://github.com//companion.git
diff --git a/for-developers/module-development/api-changes/v2.0.md b/for-developers/module-development/api-changes/v2.0.md
index 357bed7..69c6dad 100644
--- a/for-developers/module-development/api-changes/v2.0.md
+++ b/for-developers/module-development/api-changes/v2.0.md
@@ -1,7 +1,8 @@
---
title: API 2.0 (Companion 4.3+)
sidebar_position: -200
-description: 'Overview of API 2.0 breaking changes (expression parsing, presets overhaul,
+description:
+ 'Overview of API 2.0 breaking changes (expression parsing, presets overhaul,
TypeScript improvements).'
---
diff --git a/for-developers/module-development/module-lifecycle/index.md b/for-developers/module-development/module-lifecycle/index.md
index 8c03bae..67ca583 100644
--- a/for-developers/module-development/module-lifecycle/index.md
+++ b/for-developers/module-development/module-lifecycle/index.md
@@ -1,6 +1,7 @@
---
title: 'Module Development Lifecycle: Release and Maintenance'
-description: The task necessary to release, maintain and upgrade a module repository over
+description:
+ The task necessary to release, maintain and upgrade a module repository over
time.
auto_toc: 2
---
diff --git a/for-developers/module-development/module-lifecycle/releasing-your-module.md b/for-developers/module-development/module-lifecycle/releasing-your-module.md
index a2de0d1..3106b6f 100644
--- a/for-developers/module-development/module-lifecycle/releasing-your-module.md
+++ b/for-developers/module-development/module-lifecycle/releasing-your-module.md
@@ -2,7 +2,8 @@
title: 'Releasing a Companion Module'
sidebar_label: 'Release a module'
sidebar_position: 3
-description: How to release your module for delivery to others using Companion's "web
+description:
+ How to release your module for delivery to others using Companion's "web
store".
---
diff --git a/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md b/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
index 7fd4b1b..0e2257e 100644
--- a/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
+++ b/for-developers/module-development/module-lifecycle/testing-a-custom-version-of-@companion-module-base.md
@@ -2,7 +2,8 @@
title: 'Using a custom @companion-module/base library'
sidebar_label: 'Custom @companion-module/base'
sidebar_position: 8
-description: How to test and use your module with a non-release version of the companion
+description:
+ How to test and use your module with a non-release version of the companion
modules.
---
diff --git a/for-developers/module-development/module-setup/index.md b/for-developers/module-development/module-setup/index.md
index b743244..453d3f2 100644
--- a/for-developers/module-development/module-setup/index.md
+++ b/for-developers/module-development/module-setup/index.md
@@ -1,6 +1,7 @@
---
title: Module Setup and Structure
-description: The files and file structure necessary to create a module repository.
+description:
+ The files and file structure necessary to create a module repository.
auto_toc: 3
---
diff --git a/for-developers/module-development/module-setup/typescript-config.md b/for-developers/module-development/module-setup/typescript-config.md
index 1a65d95..3683ad8 100644
--- a/for-developers/module-development/module-setup/typescript-config.md
+++ b/for-developers/module-development/module-setup/typescript-config.md
@@ -24,7 +24,12 @@ A typical _tsconfig.json_ file looks like:
{
"extends": "@companion-module/tools/tsconfig/node22/recommended",
"include": ["src/**/*.ts"],
- "exclude": ["node_modules/**", "src/**/*spec.ts", "src/**/__tests__/*", "src/**/__mocks__/*"],
+ "exclude": [
+ "node_modules/**",
+ "src/**/*spec.ts",
+ "src/**/__tests__/*",
+ "src/**/__mocks__/*",
+ ],
"compilerOptions": {
"outDir": "./dist",
"baseUrl": "./",
@@ -54,7 +59,12 @@ Our TypeScript template splits it into two files:
{
"extends": "@companion-module/tools/tsconfig/node22/recommended",
"include": ["src/**/*.ts"],
- "exclude": ["node_modules/**", "src/**/*spec.ts", "src/**/__tests__/*", "src/**/__mocks__/*"],
+ "exclude": [
+ "node_modules/**",
+ "src/**/*spec.ts",
+ "src/**/__tests__/*",
+ "src/**/__mocks__/*",
+ ],
"compilerOptions": {
"outDir": "./dist",
"baseUrl": "./",
diff --git a/for-developers/module-development/module-setup/unit-testing.md b/for-developers/module-development/module-setup/unit-testing.md
index 4ff4f20..8ab676d 100644
--- a/for-developers/module-development/module-setup/unit-testing.md
+++ b/for-developers/module-development/module-setup/unit-testing.md
@@ -12,7 +12,7 @@ modules is not very common: We find it quite hard to test most modules as to do
so requires mocking-up the device connection.
For TypeScript repos, you may need to add information to
-`compilerOptions": {"types": [] }`.
+`"compilerOptions": {"types": [] }`.
If you have any suggestions on mocks, tooling or examples we should provide to
make this easier, we are open to suggestions!
diff --git a/for-developers/setting-up-WSL.md b/for-developers/setting-up-WSL.md
index 1ea086e..8052452 100644
--- a/for-developers/setting-up-WSL.md
+++ b/for-developers/setting-up-WSL.md
@@ -2,7 +2,8 @@
title: Setting Up WSL for the Developer Environment
sidebar_label: '└─ WSL Setup Notes'
sidebar_position: 1.1
-description: How to set up Windows System for Linux (WSL) for Companion development
+description:
+ How to set up Windows System for Linux (WSL) for Companion development
---
For other platforms see: [Initial Setup](setting-up-developer-environment.md)
diff --git a/for-developers/setting-up-developer-environment.md b/for-developers/setting-up-developer-environment.md
index 8499700..8cdf2a1 100644
--- a/for-developers/setting-up-developer-environment.md
+++ b/for-developers/setting-up-developer-environment.md
@@ -21,7 +21,8 @@ three platforms.
For module development you may be able to skip step 5, below, "Enabling USB on
Unix". Instead simply install Companion according to the instructions in the
-getting started guide.
+getting started
+guide.
:::
diff --git a/src/css/custom.css b/src/css/custom.css
index e972fd5..d8b7cca 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -294,7 +294,7 @@
font-size: 1.25em;
}
-.markdown img {
+.markdown p > img:last-child {
display: block;
margin-left: auto;
margin-right: auto;
From 64e36936c731cd2766859ac182bf0f288769f6b5 Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Sat, 28 Feb 2026 23:57:27 -0800
Subject: [PATCH 08/12] fix improve css selector
(sync with PR #40)
Using p > img (suggested in PR #42) leads to too many edge-cases that fail. For example, if the image is clickable, i.e. inside ``. The following is more robust and still overrideable by adding an element after it (such as ).
---
src/css/custom.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/css/custom.css b/src/css/custom.css
index d8b7cca..f9f46bf 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -294,7 +294,7 @@
font-size: 1.25em;
}
-.markdown p > img:last-child {
+.markdown img:last-child {
display: block;
margin-left: auto;
margin-right: auto;
From a92b5ed80510ff81c4bb09a22cc9cd06a595e58a Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Mon, 2 Mar 2026 15:48:23 -0800
Subject: [PATCH 09/12] fix reflow merged files
---
.../module-development/api-changes/v2.0.md | 3 ++-
.../connection-basics/variables.md | 13 ++++++++++---
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/for-developers/module-development/api-changes/v2.0.md b/for-developers/module-development/api-changes/v2.0.md
index e8c8a31..cc1b4b3 100644
--- a/for-developers/module-development/api-changes/v2.0.md
+++ b/for-developers/module-development/api-changes/v2.0.md
@@ -106,7 +106,8 @@ have missed.
### Updates to `setVariableDefinitions`
-To better match the other similar methods, `setVariableDefinitions` no longer expects an array of definitions, and instead expects an object
+To better match the other similar methods, `setVariableDefinitions` no longer
+expects an array of definitions, and instead expects an object
Before:
diff --git a/for-developers/module-development/connection-basics/variables.md b/for-developers/module-development/connection-basics/variables.md
index 789283e..c507e13 100644
--- a/for-developers/module-development/connection-basics/variables.md
+++ b/for-developers/module-development/connection-basics/variables.md
@@ -37,11 +37,17 @@ defined. It is not required to use this structure, but it keeps it more readable
than having everything in one file. More complex modules will likely want to
split the variable definitions into even more files/folders.
-The [TypeScript module template](https://github.com/bitfocus/companion-module-template-ts) includes a file `src/variables.ts`, which is where your variables should be defined. It is not required to use this structure, but it keeps it more readable than having everything in one file. More complex modules will likely want to split the variable definitions into even more files/folders.
+The
+[TypeScript module template](https://github.com/bitfocus/companion-module-template-ts)
+includes a file `src/variables.ts`, which is where your variables should be
+defined. It is not required to use this structure, but it keeps it more readable
+than having everything in one file. More complex modules will likely want to
+split the variable definitions into even more files/folders.
### API 2.x
-All the variable definitions are passed in as a single JavaScript object, in the form of:
+All the variable definitions are passed in as a single JavaScript object, in the
+form of:
```js
const definitions = {
@@ -59,7 +65,8 @@ VariableId must only use letters [a-zA-Z], numbers, underscore, hyphen.
### API 1.x
-All the variable definitions are passed in as a single JavaScript array, in the form of:
+All the variable definitions are passed in as a single JavaScript array, in the
+form of:
```js
const definitions = [
From 2764970a4a8b630ec7abdd25d7c7fcbd6b38a64f Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Mon, 2 Mar 2026 16:55:24 -0800
Subject: [PATCH 10/12] minor copy-edits after comparing this PR with main
Visually, all rendered pages are structurally identical in the browser. Exceptions are mainly due to intentionally removing incorrect line breaks or very minor copy-edits.
---
.../module-development/connection-basics/variables.md | 7 -------
for-developers/module-development/local-modules.md | 4 ++--
.../module-lifecycle/renaming-your-module.md | 2 +-
.../module-development/module-setup/typescript-config.md | 4 ++--
4 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/for-developers/module-development/connection-basics/variables.md b/for-developers/module-development/connection-basics/variables.md
index c507e13..34b63cd 100644
--- a/for-developers/module-development/connection-basics/variables.md
+++ b/for-developers/module-development/connection-basics/variables.md
@@ -37,13 +37,6 @@ defined. It is not required to use this structure, but it keeps it more readable
than having everything in one file. More complex modules will likely want to
split the variable definitions into even more files/folders.
-The
-[TypeScript module template](https://github.com/bitfocus/companion-module-template-ts)
-includes a file `src/variables.ts`, which is where your variables should be
-defined. It is not required to use this structure, but it keeps it more readable
-than having everything in one file. More complex modules will likely want to
-split the variable definitions into even more files/folders.
-
### API 2.x
All the variable definitions are passed in as a single JavaScript object, in the
diff --git a/for-developers/module-development/local-modules.md b/for-developers/module-development/local-modules.md
index 06e3e00..54534f2 100644
--- a/for-developers/module-development/local-modules.md
+++ b/for-developers/module-development/local-modules.md
@@ -16,10 +16,10 @@ module folder is specified as described below. Inside of this folder should be
one or more folders that use the following layouts, with each folder
corresponding to a different module.
-1. A git clone of a module from github This requires some additional setup, as
+1. **A git clone of a module from github**. This requires some additional setup, as
the module will need to be prepared with a `yarn install`, and for some, a
`yarn build`.
-2. Packaged output This is a folder that contains a `companion/manifest.json`,
+2. **Packaged output**. This is a folder that contains a `companion/manifest.json`,
`companion/HELP.md`, `package.json`, `main.js` (or another name), and
possibly a few other files. No extra work is needed for this to be loaded
diff --git a/for-developers/module-development/module-lifecycle/renaming-your-module.md b/for-developers/module-development/module-lifecycle/renaming-your-module.md
index ac1d16c..3aa711e 100644
--- a/for-developers/module-development/module-lifecycle/renaming-your-module.md
+++ b/for-developers/module-development/module-lifecycle/renaming-your-module.md
@@ -9,7 +9,7 @@ Occasionally you will need to rename a module, perhaps for example, to make the
name more inclusive as you add more devices, or the manufacturer releases a new
device.
-1. Ask in the module-development slack for approval on the new name This is so
+1. Ask in the module-development slack for approval on the new name. This is so
that we can be sure the new name conforms to our standard structure of
`companion-module-manufacturer-product` (or
`companion-module-manufacturer-protocol`).
diff --git a/for-developers/module-development/module-setup/typescript-config.md b/for-developers/module-development/module-setup/typescript-config.md
index 3683ad8..2b0f5fb 100644
--- a/for-developers/module-development/module-setup/typescript-config.md
+++ b/for-developers/module-development/module-setup/typescript-config.md
@@ -28,7 +28,7 @@ A typical _tsconfig.json_ file looks like:
"node_modules/**",
"src/**/*spec.ts",
"src/**/__tests__/*",
- "src/**/__mocks__/*",
+ "src/**/__mocks__/*"
],
"compilerOptions": {
"outDir": "./dist",
@@ -63,7 +63,7 @@ Our TypeScript template splits it into two files:
"node_modules/**",
"src/**/*spec.ts",
"src/**/__tests__/*",
- "src/**/__mocks__/*",
+ "src/**/__mocks__/*"
],
"compilerOptions": {
"outDir": "./dist",
From 88fb9520f436d1f60dc13c23199c236d911ff14f Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Mon, 2 Mar 2026 17:07:20 -0800
Subject: [PATCH 11/12] prettier
also fix code blocks marked as "jsonc" to just "json" so they format correctly
---
.../module-development/api-changes/v2.0.md | 13 +++++++----
.../module-development/local-modules.md | 11 +++++-----
.../module-setup/typescript-config.md | 22 +++++++++----------
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/for-developers/module-development/api-changes/v2.0.md b/for-developers/module-development/api-changes/v2.0.md
index e2d54e6..3f3bbe8 100644
--- a/for-developers/module-development/api-changes/v2.0.md
+++ b/for-developers/module-development/api-changes/v2.0.md
@@ -6,9 +6,12 @@ description:
TypeScript improvements).'
---
-This is a major series of changes — the first breaking changes since Companion 3.0, over three years in the making.
+This is a major series of changes — the first breaking changes since Companion
+3.0, over three years in the making.
-If you are not ready to tackle these changes, there is no rush. Many of the changes improve module functionality, but API 1.x remains fully supported and there are no plans to remove that support.
+If you are not ready to tackle these changes, there is no rush. Many of the
+changes improve module functionality, but API 1.x remains fully supported and
+there are no plans to remove that support.
## Required changes
@@ -39,9 +42,11 @@ JavaScript module.
### Minimum @companion-module/tools version
-In order to build your module correctly, you need to be using `@companion-module/tools` v2.7.1 or later
+In order to build your module correctly, you need to be using
+`@companion-module/tools` v2.7.1 or later
-We will soon be releasing a v3.0.0 which will optimise the build process further and should be a drop in replacement.
+We will soon be releasing a v3.0.0 which will optimise the build process further
+and should be a drop in replacement.
### Remove `runEntrypoint` method
diff --git a/for-developers/module-development/local-modules.md b/for-developers/module-development/local-modules.md
index 54534f2..ab4fbb3 100644
--- a/for-developers/module-development/local-modules.md
+++ b/for-developers/module-development/local-modules.md
@@ -16,12 +16,13 @@ module folder is specified as described below. Inside of this folder should be
one or more folders that use the following layouts, with each folder
corresponding to a different module.
-1. **A git clone of a module from github**. This requires some additional setup, as
- the module will need to be prepared with a `yarn install`, and for some, a
+1. **A git clone of a module from github**. This requires some additional setup,
+ as the module will need to be prepared with a `yarn install`, and for some, a
`yarn build`.
-2. **Packaged output**. This is a folder that contains a `companion/manifest.json`,
- `companion/HELP.md`, `package.json`, `main.js` (or another name), and
- possibly a few other files. No extra work is needed for this to be loaded
+2. **Packaged output**. This is a folder that contains a
+ `companion/manifest.json`, `companion/HELP.md`, `package.json`, `main.js` (or
+ another name), and possibly a few other files. No extra work is needed for
+ this to be loaded
## Set up a developer folder
diff --git a/for-developers/module-development/module-setup/typescript-config.md b/for-developers/module-development/module-setup/typescript-config.md
index 2b0f5fb..5d33423 100644
--- a/for-developers/module-development/module-setup/typescript-config.md
+++ b/for-developers/module-development/module-setup/typescript-config.md
@@ -20,7 +20,7 @@ the name of the source or destination directories.
A typical _tsconfig.json_ file looks like:
-```jsonc
+```json
{
"extends": "@companion-module/tools/tsconfig/node22/recommended",
"include": ["src/**/*.ts"],
@@ -34,27 +34,27 @@ A typical _tsconfig.json_ file looks like:
"outDir": "./dist",
"baseUrl": "./",
"paths": {
- "*": ["./node_modules/*"],
- },
- },
+ "*": ["./node_modules/*"]
+ }
+ }
}
```
Our TypeScript template splits it into two files:
-```jsonc
+```json
//tsconfig.json
{
"extends": "./tsconfig.build.json",
"include": ["src/**/*.ts"],
"exclude": ["node_modules/**"],
"compilerOptions": {
- "types": ["node"],
- },
+ "types": ["node"]
+ }
}
```
-```jsonc
+```json
// tsconfig.build.json
{
"extends": "@companion-module/tools/tsconfig/node22/recommended",
@@ -69,11 +69,11 @@ Our TypeScript template splits it into two files:
"outDir": "./dist",
"baseUrl": "./",
"paths": {
- "*": ["./node_modules/*"],
+ "*": ["./node_modules/*"]
},
"module": "Node16",
- "moduleResolution": "Node16",
- },
+ "moduleResolution": "Node16"
+ }
}
```
From c55835c37abcb6c5b8133772c70df7d3832759f8 Mon Sep 17 00:00:00 2001
From: Ari Kornfeld
Date: Mon, 2 Mar 2026 18:41:42 -0800
Subject: [PATCH 12/12] fix: clean up variables syntax, hopefully
---
.../connection-basics/variables.md | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/for-developers/module-development/connection-basics/variables.md b/for-developers/module-development/connection-basics/variables.md
index 34b63cd..ad652bd 100644
--- a/for-developers/module-development/connection-basics/variables.md
+++ b/for-developers/module-development/connection-basics/variables.md
@@ -16,9 +16,10 @@ are defined by the module InstanceBase class.
## API call: `setVariableDefinitions()`
Your module should define the list of variables it exposes by making a call to
-`this.setVariableDefinitions([ ...some variables here... ])`. You will need to
-do this as part of your `init()` method, but can also call it at any other time
-if you wish to change the list of variables exposed.
+`this.setVariableDefinitions(...some variables here...)` -- the exact format
+depends on the module API you are using; see below. You will need to do this as
+part of your `init()` method, but can also call it at any other time if you wish
+to change the list of variables exposed.
:::warning
@@ -39,8 +40,8 @@ split the variable definitions into even more files/folders.
### API 2.x
-All the variable definitions are passed in as a single JavaScript object, in the
-form of:
+All the variable definitions are passed in as a single JavaScript _object_, in
+the form of:
```js
const definitions = {
@@ -58,8 +59,8 @@ VariableId must only use letters [a-zA-Z], numbers, underscore, hyphen.
### API 1.x
-All the variable definitions are passed in as a single JavaScript array, in the
-form of:
+All the variable definitions are passed in as a single JavaScript _array_, in
+the form of:
```js
const definitions = [