From a76bfa58d235f07142733e24b8018d29886d6d8c Mon Sep 17 00:00:00 2001 From: SteffoSpieler Date: Wed, 11 Sep 2024 21:39:08 +0200 Subject: [PATCH 1/3] feat(pishock): Add pishock service --- package-lock.json | 56 ++++++++++++++-- samples/pishock/extension/index.ts | 24 +++++++ samples/pishock/package.json | 20 ++++++ samples/pishock/tsconfig.json | 11 ++++ services/nodecg-io-pishock/extension/index.ts | 65 +++++++++++++++++++ services/nodecg-io-pishock/package.json | 50 ++++++++++++++ services/nodecg-io-pishock/schema.json | 33 ++++++++++ services/nodecg-io-pishock/tsconfig.json | 8 +++ 8 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 samples/pishock/extension/index.ts create mode 100644 samples/pishock/package.json create mode 100644 samples/pishock/tsconfig.json create mode 100644 services/nodecg-io-pishock/extension/index.ts create mode 100644 services/nodecg-io-pishock/package.json create mode 100644 services/nodecg-io-pishock/schema.json create mode 100644 services/nodecg-io-pishock/tsconfig.json diff --git a/package-lock.json b/package-lock.json index 55c81dced..469db3b4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4058,11 +4058,11 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -6162,9 +6162,9 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -9660,6 +9660,10 @@ "resolved": "services/nodecg-io-philipshue", "link": true }, + "node_modules/nodecg-io-pishock": { + "resolved": "services/nodecg-io-pishock", + "link": true + }, "node_modules/nodecg-io-rcon": { "resolved": "services/nodecg-io-rcon", "link": true @@ -10339,6 +10343,18 @@ "node": ">= 6" } }, + "node_modules/pishock": { + "resolved": "samples/pishock", + "link": true + }, + "node_modules/pishock-ts": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pishock-ts/-/pishock-ts-1.0.1.tgz", + "integrity": "sha512-WbcQS+CQm7Iw9xK2kVQ3pSnyJ2UcYdoxmD9JaXiKFxhcJzkdauKuad5vyrtPqpV9h1R2mlHr6LctKuTrDaMSAw==", + "dependencies": { + "axios": "^1.7.7" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "dev": true, @@ -12999,6 +13015,18 @@ "typescript": "^5.4.3" } }, + "samples/pishock": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "@nodecg/types": "^2.1.12", + "@types/node": "^20.12.2", + "nodecg-io-core": "^0.3.0", + "nodecg-io-pishock": "^0.3.0", + "nodecg-io-tsconfig": "^1.0.0", + "typescript": "^5.4.3" + } + }, "samples/rcon-minecraft": { "version": "0.3.0", "license": "MIT", @@ -13644,6 +13672,20 @@ "typescript": "^5.4.3" } }, + "services/nodecg-io-pishock": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "nodecg-io-core": "^0.3.0", + "pishock-ts": "^1.0.1" + }, + "devDependencies": { + "@nodecg/types": "^2.1.12", + "@types/node": "^20.12.2", + "nodecg-io-tsconfig": "^1.0.0", + "typescript": "^5.4.3" + } + }, "services/nodecg-io-rcon": { "version": "0.3.0", "license": "MIT", diff --git a/samples/pishock/extension/index.ts b/samples/pishock/extension/index.ts new file mode 100644 index 000000000..a2ace306e --- /dev/null +++ b/samples/pishock/extension/index.ts @@ -0,0 +1,24 @@ +import NodeCG from "@nodecg/types"; +import { PiShockClient } from "nodecg-io-pishock"; +import { requireService } from "nodecg-io-core"; + +module.exports = function (nodecg: NodeCG.ServerAPI) { + nodecg.log.info("Sample bundle for the PiShock service started."); + + const pishock = requireService(nodecg, "pishock"); + + pishock?.onAvailable((client) => { + nodecg.log.info("PiShock client has been updated, printing all device's infos"); + client.connectedDevices.forEach(async (device) => { + const info = await device.getInfo(); + nodecg.log.info( + `Client ID: ${info.clientId}, ID: ${info.id}, Name: ${info.name}, Paused: ${info.paused}, ` + + `MaxIntensity: ${info.maxIntensity}, MaxDuration: ${info.maxDuration}, Online: ${info.online}`, + ); + }); + }); + + pishock?.onUnavailable(() => { + nodecg.log.info("PiShock service unavailable."); + }); +}; diff --git a/samples/pishock/package.json b/samples/pishock/package.json new file mode 100644 index 000000000..c0b724234 --- /dev/null +++ b/samples/pishock/package.json @@ -0,0 +1,20 @@ +{ + "name": "pishock", + "version": "0.3.0", + "private": true, + "nodecg": { + "compatibleRange": ">=1.1.1 <3.0.0", + "bundleDependencies": { + "nodecg-io-pishock": "^0.3.0" + } + }, + "license": "MIT", + "dependencies": { + "@types/node": "^20.12.2", + "@nodecg/types": "^2.1.12", + "nodecg-io-core": "^0.3.0", + "nodecg-io-pishock": "^0.3.0", + "typescript": "^5.4.3", + "nodecg-io-tsconfig": "^1.0.0" + } +} diff --git a/samples/pishock/tsconfig.json b/samples/pishock/tsconfig.json new file mode 100644 index 000000000..007b7cba7 --- /dev/null +++ b/samples/pishock/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "nodecg-io-tsconfig", + "references": [ + { + "path": "../../nodecg-io-core" + }, + { + "path": "../../services/nodecg-io-template" + } + ] +} diff --git a/services/nodecg-io-pishock/extension/index.ts b/services/nodecg-io-pishock/extension/index.ts new file mode 100644 index 000000000..7d81a4033 --- /dev/null +++ b/services/nodecg-io-pishock/extension/index.ts @@ -0,0 +1,65 @@ +import NodeCG from "@nodecg/types"; +import { Result, emptySuccess, success, ServiceBundle, Logger, error } from "nodecg-io-core"; +import { PiShockDevice, PiShockAuthentication } from "pishock-ts"; + +export interface PiShockConfig { + authentications: Array; +} + +export interface PiShockClient { + connectedDevices: Array; +} + +module.exports = (nodecg: NodeCG.ServerAPI) => { + new PiShockService(nodecg, "pishock", __dirname, "../schema.json").register(); +}; + +class PiShockService extends ServiceBundle { + async validateConfig(config: PiShockConfig): Promise> { + for (const deviceConfig of config.authentications) { + if (!/[0-9a-f-]+/.test(deviceConfig.apiKey)) { + return error(`Invalid PiShock apiKey format: ${deviceConfig.apiKey}`); + } + + if (!/[0-9A-Z]+/.test(deviceConfig.code)) { + return error(`Invalid PiShock code format: ${deviceConfig.code}`); + } + } + + return emptySuccess(); + } + + async createClient(config: PiShockConfig, logger: Logger): Promise> { + const devices = config.authentications.map((c) => { + // Set name if missing. + c.name ??= "nodecg-io PiShock Service"; + return new PiShockDevice(c); + }); + + // Test connection and return error if any provided auth details fail to do the request. + const connectionStates = await Promise.all( + devices.map(async (dev) => { + try { + await dev.getInfo(); + return true; + } catch (err) { + return err; + } + }), + ); + + for (const state of connectionStates) { + if (state instanceof Error) { + return error(`Failed to connect to PiShock api: ${state.message}`); + } + } + + const client = { connectedDevices: devices }; + logger.info("Successfully created PiShock client."); + return success(client); + } + + stopClient(_: PiShockClient, _logger: Logger): void { + // Stateless REST API, cannot be stopped + } +} diff --git a/services/nodecg-io-pishock/package.json b/services/nodecg-io-pishock/package.json new file mode 100644 index 000000000..f7f5f87e8 --- /dev/null +++ b/services/nodecg-io-pishock/package.json @@ -0,0 +1,50 @@ +{ + "name": "nodecg-io-pishock", + "version": "0.3.0", + "description": "Allows using the PiShock api.", + "homepage": "https://nodecg.io/RELEASE/samples/pishock", + "author": { + "name": "CodeOverflow team", + "url": "https://github.com/codeoverflow-org" + }, + "contributors": [ + { + "name": "SteffoSpieler", + "url": "https://steffo.dev" + } + ], + "repository": { + "type": "git", + "url": "https://github.com/codeoverflow-org/nodecg-io.git", + "directory": "services/nodecg-io-pishock" + }, + "files": [ + "**/*.js", + "**/*.js.map", + "**/*.d.ts", + "*.json" + ], + "main": "extension/index", + "keywords": [ + "nodecg-io", + "nodecg-bundle", + "pishock" + ], + "nodecg": { + "compatibleRange": ">=1.1.1 <3.0.0", + "bundleDependencies": { + "nodecg-io-core": "^0.3.0" + } + }, + "license": "MIT", + "devDependencies": { + "@types/node": "^20.12.2", + "@nodecg/types": "^2.1.12", + "typescript": "^5.4.3", + "nodecg-io-tsconfig": "^1.0.0" + }, + "dependencies": { + "nodecg-io-core": "^0.3.0", + "pishock-ts": "^1.0.1" + } +} diff --git a/services/nodecg-io-pishock/schema.json b/services/nodecg-io-pishock/schema.json new file mode 100644 index 000000000..d6b38eda3 --- /dev/null +++ b/services/nodecg-io-pishock/schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "authentications": { + "type": "array", + "items": { + "type": "object", + "required": ["username", "apiKey", "code"], + "properties": { + "username": { + "type": "string", + "description": "Username you use to log into PiShock.com. Can be found in the Account section of the website." + }, + "apiKey": { + "type": "string", + "description": "API Key generated on PiShock.com. Can be found in the Account section of the website." + }, + "code": { + "type": "string", + "description": "Sharecode generated on PiShock.com. Limitations can be set when generating the code." + }, + "name": { + "type": "string", + "description": "Name of what sent the commands. This will show up in the PiShock logs on the website." + } + } + } + } + }, + "required": ["authentications"] +} diff --git a/services/nodecg-io-pishock/tsconfig.json b/services/nodecg-io-pishock/tsconfig.json new file mode 100644 index 000000000..f114d2be2 --- /dev/null +++ b/services/nodecg-io-pishock/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "nodecg-io-tsconfig", + "references": [ + { + "path": "../../nodecg-io-core" + } + ] +} From 671f24074b530b58a07abeed4227e9099d594698 Mon Sep 17 00:00:00 2001 From: SteffoSpieler Date: Wed, 11 Sep 2024 21:39:44 +0200 Subject: [PATCH 2/3] chore: Update contributor info --- services/nodecg-io-gametts/package.json | 2 +- services/nodecg-io-google-cast/package.json | 2 +- services/nodecg-io-opentts/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/nodecg-io-gametts/package.json b/services/nodecg-io-gametts/package.json index a8c88f85d..fa73aa997 100644 --- a/services/nodecg-io-gametts/package.json +++ b/services/nodecg-io-gametts/package.json @@ -10,7 +10,7 @@ "contributors": [ { "name": "SteffoSpieler", - "url": "https://about.steffospieler.de" + "url": "https://steffo.dev" } ], "repository": { diff --git a/services/nodecg-io-google-cast/package.json b/services/nodecg-io-google-cast/package.json index 2a519647a..8ee92d1a2 100644 --- a/services/nodecg-io-google-cast/package.json +++ b/services/nodecg-io-google-cast/package.json @@ -10,7 +10,7 @@ "contributors": [ { "name": "SteffoSpieler", - "url": "https://about.steffospieler.de" + "url": "https://steffo.dev" } ], "repository": { diff --git a/services/nodecg-io-opentts/package.json b/services/nodecg-io-opentts/package.json index c595da535..8a308e13e 100644 --- a/services/nodecg-io-opentts/package.json +++ b/services/nodecg-io-opentts/package.json @@ -10,7 +10,7 @@ "contributors": [ { "name": "SteffoSpieler", - "url": "https://about.steffospieler.de" + "url": "https://steffo.dev" } ], "repository": { From fb872b8e3f90ce87371770c331a6d679366cff3e Mon Sep 17 00:00:00 2001 From: SteffoSpieler Date: Wed, 11 Sep 2024 21:53:00 +0200 Subject: [PATCH 3/3] feat(pishock): Add pishock docs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8f12c9a73..dc11fa483 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ nodecg-io is the successor of [ChatOverflow](https://github.com/codeoverflow-org - OBS - [OpenTTS](https://github.com/synesthesiam/opentts) - Philips Hue +- [PiShock](https://pishock.com) - RCON - Reddit - sACN Receiver