open-index/open-npm huggingface dataset:
npm package: @homelabsio/wgctrl
Description: WireGuard Control API for Node.js
Author: troopert
Latest version: 0.0.2

# wgctrl-js
[![npm Version][NPM VERSION BADGE]][NPM PAGE]
[![Node.js][NODE VERSION BADGE]][NODE PAGE]
[![GitHub License][LICENSE BADGE]][LICENSE PAGE]
[![CI Status][CI BADGE]][CI PAGE]

Wireguard control API for Node.js

# Install

```sh
npm install @homelabsio/wgctrl
```

# Runtime Requirements
@homelabsio/wgctrl performs various network configuration tasks which require that the node process either:
* be executing as root [NOT PREFERRED]  
*OR*
* have CAP_NET_ADMIN [PREFERRED]

# Usage

### Modify existing Wireguard device

```typescript
import { Peer, Device, getDevices, getDevice, setDevice } from '@homelabsio/wgctrl';

// Get array of current WireGuard devices
let devs: string[] = getDevices();
console.log (devs); // [ 'wg0', 'wg1', 'wg2' ]

const wg0: Device = getDevice('');
let newPeer: Peer = new Peer('BCBqOfgqPK2RQO+z1QPYHvlxcOG41m2385dvjJcj5mE=');
newPeer.endpoint = "203.0.113.0:51820";
newPeer.presharedKey = "QJa8/fxAxEZtbaWrQ1UOrkGc2Gzx+O/DbhYzYcICPew=";
newPeer.persistentKeepaliveInterval = 25;
newPeer.addAllowedIP("198.19.254.250/32");
newPeer.addAllowedIP("198.19.254.252");
wg.addPeer(newPeer);

setDevice(wg0);
```

# Testing
```sh
npm run format
npm run lint
npm run test
```

# See Also
- TODO

# Legal
@homelabsio/wgctrl is licensed under the terms of the MIT License. See the [license file](LICENSE) for details.

[CI BADGE]: https://github.com/homelabsio/wgctrl-js/actions/workflows/ci.yaml/badge.svg
[CI PAGE]: https://github.com/homelabsio/wgctrl-js/actions/workflows/ci.yaml
[LICENSE BADGE]: https://img.shields.io/badge/license-MIT%20License-blue.svg?style=flat
[LICENSE PAGE]: https://github.com/homelabsio/wgctrl-js/blob/master/LICENSE
[NODE PAGE]: https://nodejs.org/
[NODE VERSION BADGE]: https://img.shields.io/node/v/@homelabsio/wgctrl.svg?style=flat
[NPM PAGE]: https://www.npmjs.com/package/@homelabsio/wgctrl
[NPM VERSION BADGE]: https://img.shields.io/npm/v/@homelabsio/wgctrl.svg?style=flat
[NPM KEYWORDS BADGE]: https://img.shields.io/github/package-json/keywords/homelabsio/wgctrl.svg?style=flat
npm package: @homenet/core
Description: Homenet home automation - core system
Author: Den Williams
Latest version: 4.0.0-beta.42

# Homenet Core

