From e34565ec735d46b8916d1d6da441efcecf1a8297 Mon Sep 17 00:00:00 2001 From: ui_creeperlv Date: Fri, 29 Mar 2024 23:36:10 +0530 Subject: [PATCH] Inital Client. --- .gitignore | 261 ++++++++++++++++++++++++++++++++ example/index.js | 36 +++++ index.js | 10 +- node_modules/.package-lock.json | 35 ++++- node_modules/connectx.js | 1 - package-lock.json | 48 ++++++ package.json | 8 +- src/Client.js | 109 +++++++++++++ src/Events.js | 7 + src/Message.js | 53 +++++++ 10 files changed, 561 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 example/index.js mode change 100644 => 100755 index.js mode change 100644 => 100755 node_modules/.package-lock.json delete mode 120000 node_modules/connectx.js create mode 100644 package-lock.json mode change 100644 => 100755 package.json create mode 100644 src/Client.js create mode 100644 src/Events.js create mode 100644 src/Message.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c09199 --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/example/index.js b/example/index.js new file mode 100644 index 0000000..8c17c74 --- /dev/null +++ b/example/index.js @@ -0,0 +1,36 @@ +require("dotenv").config(); +const { Client, Events, Message } = require("../index"); + +let connectx = new Client(process.env['TOKEN']); + +connectx.on(Events.LOG , (data) => { + console.log(data); +}); + +connectx.on(Events.ERROR , (data) => { + console.log(data); +}); + +connectx.on(Events.CLIENT_READY , async (data) => { + console.log(data); + + console.log(await connectx.servers()); + + let message = new Message(); + + message.authorIcon = "https://static.wikia.nocookie.net/digitousailorcure/images/0/09/Anya_forger.png"; + message.authorName = "Anya Forger"; + message.serverIcon = "https://static.wikia.nocookie.net/digitousailorcure/images/0/09/Anya_forger.png"; + message.serverName = "Forger's Basement"; + message.message = "Waku Waku"; + + console.log(await connectx.send( + message.toArray() + )); +}); + +connectx.on(Events.MESSAGE , (data) => { + console.log(data); +}); + +connectx.login(); \ No newline at end of file diff --git a/index.js b/index.js old mode 100644 new mode 100755 index 4ba52ba..ad37998 --- a/index.js +++ b/index.js @@ -1 +1,9 @@ -module.exports = {} +const Client = require("./src/Client"); +const Events = require("./src/Events"); +const Message = require("./src/Message"); + +module.exports = { + Client: Client, + Events: Events, + Message: Message +} \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json old mode 100644 new mode 100755 index eecd8ce..29cf5ee --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -1,10 +1,39 @@ { + "name": "connectx.js", + "version": "0.0.1-hold", "lockfileVersion": 3, "requires": true, "packages": { - "node_modules/connectx.js": { - "resolved": "", - "link": true + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } } } } diff --git a/node_modules/connectx.js b/node_modules/connectx.js deleted file mode 120000 index a96aa0e..0000000 --- a/node_modules/connectx.js +++ /dev/null @@ -1 +0,0 @@ -.. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..47309a7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,48 @@ +{ + "name": "connectx.js", + "version": "0.0.1-hold", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "connectx.js", + "version": "0.0.1-hold", + "license": "AGPL-3.0-or-later", + "dependencies": { + "dotenv": "^16.4.5", + "ws": "^8.16.0" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json old mode 100644 new mode 100755 index ef766ae..c98a3ee --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "HOLD", "main": "index.js", "scripts": { - "test": "node tests/example.js" + "test": "node example/index.js" }, "repository": { "type": "git", @@ -18,5 +18,9 @@ "messages" ], "author": "Unbound LLC", - "license": "AGPL-3.0-or-later" + "license": "AGPL-3.0-or-later", + "dependencies": { + "dotenv": "^16.4.5", + "ws": "^8.16.0" + } } diff --git a/src/Client.js b/src/Client.js new file mode 100644 index 0000000..3c2d2e3 --- /dev/null +++ b/src/Client.js @@ -0,0 +1,109 @@ +const WebSocket = require('ws'); +const Message = require('./Message'); + +class Client { + constructor(token) { + this.token = token; + this.clientUri = "https://connectx.unboundllc.tech/"; + this.events = {}; + this.clientid = null; + this.websocket = null; + } + + on(event, callback) { + this.events[event] = this.events[event] || []; + this.events[event].push(callback); + } + + login(){ + this.websocket = new WebSocket(this.clientUri + "ws", { + headers: { + 'Authorization': `Basic ${this.token}` + } + }); + + this.websocket.onopen = () => { + this.websocket.send("login"); + this.trigger("log" , "Connected to WebSocket Server Successfully"); + }; + + this.websocket.onclose = () => { + this.trigger("disconnect" , new Date()) + } + + this.websocket.onerror = (error) => { + this.trigger("disconnect" , new Date()); + } + + this.websocket.onmessage = (event) => { + let data = JSON.parse(event.data); + let main_event = data.event; + delete data.event; + if(main_event == "ready"){ + this.clientid = data.authorId; + } + if(main_event == "message"){ + this.trigger(main_event , data.data) + }else{ + this.trigger(main_event , { + ...data + }) + } + }; + } + + async servers() { + const headers = new Headers(); + headers.append("Authorization", `Basic ${this.token}`); + + const requestOptions = { + method: "GET", + headers: headers, + redirect: "follow" + }; + + let response = await fetch(`${this.clientUri}api/servers`, requestOptions); + let result = await response.json(); + + return result.servers; + } + + /** + * + * @param {Message} MessageData + */ + async send(MessageData) { + const headers = new Headers(); + headers.append("Authorization", `Basic ${this.token}`); + + const formdata = new FormData(); + formdata.append("authorName", MessageData.authorName); + formdata.append("authorIcon", MessageData.authorIcon); + formdata.append("serverName", MessageData.serverName); + formdata.append("serverIcon", MessageData.serverIcon); + formdata.append("fields", MessageData.fields); + formdata.append("message", MessageData.message); + + const requestOptions = { + method: "POST", + headers: headers, + body: formdata, + redirect: "follow" + }; + + let response = await fetch(`${this.clientUri}api/message`, requestOptions); + let result = await response.json(); + + return result.message; + } + + trigger(event, data) { + if (this.events[event]) { + for (const callback of this.events[event]) { + callback(data); + } + } + } +} + +module.exports = Client; \ No newline at end of file diff --git a/src/Events.js b/src/Events.js new file mode 100644 index 0000000..2af2124 --- /dev/null +++ b/src/Events.js @@ -0,0 +1,7 @@ +module.exports = { + CLIENT_READY: "ready", + MESSAGE: "message", + ERROR: "error", + LOG: "log", + DISCONNECT: "disconnect" +} \ No newline at end of file diff --git a/src/Message.js b/src/Message.js new file mode 100644 index 0000000..ddc33c5 --- /dev/null +++ b/src/Message.js @@ -0,0 +1,53 @@ +class Message { + /** + * @typedef {Object} MessageFields + * @property {string|null} authorName + * @property {URL|null} authorIcon + * @property {string|null} serverName + * @property {string|null} serverIcon + * @property {string|null} message + * @property {string|null} fields + * @property {boolean|null} isSameId + */ + + constructor() { + this.authorName = null; + this.authorIcon = "auto"; + this.serverName = null; + this.serverIcon = null; + this.message = null; + this.fields = []; + this.isSameId = false; + } + + /** + * Fill Product fields with new values + * @param {MessageFields} newFields - Object containing new values for Category fields + */ + fill (newFields) { + for (let field in newFields) { + if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) { + if (this[field] !== 'undefined') { + this[field] = newFields[field]; + } + } + } + + return this.toArray(); + } + + toArray() { + return { + authorName: this.authorName, + authorIcon: this.authorIcon, + serverName: this.serverName, + serverIcon: this.serverIcon, + message: this.message, + fields: this.fields, + isSameId: this.isSameId + }; + } + +} + +module.exports = Message; \ No newline at end of file