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

express-gui

v1.0.1

Published

ExpressJS basic file delivery with a small layer of templating provided by lodash

Downloads

11

Readme

Express GUI

ExpressJS basic file delivery with a small layer of templating provided by lodash.

| Should be paired with connect-modrewrite and conf-stack, more information below

Why?

  • Static files and dynamic files can overlap in url path (e.g /main-dynamic.html /static.html), as well as created files by a frontend build system (e.g artifacts)
  • Not only a static file server
  • Will attempt to provide a dynamic file if available otherwise it will provide a static one
  • A convention for delivering a small gui
  • Pairs well with the websdk
  • Promotes small GUIs (flat directory structure for dynamic and static dirs)

Info

  • Provides a route named /gui or a middleware only that you can bind to your own route.
  • Expects a directory named gui on your working directory or a directory path provided.
  • Expects 3 subdirectories the gui dir: dynamic, static and artifacts
  • Provides a standard configuration/data to all dynamic files (lodash templates)
  • Provides an error handler middleware with a json response
  • Expects you to have a common base for all of your api routes, like /api so any other route might deliver a file if available
  • Attempts to expose as data to all dynamic files the session and session.user if available, so dynamic files can render parts of that data if needed (the suggestion is to create a single properties.js)
  • If route is enabled, files are accesible through /gui?file=name/to/file.html or /gui/name/to/file.html

Installation

npm install express-gui

Using

On your main app file (server.js)


'use strict';

// Get a logger
var logger = console;

// Log some info
logger.log('Starting server process: '+process.pid);

var
  // Load some apis
  guiApi  = require('express-gui')

  // Get some references
  ,express    = require('express')
  ,confStack  = require('conf-stack')
  ,modrewrite = require('connect-modrewrite')

  // Create some instances
  ,app = express()

  // Load the configuration
  ,config = confStack()
;

// Add the logger to the app and a reference of it to the request
app.logger = logger;
app.use(function(req, res, next){
  req.logger = logger;
  next();
});

// Allow internal URL aliasing
logger.info('Config modrewrite is set to: ', config.modrewrite);
app.use(modrewrite(config.modrewrite||[]));

// Load dependency APIs
logger.log('Configuring GUI...');
guiApi(app, config);

// If not handled by now, provide the default url
app.use(function(req,res,next){
  res.send('Nothing here. Maybe will redirect to config.public.home');
});

// Start listening
app.listen(config.port);
logger.info('Server running at: ', config.port);

// Handle Errors sample
app.use(function handleError(err, req, res, next){
  logger.error(err);
  if(err.code === 'ENOENT'){ err.message = 'File not found'; }
  res.status(err.status).json({
    msg     : err.message
    ,id     : err.id
    ,status : err.status
  });
  next();
});

// Require the debugger and run node-inspector
// var inspector = require('delay-debug');
// inspector();

Configuration

Using conf-stack, create a conf directory and add the following to base.yaml, note that you will need to change /gui for whichever path the gui middleware is located at. Also pick a base path for your api, like /api and put all routes there

base.yaml

modrewrite:
  # Sample redirection, your api should be at api/base or so
  - "/some/url/from/api /api/redirect/here/as/last [L]"

  # Redirection for frontend
  - "^/sample(.+)?$ /gui/?file=app.html&appName=sample-app [L]" # To reuse an html for multilpe websdk builds
  - "^/$ /gui?file=app.html&appName=sample-app [L]" # Will serve app.html on root
    
  - "^/(?!gui(\\/)?)(.+\\..{2,5})$ /gui?file=$2 [L]" # If not for /gui, but has an extension then send the request to gui
  - "^/((?!api|gui\\/).+)*$ /gui?file=app.html&appName=sample-app [L]" # Any other request will always serve the app
  # - "^/(gui\\/)?((?!api\\/).+)*$ /gui?file=$2" # Everything that is not under /api/ goes to gui

expressgui:
  route: true # If it should automatically create a /gui route or not
  dir: gui # Which directory to load the gui file from
  root: <process.mainModule.filename directory> # Which directory to use as root, leave empty to use relative to the main file 

public:
  any: config set here will be delivered as config.json

NOTE: When using modrewrite and conf-stack (and defining routes other than in base.yaml) you might want to define modrewrite as an object with keys (0...100) and use the following to create the array var rewrites = Object.keys(config.modrewrite||[]).sort().map(it=>config.modrewrite[it]).filter(it=>it);, since confstack also merges arrays by index

How to deliver user data

Up to your implementation, but this is the suggested approach:

Create a properties.js within your gui/dynamic directory.

// Expose the properties globally
var PROPERTIES = {
  config : ${configStr}
  ,user  : "${user.username}"
}

In an app.html you can now load your propeties

<!DOCTYPE html>
<html>
<head>
<script src="properties.js"></script>
<script>
  console.log(PROPERTIES);
</script>
</head>
<body></body>
</html>

Data exposed to dynamic the dynamic page

configStr  : JSON.stringify(config.public)
,config    : config.public
,files     : dynamicFilesMap
,anonymous : (req.session && req.session.anonymous) ? req.session.anonymous : {} // If the session has anonymous data then use it
,user      : (req.session && req.session.user) ? req.session.user : {}
,session   : req.session || {}
,appName   : (req.query&&req.query.appName ? req.query.appName : 'main-app')
,query     : req.query
,body      : req.body
,req       : req
,res       : res

Need a debugger?

Use node-inspector through delay-debug

Useful server snippet

Refer to test directory. Use that setup.