npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@fbarda/dirty-serve

v0.0.7

Published

An easy, quick and dirty way to host your static web files with an optional API path interface!

Downloads

19

Readme

Dirty Serve

A quickly hacked together server for serving:

Click on the item to view a code example.

It's called dirty because I didn't intend doing it with good practices and readable code. I might reject PRs only changing code styling.

Code examples

This module will always be imported via require("dirty-serve") in all examples.

Starting the server with default settings

const serverInterface = require("dirty-serve");
serverInterface.startServer();

Changing port

By default, the module checks if $PORT is defined, and if it is, sets the port to $PORTs value. Otherwise it's set to 3000.

Let's change it without setting an environment variable.

const serverInterface = require("dirty-serve");
serverInterface.port = 8080; 
//If you had to use sockets, you could just use socket file's relative path.
//For example, assume our socket is "app.sock":
serverInterface.port = "app.sock";

Blacklisting requests by filtering parts of the requests

OK, I must admit the title is long, but it's necessary. Let's say we need to filter /admin for some reason.

const serverInterface = require("dirty-serve");
serverInterface.pathFilter.add("/admin"); 

Filters out any requests with "/admin" in them. That will filters requests like this:

  • /pictures/admin.jpg
  • /settings/admin
  • /admin But it won't filter something like this: /pictures/picture_of_admin.png /controlAdmin /haha/../Admin

You can use /\/admin/u (see RegExp for more details) to check it without case sensitivity or with more flexibility, or use something like /\/.+admin(?:.html)?$/u to filter requests with admin at the end of them. The possibilities are endless!

Also, let's say we have an api that needs to get ready asyncly before being able to serve. You can also filter and remove that filter if you save the key!

const serverInterface = require("dirty-serve");
//imaginary api has an initialize function which returns a promise that resolves when it's initialized.
function getApiReady(){
    const filterKey = serverInterface.pathFilters.add(IMAGINARY_API_SERVE_PATH);
    imaginaryApi.initialize().then(()=>serverInterface.pathFilters.remove(filterKey));
}

Serving static files

Assuming we have files in "/app/www" we want to serve, but filter out .git requests.

const serverInterface = require("dirty-serve");
serverInterface.pathFilters.add(".git");
serverInterface.static.servePath = "/app/www";
//do other things you need to do, and start the server.

Serving dynamic (API) pages

Assume that we need to make a coin flipper API which can output json and html depending on Accept header. Let's code it!

function flipACoin(){
    return Math.random() > 0.5;
}

function handleCoinFlipPage(incoming,outgoing,_sanitizedPath){
    const serveHTTP = ("accept" in incoming.headers) && (incoming.headers.accept.split(",").includes("text/html"));
    const coinResult = flipACoin() ? "heads" : "tails";
    if(serveHTTP){
        outgoing.writeHead(200,"OK",{ "Content-Type": "text/html"});
        outgoing.write("<p>" + coinResult + "</p>");
        outgoing.end();
    }else{
        outgoing.writeHead(200,"OK",{ "Content-Type": "application/json"});
        outgoing.write('"' + coinResult + '"');
        outgoing.end();
    }
}

const serverInterface = require("dirty-serve");
serverInterface.apiPageHandlers.add("/flipcoin",handleCoinFlipPage);

Handling a Websocket connection

const serverInterface = require("dirty-serve");
const connections = new Set();

function acceptConnection(connection){
    connections.add(connection);
    //The developer must handle removing of connections by themselves.
    connection.on("error",()=>connections.delete(connection));
    connection.on("close",()=>connections.delete(connection));
}
serverInterface.websocketHandlers.add("/getUpdates",acceptConnection);

function publishUpdate(updateText){
    connections.forEach(connection=>connection.sendUTF(updateText));
}
someEventEmitter.on("update",publishUpdate);