Home automation system tightly coupled with [Node RED](https://nodered.org) intended for those who like to write their own code.

I'm not a fan of complex web and app interfaces, so the approach is more of a hands off - triggers are automatic or via sensors or buttons. There is an Android tablet app in the works that uses multi-finger gestures to control things. Ideally I'd like to integrate with voice control when that becomes feasible.

## Powerful Rules

- Uses [Node RED](https://nodered.org) for rule system. Much more powerful than the IFTTT style rules used by others.
- Infinite number of "scenes". Each scene is like a clean slate of rules. When the scene changes, so do the Node RED flows. For example have a "day" and "night" scene, one for when you're "away" from home, one for when you're watching "movies", one for when you're "entertaining".
- Common tabs - any Node RED tab that starts with the word "Common" is available in every scene. No need to repeat rules that you always want available.
- [Custom Node RED nodes](https://www.npmjs.com/package/@homenet/nodes) are provided for tighter integration with core.

## Pluggable Architecture

Core relies on plugins to communicate with external devices and services.

- Core plugins can easily be written in Javascript or Typescript (or any other language that compiles to Javascript such as Coffeescript).
- Core plugins are discovered automatically if installed globally via NPM.
- Any Node RED plugin can also be used within the rule systems (although they will not be controllable via the HTTP API).

## API

External applications can interact and control devices via the HTTP APIs. There is both a REST and GraphQL API.

## Documentation

[Click here to view documentation](http://www.denwilliams.net/homenet-core/)

## Installing and Running

The best way to use now is to install globally:

```
npm install -g @homenet/core node-red-contrib-scenes
```

Then to run:

```
homenet4 /path/to/my/config.json
```

## Adding Plugins

> [Search for plugins on NPM](https://www.npmjs.com/search?q=homenet4-plugin)

`homenet-core` doesn't do much without plugins. Install plugins globally and they will be automatically discovered. Eg:

```
npm install -g @homenet/plugin-hue
```

Plugins are discovered by searching global and local `node_modules` for modules with the keyword `homenet4-plugin`.

example `package.json`:

```json
{
    "keywords": [
        "homenet4-plugin"
    ],
    "homenet4": {
        "plugins": [
            "MyPluginLoader"
        ]
    }
}
```

## Using as a Module

It is also possible to use as an NPM module inside a project. Docs TBD.

## Developer Help

### Clone and Build Locally

Build using Typescript 2.

```
git clone git@github.com:denwilliams/homenet-core.git
cd homenet-core
npm install
npm install -g typescript
tsc
```

### Building Docs Locally

```
npm install -g typedoc
npm run typedoc
```

### Running Tests

```
npm test
```

or

```
node_modules/.bin/ava
```
npm package: @homenet/plugin-flic
Description: Flic button plugin for Homenet
Author: Den Williams
Latest version: 2.0.0

# homenet-plugin-flic
Flic plugin for Homenet

Requires a [Flic server](https://github.com/50ButtonsEach/fliclib-linux-hci) to connect to.\

[See Homenet](https://www.npmjs.com/package/homenet-core)
npm package: @homenet/plugin-hue
Description: Philips Hue plugin for Homenet
Author: Den Williams
Latest version: 2.0.1

# homenet-plugin-hue
Philips Hue plugin for [Homenet](http://www.denwilliams.net/homenet-core/)

> Requires `homenet-core` version `4.0.0-beta.15` or above.

## Installing

```
npm install -g homenet-hue
```

## Usage

Once installed globally it should be automatically discovered when you run `homenet4`.

## Configuration

In the configuration file create a `hue.hubs` key and register each Hue hub/controller.

> Note: at present

```json
{
  "hue": {
    "hubs": [
      { "id": "main", "name": "Main", "host": "192.168.0.123", "key": "valid_hue_api_key" }
    ]
  }
}
```

## Classes

Only the light class for Homenet is implemented.

To add an instance use the type `hue`.

For options specify the Hue `groupId` or `lightId` (should be an integer), and the ID of the hub registered above.

```json
{
  "instances": [
    { "class": "light", "id": "lounge-room", "type": "hue", "options": { "groupId": 3, "hub": "main" } }
  ]
}
```

## Example Config

```json
{
  "instances": [
    { "class": "light", "id": "lounge-room", "type": "hue", "options": { "groupId": 3, "hub": "main" } }
  ],
  "hue": {
    "hubs": [
      { "id": "main", "name": "Main", "host": "192.168.0.123", "key": "valid_hue_api_key" }
    ]
  }
}
```
npm package: @homenet/plugin-zway
Description: Homenet plugin for Z-Way connected Z-Wave devices
Author: Den Williams
Latest version: 2.1.2

# homenet-plugin-zway
Z-Way plugin for controlling Z-Wave devices through a Z-Way controller.

Note: currently only supports locks, and only tested on a Yale lock (other locks might work slightly differently).
Sensors and binary switches coming soon.

## Registering the Plugin

Use the `loadPlugin` method on the core runtime:

```js
const core = require('@homenet/core');
const zwayPlugin = require('@homenet/plugin-zway');
const runtime = core.init(RED, myConfig);
runtime.loadPlugin(zwayPlugin.ZwayPluginLoader);
runtime.start();
```

## Configuration

In the configuration file create a `zway.controllers` key and register each Z-Way controller:

```json
{
  "zway": {
    "controllers": [
      { "id": "main", "host": "192.168.0.123", "port": 8083, "user": "admin", "password": "mysecretpasswd" }
    ]
  }
}
```

## Classes

Currently only the lock class for Homenet is implemented.

To add an instance use the type `zway`.

For options specify the Z-Way `deviceId` (should be an integer), and the ID of the `controller` registered above.

```json
{
  "instances": [
    { "class": "lock", "id": "front-door", "type": "zway", "options": { "deviceId": 3, "controller": "main" } }
  ]
}
```

## Example Config

```json
{
  "instances": [
    { "class": "lock", "id": "front-door", "type": "zway", "options": { "deviceId": 3, "controller": "main" } }
  ],
  "zway": {
    "controllers": [
      { "id": "main", "host": "192.168.0.123", "port": 8083, "user": "admin", "password": "mysecretpasswd" }
    ]
  }
}
```
npm package: @homeofthings/node-sys
Description: HomeOfThings - fluent API for spawning child processes and shell-like filesystem function
Author: Guenter Sandner
Latest version: 1.0.5

[![npm version](https://badge.fury.io/js/%40homeofthings%2Fnode-sys.svg)](https://badge.fury.io/js/%40homeofthings%2Fnode-sys)
[![Build Workflow](https://github.com/gms1/HomeOfThings/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/gms1/HomeOfThings/actions/workflows/build.yml)
[![Coverage Status](https://codecov.io/gh/gms1/HomeOfThings/branch/master/graph/badge.svg?flag=node-sys)](https://app.codecov.io/gh/gms1/HomeOfThings/tree/master/packages%2Fnode%2F%40homeofthings%2Fnode-sys)
[![DeepScan grade](https://deepscan.io/api/teams/439/projects/987/branches/1954/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=439&pid=987&bid=1954)
[![Known Vulnerabilities](https://snyk.io/test/github/gms1/HomeOfThings/badge.svg)](https://snyk.io/test/github/gms1/HomeOfThings)

[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![License](https://img.shields.io/npm/l/@homeofthings/node-sys.svg?style=flat-square)](https://github.com/gms1/HomeOfThings/blob/master/packages/node/@homeofthings/node-sys/LICENSE)

# @homeofthings/node-sys

This library is mainly intended to be helpful for build and installation tasks. It includes a Fluent API for spawning child processes and many file-system related functions that work and are named similarly to their shell counterparts.

## Fluent API for spawning child processes

```Typescript
const out: string[] = [];
await exec('node', '-e', `console.log("hello world")`).setStdOut(out).run();
```

```Typescript
const script: string[] = [`console.log("hello world")`];
await exec('node').setStdIn(script).run();
```

```Typescript
const out: string[] = [];
await sh('ls -l *.md').setStdOut(out).run();
```

```Typescript
const out: string[] = [];
await pipe(sh('ls -l *.md')).to(exec('wc', '-l').setStdOut(out)).run();
// out[0] contains the number of *.md files as string
```

## file-system related functions

file-system related functions that work and are named similarly to their shell counterparts, e.g.:
cd, pwd, pushd, popd, dirs, realpath, stat, which, unlink, ln, mktemp, chmod, chown, mkdir, rm, rmdir, touch, cp, mv, rename, ...

```Typescript
await rm('myfile.bak');
await rm(['myfile.bak', 'mytmpdir'], { recursive: true, force: true });
await rm(glob('**/*.bak'));
```
npm package: @homer0/deferred
Description: Small utility to create a deferred promise
Author: Leonardo Apiwan
Latest version: 5.0.8

# 🕗 Deferred

Small utility to create a deferred promise

## 🍿 Usage

- ⚙️ [Examples](#%EF%B8%8F-examples)
- 🤘 [Development](#-development)

### ⚙️ Examples

Using it is really simple, you call the `deferred()` function and get an object with `promise`, `resolve` and `reject`. You return the `promise` property and, eventually, call `resolve` or `reject` to either resolve the promise or reject it.

Now, a reason to use this is for when you have another service/function/something asking for something that your code hasn't even started to do:

```ts
import * as fs from 'fs/promises';
import { deferred, type DeferredPromise } from '@homer0/deferred';

class MyServiceThatLoadsAfile {
  private defer: DeferredPromise<string>;
  private file: string;

  constructor() {
    this.defer = deferred();
  }

  getFileContents(): Promise<string> {
    if (this.file) return Promise.resolve(this.file);
    return this.defer.promise;
  }

  async loadTheFile(): Promise<void> {
    try {
      this.file = await fs.readFile('some-path', 'utf-8');
      this.defer.resolve(this.file);
    } catch (err) {
      this.defer.reject(err);
    }
  }
}

const myService = new MyServiceThatLoadsAfile();
myService.getFileContents().then((contents) => {
  console.log('GOT IT', contents);
});

// ...
myService.loadTheFile();
```

Ok, there's a lot going on this example, so let's break it:

1. `MyServiceThatLoadsAFile` creates a deferred promise on its constructor.
2. `getFileContents` should return the file contents, but because the file is not loaded yet (as `loadTheFile` has not been called), it returns the deferred promise.
3. Eventually, `loadTheFile` gets called, it loads the file and either resolves or rejects the deferred promise, so the `getFileContents().then(...)` (or `catch` :P) gets finally called.

I wanted to keep the example small, but on a real app, `getFileContents` is probably called by other service that has no idea the instance was just created or that `loadTheFile` hasn't been called yet.

### 🤘 Development

As this project is part of the `packages` monorepo, some of the tooling, like `lint-staged` and `husky`, are installed on the root's `package.json`.

#### Tasks

| Task          | Description                         |
| ------------- | ----------------------------------- |
| `lint`        | Lints the package.                  |
| `test`        | Runs the unit tests.                |
| `build`       | Transpiles and bundles the project. |
| `types:check` | Validates the TypeScript types.     |
npm package: @homer0/package-info
Description: Gets the content of the project's package.json
Author: Leonardo Apiwan
Latest version: 5.0.8

# 📦 Package info

A tiny service that reads the contents of the project's `package.json`, sync & async.

## 🍿 Usage

> ⚠️ **This package is only for Node**.

- ⚙️ [Examples](#%EF%B8%8F-examples)
- 🤘 [Development](#-development)

### ⚙️ Example

```ts
import { packageInfo } from '@homer0/package-info';

const pkg = packageInfo();

// ...

const info = await pkg.get();
// or
const info = pkg.getSync();
```

#### Jimple provider

If your app uses a [Jimple container](https://npmjs.com/package/jimple), you can register `PackageInfo` as the `packageInfo` service by using its provider:

```ts
import { packageInfoProvider } from '@homer0/package-info';

// ...

container.register(packageInfoProvider);

// ...

const info = container.get('packageInfo');
```

And since the provider is a "provider creator" (created with [my custom version of Jimple](https:///npmjs.com/package/@homer0/jimple)), you can customize its service name:

```ts
container.register(
  packageInfoProvider({
    serviceName: 'myPackageInfo',
  }),
);
```

##### Dependencies

`PackageInfo` depends on the following services, and when used with Jimple, it will try to find them in the container, otherwise, it will create new instances:

- [`@homer0/path-utils`](https://npmjs.com/package/@homer0/path-utils), with the name `pathUtils`. Used to generate the paths relative to the project root.

If you already implement the dependencies, but with a different name, you can specify them in the provider:

```ts
container.register(
  packageInfoProvider({
    services: {
      pathUtils: 'myPathUtils',
    },
  }),
);
```

### 🤘 Development

As this project is part of the `packages` monorepo, some of the tooling, like `lint-staged` and `husky`, are installed on the root's `package.json`.

#### Tasks

| Task          | Description                     |
| ------------- | ------------------------------- |
| `lint`        | Lints the package.              |
| `test`        | Runs the unit tests.            |
| `build`       | Transpiles the project.         |
| `types:check` | Validates the TypeScript types. |
npm package: @homer0/root-file
Description: Import or require a file for the project root
Author: Leonardo Apiwan
Latest version: 5.0.8

# ⚓️ Root file

Import or require a file for the project root.

## 🍿 Usage

> ⚠️ **This package is only for Node**.

- ⚙️ [Examples](#%EF%B8%8F-examples)
- 🤘 [Development](#-development)

### ⚙️ Example

```ts
import { rootFile } from '@homer0/root-file';

const root = rootFile();

// ...

const info = await root.import('some-file.js');
// or
const info = root.require('some-file.js');
```

#### Jimple provider

If your app uses a [Jimple container](https://npmjs.com/package/jimple), you can register `RootFile` as the `rootFile` service by using its provider:

```ts
import { rootFileProvider } from '@homer0/root-file';

// ...

container.register(rootFileProvider);

// ...

const env = container.get('rootFile');
```

And since the provider is a "provider creator" (created with [my custom version of Jimple](https:///npmjs.com/package/@homer0/jimple)), you can customize its service name:

```ts
container.register(
  rootFileProvider({
    serviceName: 'myRootFile',
  }),
);
```

##### Dependencies

`RootFile` depends on the following services, and when used with Jimple, it will try to find them in the container, otherwise, it will create new instances:

- [`@homer0/path-utils`](https://npmjs.com/package/@homer0/path-utils), with the name `pathUtils`. Used to generate the paths relative to the project root.

If you already implement the dependencies, but with a different name, you can specify them in the provider:

```ts
container.register(
  rootFileProvider({
    services: {
      pathUtils: 'myPathUtils',
    },
  }),
);
```

### 🤘 Development

As this project is part of the `packages` monorepo, some of the tooling, like `lint-staged` and `husky`, are installed on the root's `package.json`.

#### Tasks

| Task          | Description                     |
| ------------- | ------------------------------- |
| `lint`        | Lints the package.              |
| `test`        | Runs the unit tests.            |
| `build`       | Transpiles the project.         |
| `types:check` | Validates the TypeScript types. |
npm package: @homer0/ts-async-import
Description: Small utility to dynamically import ESM modules in CJS with TS
Author: Leonardo Apiwan
Latest version: 3.0.8

# ☢️ TS Async Import

A wrapper to do dynamic imports in TypeScript contexts that target CommonJS.

## 🍿 Usage

> ⚠️ **Don't use this package if you are targeting ES modules**.

- ⚙️ [Examples](#%EF%B8%8F-examples)
- 🤘 [Development](#-development)

### ⚙️ Examples

```ts
import { tsAsyncImport } from '@homer0/ts-async-import';

// ...

const { default: nodeFetch } =
  await tsAsyncImport<typeof import('node-fetch')>('node-fetch');
```

That's it, the only difference between this and a regular `import` is that you need to specify the type of the module you are importing.

And, if for some reason, you want to specify the context path for the import, you can do it with the second parameter:

```ts
import { tsAsyncImport } from '@homer0/ts-async-import';

// ...

const { default: nodeFetch } = await tsAsyncImport<typeof import('node-fetch')>(
  'node-fetch',
  __dirname,
);
```

### 🤘 Development

As this project is part of the `packages` monorepo, some of the tooling, like `lint-staged` and `husky`, are installed on the root's `package.json`.

#### Tasks

| Task          | Description                     |
| ------------- | ------------------------------- |
| `lint`        | Lints the package.              |
| `test`        | Runs the unit tests.            |
| `types:check` | Validates the TypeScript types. |

## Motivation

I didn't want to have to change my `tsconfig.json` just to prevent TS to transform the two `import`s I have into `require`s 🤬.