MQTT broker that can run on any stream server

Overview

Nest Mqtt Server Logo

npm version npm download npm lisence github star github fork

Nest.js MQTT broker that can run on any stream server

Topics

What is MQTT ?

MQTT is a lightweight IoT messaging protocol based on the publish/subscribe model. It can provide real-time and reliable messaging services for networked devices with very little code and bandwidth. It is widely used in the industries such as the IoT, mobile Internet, smart hardware, Internet of Vehicles and power energy.

MQTT (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for low latency. This protocol provides a callable and cost-efficient way to connect devices using a publish/subscribe model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

Installation

Install From NPM :

$ npm i pigeon-mqtt-nest

https://nodei.co/npm/pigeon-mqtt-nest.png?downloads=true&downloadRank=true&stars=true


Usage

Pigeon-Mqtt-Nestjs will register as a global module. You can import with configuration

@Module({
  imports: [

    PigeonModule.forRoot({
      port: 1884,
      id: "binarybeast",
      concurrency:100,
      queueLimit:42,
      maxClientsIdLength:23,
      connectTimeout:30000,
      heartbeatInterval:60000,
     })

  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
}
  • options
    • mq middleware used to deliver messages to subscribed clients. In a cluster environment it is used also to share messages between brokers instances. Default: mqemitter
    • concurrency maximum number of concurrent messages delivered by mq. Default: 100
    • persistence middleware that stores QoS > 0, retained, will packets and subscriptions. Default: aedes-persistence (in memory)
    • queueLimit maximum number of queued messages before client session is established. If number of queued items exceeds, connectionError throws an error Client queue limit reached. Default: 42
    • maxClientsIdLength option to override MQTT 3.1.0 clients Id length limit. Default: 23
    • heartbeatInterval an interval in millisconds at which server beats its health signal in $SYS//heartbeat topic. Default: 60000
    • id aedes broker unique identifier. Default: uuidv4()
    • connectTimeout maximum waiting time in milliseconds waiting for a CONNECT packet. Default: 30000
  • Returns
  • Handlers

    Handler Emitted When
    preConnect Invoked when server receives a valid CONNECT packet.
    authenticate Invoked after preConnect.
    authorizePublish publish LWT to all online clients,incoming client publish
    authorizeSubscribe restore subscriptions in non-clean session.,incoming client SUBSCRIBE
    published same as Event: publish, but provides a backpressure functionality.

    Handler: preConnect

    • client:
    • packet: CONNECT
    • callback: (error, successful) => void
      • error | null
      • successful
    • Invoked when server receives a valid CONNECT packet. The packet can be modified.

      client object is in default state. If invoked callback with no errors and successful be true, server will continue to establish a session.

      Any error will be raised in connectionError event.

      Some Use Cases:

      1. Rate Limit / Throttle by client.conn.remoteAddress
      2. Check aedes.connectedClient to limit maximum connections
      3. IP blacklisting
      @Injectable()
      export class TestService {
      
        @onPreConnect()
        onPreConnect(@Client() client, @Packet() packet, @Function() done) {
          console.log("Function: @onPreConnect()");
          return done(null, true);
        }
      
      }

      Handler: authenticate

      • client:
      • credential:
      • callback: (error, successful) => void
        • error | null
        • successful

      Invoked after preConnect.

      Server parses the CONNECT packet, initializes client object which set client.id to match the one in CONNECT packet and extract username and password as parameters for user-defined authentication flow.

      If invoked callback with no errors and successful be true, server authenticates client and continues to setup the client session.

      If authenticated, server acknowledges a CONNACK with returnCode=0, otherwise returnCode=5. Users could define the value between 2 and 5 by defining a returnCode property in error object.

      @Injectable()
      export class TestService {
      
        @onAuthenticate()
        onAuthenticate(@Client() client, @Credential() credential, @Function() done) {
          console.log("Function: @onAuthenticate()");
          return done(null, true);
        }
      
      }
      @Injectable()
      export class TestService {
      
        @onAuthenticate()
        onAuthenticate(@Client() client, @Credential() credential, @Function() done) {
          console.log("Function: @onAuthenticate()");
          var error = new Error('Auth error')
          error.returnCode = 4
          return done(error, false);
        }
      
      }

      Please refer to Connect Return Code to see their meanings.

      Handler: authorizePublish

      • client: | null
      • packet: PUBLISH
      • callback: (error) => void
        • error | null
      • Invoked when

        1. publish LWT to all online clients
        2. incoming client publish

        client is null when aedes publishes obsolete LWT without connected clients

        If invoked callback with no errors, server authorizes the packet otherwise emits clientError with error. If an error occurs the client connection will be closed, but no error is returned to the client (MQTT-3.3.5-2)

        @Injectable()
        export class TestService {
        
          @onAuthorizePublish()
          onAuthorizePublish(@Client() client, @Packet() packet, @Function() done) {
            console.log("Function: @onAuthorizePublish()");
            if (packet.topic === 'aaaa') {
              return done(new Error('wrong topic'))
            }
            if (packet.topic === 'bbb') {
              packet.payload = Buffer.from('overwrite packet payload')
            }
            return done(null);
          }
        
        }

        By default authorizePublish throws error in case a client publish to topics with $SYS/ prefix to prevent possible DoS (see #597). If you write your own implementation of authorizePublish we suggest you to add a check for this. Default implementation:

        @Injectable()
        export class TestService {
        
          @onAuthorizePublish()
          onAuthorizePublish(@Client() client, @Packet() packet, @Function() done) {
            if (packet.topic.startsWith($SYS_PREFIX)) {
              return done(new Error($SYS_PREFIX + ' topic is reserved'))
            }
            return done(null);
          }
        
        }

        Handler: authorizeSubscribe

        • client:
        • subscription:
        • callback: (error) => void
          • error | null
          • subscription: | null

            Invoked when

            1. restore subscriptions in non-clean session.
            2. incoming client SUBSCRIBE

            subscription is a dictionary object like { topic: hello, qos: 0 }.

            If invoked callback with no errors, server authorizes the packet otherwise emits clientError with error.

            In general user should not touch the subscription and pass to callback, but server gives an option to change the subscription on-the-fly.

            @Injectable()
            export class TestService {
            
              @onAuthorizeSubscribe()
              onAuthorizeSubscribe(@Client() client, @Subscription() subscription, @Function() done) {
                console.log("Function: @onAuthorizeSubscribe()");
                if (subscription.topic === 'aaaa') {
                  return done(new Error('wrong topic'))
                }
                if (subscription.topic === 'bbb') {
                  // overwrites subscription
                  subscription.topic = 'foo'
                  subscription.qos = 1
                }
                return done(null, subscription);
              }
            
            }

            To negate a subscription, set the subscription to null. Aedes ignores the negated subscription and the qos in SubAck is set to 128 based on MQTT 3.11 spec:

            @Injectable()
            export class TestService {
            
              @onAuthorizeSubscribe()
              onAuthorizeSubscribe(@Client() client, @Subscription() subscription, @Function() done) {
                done(null, subscription.topic === 'aaaa' ? null : sub)
              }
            
            }

            Handler: published

            • packet: & PUBLISH
            • client:
            • callback:

            same as Event: publish, but provides a backpressure functionality. TLDR; If you are doing operations on packets that MUST require finishing operations on a packet before handling the next one use this otherwise, especially for long-running operations, you should use Event: publish instead.

            @Injectable()
            export class TestService {
            
              @onPublish()
              OnPublish(@Topic() topic, @Packet() packet, @Payload() payload, @Client() client) {
                console.log("Function: @OnPublish()");
              }
            
            }

            Events

            Name Emitted When
            Client client registers itself to server
            Client Ready client has received all its offline messages and be initialized.
            Client Disconnect client disconnects.
            Client Error an error occurs.
            Connection Error an error occurs.
            Keep Alive Timeout timeout happes in the client keepalive.
            Publish servers delivers the packet to subscribed client.
            Ack packet successfully delivered to the client.
            Subscribe client successfully subscribe the subscriptions in server.
            Unsubscribe client successfully unsubscribe the subscriptions in server.
            Connack Sent server sends an acknowledge to client.
            Closed server is closed.

            Event: client

            • client

            Emitted when the client registers itself to server. The client is not ready yet. Its connecting state equals to true.

            Server publishes a SYS topic $SYS//new/clients to inform it registers the client into its registration pool. client.id is the payload.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onClient()
              OnNewClient(@Client() client) {
                console.log("Function: @onClient()");
              }
            
            }

            Event: clientReady

            • client

            Emitted when the client has received all its offline messages and be initialized. The client connected state equals to true and is ready for processing incoming messages.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onClientReady()
              async onClientReady(@Client() client) {
                console.log("Function: @onClientReady()");
              }
            
            }

            Event: clientDisconnect

            • client

            Emitted when a client disconnects.

            Server publishes a SYS topic $SYS//disconnect/clients to inform it deregisters the client. client.id is the payload.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onClientDisconnect()
              OnClientDisconnect(@Client() client) {
                console.log("Function: @OnClientDisconnect()");
              }
            
            }

            Event: clientError

            • client
            • error

            Emitted when an error occurs.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onClientError()
              OnClientError(@Client() client, @Error() error) {
                console.log("Function: @onClientError()");
              }
            
            }

            Event: connectionError

            • client
            • error

            Emitted when an error occurs. Unlike clientError it raises only when client is uninitialized.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onConnectionError()
              OnConnectionError(@Client() client, @Error() error) {
                console.log("Function: @OnConnectionError()");
              }
            
            }

            Event: keepaliveTimeout

            • client

            Emitted when timeout happes in the client keepalive.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onKeepLiveTimeout()
              onKeepLiveTimeout(@Client() client) {
                console.log("Function: @onKeepLiveTimeout()");
              }
            
            }

            Event: publish

            Emitted when servers delivers the packet to subscribed client. If there are no clients subscribed to the packet topic, server still publish the packet and emit the event. client is null when packet is an internal message like aedes heartbeat message and LWT.

            Note! packet belongs aedes-packet type. Some properties belongs to aedes internal, any changes on them will break aedes internal flow.

            @Injectable()
            export class TestService {
            
              constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
              }
            
              @onPublish()
              OnPublish(@Topic() topic, @Packet() packet, @Payload() payload, @Client() client) {
                console.log("Function: @OnPublish()");
              }
            
            }

            Event: ack

            • packet PUBLISH for QoS 1, PUBREL for QoS 2
            • client
            • Emitted an QoS 1 or 2 acknowledgement when the packet successfully delivered to the client.

              @Injectable()
              export class TestService {
              
                constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
                }
              
              
                @onAck()
                onAck(@Client() client, @Packet() packet) {
                  console.log("Function: @onAck()");
                }
              
              }

              Event: subscribe

              • subscriptions
              • client
              • Emitted when client successfully subscribe the subscriptions in server.

                subscriptions is an array of { topic: topic, qos: qos }. The array excludes duplicated topics and includes negated subscriptions where qos equals to 128. See more on authorizeSubscribe

                Server publishes a SYS topic $SYS//new/subscribers to inform a client successfully subscribed to one or more topics. The payload is a JSON that has clientId and subs props, subs equals to subscriptions array.

                @Injectable()
                export class TestService {
                
                  constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
                  }
                
                  @onSubscribe()
                  OnSubscribe(@Subscription() subscription, @Client() client) {
                    console.log("Function: @OnSubscribe()");
                  }
                
                }

                Event: unsubscribe

                • unsubscriptions Array
                • client

                Emitted when client successfully unsubscribe the subscriptions in server.

                unsubscriptions are an array of unsubscribed topics.

                Server publishes a SYS topic $SYS//new/unsubscribers to inform a client successfully unsubscribed to one or more topics. The payload is a JSON that has clientId and subs props, subs equals to unsubscriptions array.

                @Injectable()
                export class TestService {
                
                  constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
                  }
                
                  @onUnsubscribe()
                  OnUnsubscribe(@Subscription() subscription, @Client() client) {
                    console.log("Function: @OnUnsubscribe()");
                  }
                
                }

                Event: connackSent

                • packet CONNACK
                • client
                • Emitted when server sends an acknowledge to client. Please refer to the MQTT specification for the explanation of returnCode object property in CONNACK.

                  @Injectable()
                  export class TestService {
                  
                    constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
                    }
                  
                    @onConnackSent()
                    onConnackSent(@Client() client, @Packet() packet) {
                      console.log("Function: @onConnackSent()");
                    }
                  
                  }

                  Event: closed

                  Emitted when server is closed.

                  @Injectable()
                  export class TestService {
                  
                    constructor(@Inject(PigeonService) private readonly aedesService: PigeonService) {
                    }
                  
                    @onClosed()
                    onClosed(@Client() client, @Packet() packet) {
                      console.log("Function: @onClosed()");
                    }
                  
                  }

                  Methods

                  Method Emitted When
                  Publish Directly deliver packet on behalf of server to subscribed clients.
                  Close Close aedes server and disconnects all clients.

                  Method: Publish

                  • packet PUBLISH

                    Directly deliver packet on behalf of server to subscribed clients. Bypass authorizePublish.

                    callback will be invoked with error arugments after finish.

                    @Injectable()
                    export class TestService {
                    
                      //inject Pigeon Service
                      constructor(@Inject(PigeonService) private readonly pigeonService: PigeonService) {
                      }
                    
                      @onPublish()
                      async OnPublish(@Topic() topic, @Packet() packet, @Payload() payload, @Client() client) {
                    
                        //use this method to publish
                        await this.pigeonService.publish({
                          topic: "test2", qos: 0, cmd: "publish", payload: "", dup: false, retain: false
                        });
                    
                      }
                    
                    }

                    Method: Close

                    • callback:

                    Close aedes server and disconnects all clients.

                    callback will be invoked when server is closed.

                    @Injectable()
                    export class TestService {
                    
                      //inject Pigeon Service
                      constructor(@Inject(PigeonService) private readonly pigeonService: PigeonService) {
                      }
                    
                      @onPublish()
                      async OnPublish(@Topic() topic, @Packet() packet, @Payload() payload, @Client() client) {
                    
                        //use this method to publish
                        await this.pigeonService.close();
                    
                      }
                    
                    }

                    Packets

                    This section describes the format of all packets

                    Packet -
                    Connect ---
                    Connack ---
                    Subscribe ---
                    Suback ---
                    Unsubscribe ---
                    Unsuback ---
                    Publish ---
                    Puback ---
                    Pubrec ---
                    Pubrel ---
                    Pubcomp ---
                    Pingreq ---
                    Pingresp ---
                    Disconnect ---

                    Packet: Connect

                    {
                      cmd: 'connect',
                      protocolId: 'MQTT', // Or 'MQIsdp' in MQTT 3.1 and 5.0
                      protocolVersion: 4, // Or 3 in MQTT 3.1, or 5 in MQTT 5.0
                      clean: true, // Can also be false
                      clientId: 'my-device',
                      keepalive: 0, // Seconds which can be any positive number, with 0 as the default setting
                      username: 'matteo',
                      password: Buffer.from('collina'), // Passwords are buffers
                      will: {
                        topic: 'mydevice/status',
                        payload: Buffer.from('dead'), // Payloads are buffers
                        properties: { // MQTT 5.0
                          willDelayInterval: 1234,
                          payloadFormatIndicator: false,
                          messageExpiryInterval: 4321,
                          contentType: 'test',
                          responseTopic: 'topic',
                          correlationData: Buffer.from([1, 2, 3, 4]),
                          userProperties: {
                            'test': 'test'
                          }
                        }
                      },
                      properties: { // MQTT 5.0 properties
                          sessionExpiryInterval: 1234,
                          receiveMaximum: 432,
                          maximumPacketSize: 100,
                          topicAliasMaximum: 456,
                          requestResponseInformation: true,
                          requestProblemInformation: true,
                          userProperties: {
                            'test': 'test'
                          },
                          authenticationMethod: 'test',
                          authenticationData: Buffer.from([1, 2, 3, 4])
                      }
                    }

                    If password or will.payload are passed as strings, they will automatically be converted into a Buffer.

                    Packet: Connack

                    {
                      cmd: 'connack',
                      returnCode: 0, // Or whatever else you see fit MQTT < 5.0
                      sessionPresent: false, // Can also be true.
                      reasonCode: 0, // reason code MQTT 5.0
                      properties: { // MQTT 5.0 properties
                          sessionExpiryInterval: 1234,
                          receiveMaximum: 432,
                          maximumQoS: 2,
                          retainAvailable: true,
                          maximumPacketSize: 100,
                          assignedClientIdentifier: 'test',
                          topicAliasMaximum: 456,
                          reasonString: 'test',
                          userProperties: {
                            'test': 'test'
                          },
                          wildcardSubscriptionAvailable: true,
                          subscriptionIdentifiersAvailable: true,
                          sharedSubscriptionAvailable: false,
                          serverKeepAlive: 1234,
                          responseInformation: 'test',
                          serverReference: 'test',
                          authenticationMethod: 'test',
                          authenticationData: Buffer.from([1, 2, 3, 4])
                      }
                    }

                    Packet: Subscribe

                    {
                      cmd: 'subscribe',
                      messageId: 42,
                      properties: { // MQTT 5.0 properties
                        subscriptionIdentifier: 145,
                        userProperties: {
                          test: 'test'
                        }
                      }
                      subscriptions: [{
                        topic: 'test',
                        qos: 0,
                        nl: false, // no Local MQTT 5.0 flag
                        rap: true, // Retain as Published MQTT 5.0 flag
                        rh: 1 // Retain Handling MQTT 5.0
                      }]
                    }

                    Packet: Suback

                    {
                      cmd: 'suback',
                      messageId: 42,
                      properties: { // MQTT 5.0 properties
                        reasonString: 'test',
                        userProperties: {
                          'test': 'test'
                        }
                      }
                      granted: [0, 1, 2, 128]
                    }

                    Packet: Unsubscribe

                    {
                      cmd: 'unsubscribe',
                      messageId: 42,
                      properties: { // MQTT 5.0 properties
                        userProperties: {
                          'test': 'test'
                        }
                      }
                      unsubscriptions: [
                        'test',
                        'a/topic'
                      ]
                    }

                    Packet: Unsuback

                    {
                      cmd: 'unsuback',
                      messageId: 42,
                      properties: { // MQTT 5.0 properties
                        reasonString: 'test',
                        userProperties: {
                          'test': 'test'
                        }
                      }
                    }

                    Packet: Publish

                    {
                      cmd: 'publish',
                              messageId: 42,
                              qos: 2,
                              dup: false,
                              topic: 'test',
                              payload: Buffer.from('test'),
                              retain: false,
                              properties: { // optional properties MQTT 5.0
                        payloadFormatIndicator: true,
                                messageExpiryInterval: 4321,
                                topicAlias: 100,
                                responseTopic: 'topic',
                                correlationData: Buffer.from([1, 2, 3, 4]),
                                userProperties: {
                          'test': 'test'
                        },
                        subscriptionIdentifier: 120, // can be an Array in message from broker, if message included in few another subscriptions
                                contentType: 'test'
                      }
                    }

                    Packet: Puback

                    {
                      cmd: 'puback',
                              messageId: 42,
                              reasonCode: 16, // only for MQTT 5.0
                              properties: { // MQTT 5.0 properties
                        reasonString: 'test',
                                userProperties: {
                          'test': 'test'
                        }
                      }
                    }

                    Packet: Pubrec

                    {
                      cmd: 'pubrec',
                              messageId: 42,
                              reasonCode: 16, // only for MQTT 5.0
                              properties: { // properties MQTT 5.0
                        reasonString: 'test',
                                userProperties: {
                          'test': 'test'
                        }
                      }
                    }

                    Packet: Pubrel

                    {
                      cmd: 'pubrel',
                              messageId: 42,
                              reasonCode: 16, // only for MQTT 5.0
                              properties: { // properties MQTT 5.0
                        reasonString: 'test',
                                userProperties: {
                          'test': 'test'
                        }
                      }
                    }

                    Packet: Pubcomp

                    {
                      cmd: 'pubcomp',
                              messageId: 42,
                              reasonCode: 16, // only for MQTT 5.0
                              properties: { // properties MQTT 5.0
                        reasonString: 'test',
                                userProperties: {
                          'test': 'test'
                        }
                      }
                    }

                    Packet: Pingreq

                    {
                      cmd: 'pingreq'
                    }

                    Packet: Pingresp

                    {
                      cmd: 'pingresp'
                    }

                    Packet: Disconnect

                    {
                      cmd: 'disconnect',
                              reasonCode: 0, // MQTT 5.0 code
                              properties: { // properties MQTT 5.0
                        sessionExpiryInterval: 145,
                                reasonString: 'test',
                                userProperties: {
                          'test': 'test'
                        },
                        serverReference: 'test'
                      }
                    }

                    Middleware Plugins

                    Persistence

                    • [aedes-persistence]: In-memory implementation of an Aedes persistence
                    • [aedes-persistence-mongodb]: MongoDB persistence for Aedes
                    • [aedes-persistence-redis]: Redis persistence for Aedes
                    • [aedes-persistence-level]: LevelDB persistence for Aedes
                    • [aedes-persistence-nedb]: NeDB persistence for Aedes

                    MQEmitter

                    • [mqemitter]: An opinionated memory Message Queue with an emitter-style API
                    • [mqemitter-redis]: Redis-powered mqemitter
                    • [mqemitter-mongodb]: Mongodb based mqemitter
                    • [mqemitter-child-process]: Share the same mqemitter between a hierarchy of child processes
                    • [mqemitter-cs]: Expose a MQEmitter via a simple client/server protocol
                    • [mqemitter-p2p]: A P2P implementation of MQEmitter, based on HyperEmitter and a Merkle DAG
                    • [mqemitter-aerospike]: Aerospike mqemitter

                    Dependencies


                    Stay in touch


                    License

                    MIT License
                    
                    Copyright (c) 2021 behnamnasehi
                    
                    Permission is hereby granted, free of charge, to any person obtaining a copy
                    of this software and associated documentation files (the "Software"), to deal
                    in the Software without restriction, including without limitation the rights
                    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                    copies of the Software, and to permit persons to whom the Software is
                    furnished to do so, subject to the following conditions:
                    
                    The above copyright notice and this permission notice shall be included in all
                    copies or substantial portions of the Software.
                    
                    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
                    SOFTWARE.
                    

                    GO TO TOP

                    You might also like...

                    Run REST APIs in Node.js applications frameworks (Express, Koa, Hapi and Fastify) on top of any Serverless Cloud.

                    🚀 Serverless Adapter Install | Usage | Support | Architecture | Credits Run REST APIs and other web applications using your existing Node.js applicat

                    Jan 1, 2023

                    An action intended to run on pull request and post a comment summarizing any changes to DevCycle variables.

                    An action intended to run on pull request and post a comment summarizing any changes to DevCycle variables.

                    Overview With this Github action, information on which DevCycle features have been added or removed in a code change will be shown directly on each Pu

                    Jun 14, 2022

                    With this File Manager prepared for PHP/Js, you can perform all file operations on your server without any problems.

                    FileManager With this File Manager prepared for PHP/Js, you can perform all file operations on your server without any problems. Instead of downloadin

                    Sep 23, 2022

                    Monolithic repo for api server, image server, web server

                    Onsecondary Market Deployed at https://market.onsecondary.com Monolithic repo for api server, image server, web server TODO -use a script to cull expi

                    Jan 11, 2022

                    A Discord Bot that connects to your AzerothCore server so you / users can manage the server / character

                    A Discord Bot that connects to your AzerothCore server so you / users can manage the server / character. Made for AzerothCore / azerothcore-tools

                    Sep 24, 2022

                    CLI Progress Bar implemented in NodeJS to track Time, ETA and Steps for any long running jobs in any loops in JS, NodeJS code

                    CLI Progress Bar implemented in NodeJS to track Time, ETA and Steps for any long running jobs in any loops in JS, NodeJS code

                    NodeJS-ProgressBar CLI Progress Bar for NodeJS and JavaScript to track Time, ETA and Steps for any long running jobs in any loops in JS, NodeJS code D

                    Nov 14, 2022

                    A tiny JavaScript library to easily toggle the state of any HTML element in any contexts, and create UI components in no time.

                    A tiny JavaScript library to easily toggle the state of any HTML element in any contexts, and create UI components in no time.

                    A tiny JavaScript library to easily toggle the state of any HTML element in any contexts, and create UI components in no time. Dropdown, navigation bu

                    Nov 25, 2022

                    a VS Code Extension for Easily Localize any blade/php text in any Laravel project.

                    a VS Code Extension for Easily Localize any blade/php text in any Laravel project.

                    Laravel Easy Localize a VS Code Extension for Easily Localize any blade/php text in any Laravel project. Features Custom array key for each translatio

                    Oct 31, 2022

                    An adapter where you can define which function to run

                    Switch Functions An adapter where you can define which function to run Installation This is a Node.js module available through the npm registry. Befor

                    Jun 17, 2022
                    Owner
                    Behnam Nasehi
                    Android Application Developer Nest.js Developer
                    Behnam Nasehi
                    Blockchain, Smart Contract, Ganache, Remix, Web3, Solidity, Java Script, MQTT, ESP32, RFID, DHT11,

                    Blockchain, Smart Contract, Ganache, Remix, Web3, Solidity, Java Script, MQTT, ESP32, RFID, DHT11,

                    Hajar OUAAROUCH 5 May 24, 2022
                    Utility to automatically fill foreign income section of 3-NDFL report based on tax report from Tinkoff broker

                    Заполнение дохода за пределами РФ в декларации 3-НДФЛ Disclaimer Автор не несет ответственности за корректное заполнение налоговой декларации. Вы запу

                    Oleg Elifantiev 12 Dec 9, 2022
                    Using a RPI 3b+ to create a PT camera accessible through Windows browser and controllable through MQTT

                    web-camera_PT A Web flask server converts the MJPEG stream from RPI to JPG img using opencv, then display in browser. Controls added to move Camera in

                    null 11 Dec 20, 2022
                    Kafka 0.8.0 broker implementation on top of Cloudflare Workers

                    Kafka Worker A Kafka 0.8.0 broker implementation on top of Cloudflare Workers and Durable Objects. This broker supports 4 client-facing APIs: Produce

                    Max Peterson 129 Dec 11, 2022
                    Everynode allows you to run any version of Node.js in AWS Lambda, in any commercial AWS region

                    Run Any Node.js Version in AWS Lambda Everynode allows you to run any version of Node.js in AWS Lambda, in any commercial AWS region. We add support f

                    Fusebit 116 Dec 15, 2022
                    This repo is a collection of code samples and links to previous twitch live stream sessions. If you have any ideas or suggestions for future episodes, feel free to open an issue.

                    Talk DEV to me Talk DEV to me is a monthly show on twitch.tv/aws hosted by Tiago Barbosa and Alex Melnyk, where we invite customers, partners, or Amaz

                    AWS Samples 122 Jan 6, 2023
                    Run a command, watch the filesystem, stop the process on file change and then run the command again...

                    hubmon Run a command, watch the filesystem, stop the process on file change and then run the command again... Install You can install this command lin

                    Hubert SABLONNIÈRE 7 Jul 30, 2022
                    This is a project that is used to execute python codes in the web page. You can install and use it in django projects, You can do any operations that can be performed in python shell with this package.

                    Django execute code This is a project that is used to execute python codes in the web page. You can install and use it in django projects, You can do

                    Shinu 5 Nov 12, 2022
                    Prisma 2+ generator to emit a JSON file that can be run with json-server

                    Prisma JSON Server Generator A Prisma generator that automates creating a JSON file that can be run as a server from your Prisma schema. Explore the o

                    Omar Dulaimi 14 Jan 7, 2023
                    A web applicaton called 'MOVTIME' where you can come to stream movies by consuming the TMDB movie API

                    End result Click here : https://movtime-movie-app.netlify.app/ Figma design File Click here: https://www.figma.com/file/4IbpmTU6jtpRKdpbFmt4i8/Web-Des

                    Eniola Odunmbaku 12 Nov 11, 2022