Skip to content

Commit eb9b5ce

Browse files
authored
Merge pull request #41 from Flow-Launcher/add_nodejs_guide
Add Node.js plugin guide
2 parents d8b13ed + ec6d0ae commit eb9b5ce

File tree

6 files changed

+159
-0
lines changed

6 files changed

+159
-0
lines changed

_sidebar.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
- [**Write the code**](/py-write-code.md)
1313
- [**Add your plugin to Flow**](/py-release-project.md)
1414
- [**Plugin references**](/py-plugin-references.md)
15+
- JavaScript/TypeScript Plugins
16+
- [**Before you start**](/nodejs-develop-plugins.md)
17+
- [**Set up your project**](/nodejs-setup-project.md)
18+
- [**Write the code**](/nodejs-write-code.md)
19+
- [**Add your plugin to Flow**](/nodejs-release-project.md)
1520
- JSONRPC
1621
- [**JSON RPC Introduction**](/json-rpc.md)
1722
- [**Porting Plugins**](/port-plugins.md)

nodejs-develop-plugins.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### About Flow's TypeScript/JavaScript plugins
2+
3+
Plugins written in TypeScript/JavaScript use the [JSON-RPC](https://flow-launcher.github.io/docs/#/json-rpc) protocol to communicate with Flow via JSON structured calls.
4+
5+
Although not a hard requirement, this guide will use Node.js to run the TypeScript/JavaScript. We will refere to TypeScript/JavaScript plugin as Node.js plugin from here on.
6+
7+
When building a Node.js plugins there are several things to be mindful of:
8+
9+
* The most important thing is we do not expect users to have to manually install the dependencies via npm because we aim to provide a seamless experience for them. This can be achieved by adding the following three things to your project:
10+
1. Add a GitHub workflow- use a GitHub workflow that will install all your plugin's depedencies including the modules inside a folder called 'node_modules'.
11+
2. Publish all as a zip- zip up your project including a lib directory that contains the modules and publish it to GitHub Releases page.
12+
3. Point your module path to the node_modules directory- reference all the modules to that directory.
13+
14+
* Currently we will require users to install Node.js on the computer in order to use the plugin, so you will need to explain how to do so in your plugin readme.
15+
16+
### Simple Example
17+
Have a look at this simple example plugin [here](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldNodeJS), notice it has a folder called '.github/workflows' and a file called 'Publish Release.yml'. This is the workflow file that GitHub Workflow uses to run the CICD for the project. Moving out of that folder you can go into the [main.js](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldNodeJS/blob/main/main.js) file, this is the entry file for your plugin.

nodejs-release-project.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
### Release your plugin to Flow's Plugin Store
2+
When you are ready to release your plugin for people to enjoy, simply head over to Flow's [plugin repo](https://github.com/Flow-Launcher/Flow.Launcher.PluginsManifest) and follow the instructions there in the readme.

nodejs-setup-project.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
### 1. Add GitHub workflow
2+
The workflow [file](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldNodeJS/blob/main/.github/workflows/Publish%20Release.yml) will help build and deploy your project, it does the following things:
3+
1. `workflow_dispatch:` gives you the option to manually run your workflow from the Actions section of your project
4+
5+
2. On pushes to main, it will kick off the workflow but ignore the push if it's only changes made to the workflow file.
6+
7+
```yml
8+
push:
9+
branches: [ main ]
10+
paths-ignore:
11+
- .github/workflows/*
12+
```
13+
14+
3. It specifies the Node.js version that will be used for building your project:
15+
16+
```yml
17+
- name: Set up Node.Js
18+
uses: actions/setup-node@v2
19+
with:
20+
node-version: '17.3.0'
21+
```
22+
23+
4. The project's release version is obtained from your plugin.json automatically by the ci, so when built it will be appended to the zip file later:
24+
25+
```yml
26+
- name: get version
27+
id: version
28+
uses: notiz-dev/github-action-json-property@release
29+
with:
30+
path: 'plugin.json'
31+
prop_path: 'Version'
32+
```
33+
34+
5. The 'Install dependencies' section is where you will do most of your CI work. It will run `npm install`, which will output all the dependencies specified in package.json into the 'node_modules' directory. The workflow will then zip them up along with your project using `zip -r Flow.Launcher.Plugin.HelloWorldNodeJS.zip . -x '*.git*'`, where you replace this `Flow.Launcher.Plugin.HelloWorldNodeJS` with the name of your plugin.
35+
36+
```yml
37+
- name: Install dependencies
38+
run: |
39+
npm install
40+
zip -r Flow.Launcher.Plugin.HelloWorldNodeJS.zip . -x '*.git*'
41+
```
42+
43+
### 2. Publish as zip
44+
The final step to the workflow file is this publish section, which will publish the zip file you generated, upload to GitHub Releases page and tag with the version generated from the previous step from your plugin.json file. Remember again to replace `Flow.Launcher.Plugin.HelloWorldNodeJS` with the name of your plugin.
45+
46+
```yml
47+
- name: Publish
48+
uses: softprops/action-gh-release@v1
49+
with:
50+
files: 'Flow.Launcher.Plugin.HelloWorldNodeJS.zip'
51+
tag_name: "v${{steps.version.outputs.prop}}"
52+
env:
53+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
```
55+
56+
Feel free to also have a read of this [blog post](https://blog.ipswitch.com/how-to-build-your-first-github-actions-workflow) which does a simple explaination of how to use GitHub Actions Workflow.
57+
58+
### 3. Use node_modules directory
59+
Once the 'node_modules' folder is included in your zip release, it can then be used without needing the user to manually npm install the plugin's dependencies. You just have to tell the plugin during runtime to find those modules in your local node_modules directory. Do this by using this exact copy of the following block of code in your [main.js](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldNodeJS/blob/main/main.js):
60+
```javascript
61+
const open = require('./node_modules/open')
62+
```

nodejs-write-code.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
### 1. Start with a branch
2+
Since we have created a CI for your plugin in the [previous step](https://flow-launcher.github.io/docs/#/py-setup-project), which includes creating a release when you push/merge to the 'main' branch, it is then neccessary to create another git branch separate to your 'main' branch so you can continue to work on your plugin with git commits and pushes without creating a new release each time.
3+
4+
It is a good practice that you create a branch for each of the new feature/fixes you are releasing for your plugin, if you are not sure how to do so then follow this [video tutorial](https://www.gitkraken.com/learn/git/problems/create-git-branch). Once you have fully finished developing your plugin with your new branch, then you can merge it into the 'main' branch, which will consequently create a new release for your plugin with a version from your `plugin.json`.
5+
6+
### 2. main.py
7+
your main.js should look something like below:
8+
```
9+
const open = require('./node_modules/open')
10+
11+
const { method, parameters } = JSON.parse(process.argv[2])
12+
13+
if (method === "query") {
14+
console.log(JSON.stringify(
15+
{
16+
"result": [{
17+
"Title": "Hello World Typescript",
18+
"Subtitle": "Showing your query parameters: " + parameters + ". Click to open Flow's website",
19+
"JsonRPCAction": {
20+
"method": "do_something_for_query",
21+
"parameters": ["https://github.com/Flow-Launcher/Flow.Launcher"]
22+
},
23+
"IcoPath": "Images\\app.png"
24+
}]
25+
}
26+
));
27+
}
28+
29+
if (method === "do_something_for_query") {
30+
url = parameters[0]
31+
do_something_for_query(url)
32+
}
33+
34+
function do_something_for_query(url) {
35+
open(url);
36+
}
37+
```
38+
39+
<br/>
40+
41+
### 3. Query entry point
42+
**if (method === "query")**
43+
44+
This if statement captures the args passed viar JsonRPC defined as `const { method, parameters } = JSON.parse(process.argv[2])`, so if 'method' is 'query' then the console.log's code block will be run. As result is an array, you can also specify a single or multiple results.
45+
46+
### 4. Assigning an action to your results
47+
**JsonRPCAction**
48+
49+
This is where you specify the method that will be executed when the user selects on the result.
50+
In this example, if the user selects the result, the `do_something_for_query` method will be called with the url parameter which opens the Flow Launcher GitHub repo.
51+
52+
### 5. node.bat
53+
The [node.bat](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldNodeJS/blob/main/node.bat) file is the entry Flow uses to call main.js, it will set the working directory to the plugin's own location before calling main.js with node.
54+
```
55+
@echo off
56+
SET plugin_dir=%~dp0%
57+
node %plugin_dir%/main.js %*
58+
```
59+
60+
### 6. Your plugin.json
61+
You will also need to if not yet already, create a plugin.json file that will instruct Flow on how to load your plugin.
62+
63+
This file should be placed in the top level folder.
64+
65+
To revisit what to include in your plugin.json, visit [here](https://flow-launcher.github.io/docs/#/plugin.json)

py-setup-project.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
### 1. Add GitHub workflow
22
The workflow [file](https://github.com/Flow-Launcher/Flow.Launcher.Plugin.HelloWorldPython/blob/main/.github/workflows/Publish%20Release.yml) will help build and deploy your project, it does the following things:
33
1. `workflow_dispatch:` gives you the option to manually run your workflow from the Actions section of your project
4+
45
2. On pushes to main, it will kick off the workflow but ignore the push if it's only changes made to the workflow file.
6+
57
```yml
68
push:
79
branches: [ main ]
810
paths-ignore:
911
- .github/workflows/*
1012
```
13+
1114
3. It specifies the python version that will be used for building your project:
15+
1216
```yml
1317
env:
1418
python_ver: 3.8
1519
```
20+
1621
4. The project's release version is obtained from your plugin.json automatically by the ci, so when built it will be appended to the zip file later:
22+
1723
```yml
1824
- name: get version
1925
id: version
@@ -22,9 +28,11 @@ push:
2228
path: 'plugin.json'
2329
prop_path: 'Version'
2430
```
31+
2532
5. The 'Install dependencies' section is where you will do most of your CI work. Notice it installs the requirements.txt and outputs it with the `-t` parameter to the `./lib` folder. This tells pip to dump all the installed modules to the local lib folder which you will zip up along with your project using the `zip -r Flow.Launcher.Plugin.HelloWorldPython.zip . -x '*.git*'`, where you replace this `Flow.Launcher.Plugin.HelloWorldPython` with the name of your plugin.
2633

2734
You can also add additional steps here to unpack/install any additional depedencies your plugin requires, for example compiling additional translation files like [this](https://github.com/deefrawley/Flow.Launcher.Plugin.Currency/blob/23770ee929af059b1b1b7f9b5f3327b692ac9587/.github/workflows/Publish%20Release.yml#L34)
35+
2836
```yml
2937
- name: Install dependencies
3038
run: |

0 commit comments

Comments
 (0)