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 🙏

© 2026 – Pkg Stats / Ryan Hefner

zetan

v0.0.37

Published

Super Middleware

Readme

Zeta Negroni: My greatest hits (In progress)

Start

var zetan = require('zetan');
var port = process.env.PORT || 5690;
var options = {
	debug:true
};
zetan.serve(port,options);

Or

just plug the middleware

var express = require('express');
var app = express();
var zetan = require('zetan');
var port = 5678;

app.use(zetan({
	debug:true
}));

app.listen(port,function () {
	// c global object is a tracer logger
	c.log('api running on http://localhost:' + port);
});

APPs

an app is a module in the "apps" directory. it handle server and client side javascript. templating and css (less).

http://localhost:5678/
# will load the app in the apps/index directory

http://localhost:5678/friends
# will load the app in the apps/friends directory

Example structure:

  • index.js
  • apps
    • index
      • index.js
      • template.html
    • friends
      • index.js
      • template.html
    • aboutus
      • template.html

apps have to export a "render" method, a "middleware" method or both.

// file: apps/index/index.js

var q = require('q');

// first param is data setted by zetan
// the promise reponse will be render in the "template.html" if this exists
// if not it just repond the object as plain json

exports.render = function(data,zetan){
	// data is sent by the middleware (custom or default zetan middleware)
	// data.req and data.res are sent

	var deferred = q.defer();
	deferred.resolve({a:'hola'});
	return deferred.promise;
	// it has to respond a promise
}

// if middleware method exists it's used to set data to be passed to render method

exports.middleware = function(req,res,render){
	var data = {
		text:'this is passed to the render method',
		params:req.query
	}
	render(data);
}

template.html

template.html file is a Mustache template. it receive data sent by the render method. it used triple curly braces notation: {{{var}}}

if template exists alone inside the app module, zetan will return the static html as response.

partial loader

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">	
</head>
<body>
	<!-- partial function can be used within templates -->
	{{{#partial}}}partials/header.html{{{/partial}}}
</body>
</html>

client.js

a client.js can be included in the app directory

apps/index/client.js

and call it from the template like this:

<!DOCTYPE html>
<html lang="en">
<head>
	<script src="{{{appName}}}}/client.js"></script>
	...

it is browserified by zetan before response

client.less

a styles.less can be included in the app directory

apps/index/styles.less

and called it from the template like this:

<!DOCTYPE html>
<html lang="en">
<head>
	<link rel="stylesheet" href="{{{appName}}}}/styles.css">
	...

this will be automatically parsde by less process before response

C logger

// c global object added by zetan
c.log('use this instead console.log');

Development mode

--dev argument enables development mode. This avoid minify and and cache some things. Also enable livereload for less, templates and client.js

node index.js --dev

for nodemon

nodemon index.js --dev --ignore client.js

API

in order to create an API resource create a directory inside an api directory.

// File: api/user/index.js

var q = require('q');
var db = require('db');

exports.alias = {
	me:{
		get:function(data){
			// receive data formatted by zetan 
			// it can be overriten using a middleware method

			// it has to return a promise

			return db.find('users',{id:data.auth.id});
		}
	}
}

exports.get = function(data){
	if(data.id){
		return db.find('users',{ id:data.id });
	}else{
		// when is not and "id" zetan has an automatic pagination behaviour
		// the promise has to return an array
		return db.find('users');
	}
}

// override default zetan behaviour including pagination
// exports.middleware = function(req,res,method){
// 	method({
// 		... data to be passed to method or alias
// 	})
// }

Static Files

just create a "public" directory.

Browser

zetan client for browserify

var zetan = require('zetan/browser');

or you can use the preconfigured api client including the script from:

<script src="http://localhost:5678/api/v1/client.js"></script>

Helpers

helpers are attached to "req" object, "zetan" object and can be loaded as modules

from any module:

var emailHelper = require('zetan/helpers/email');
emailHelper.send({...})

from an app

exports.render = function(data,zetan){
	zetan.helpers.email.send({...})
}

or

exports.middleware = function(req,res,render){
	req.zetan.helpers.email.send({...})
	// or
	req.helpers.email.send({...})
}

Email

Mandrill

var mandrilAdapter = require('zetan/adapters/mandrill');
var emailHelper = require('zetan/helpers/email');

emailHelper.default(mandrilAdapter({
	apiKey:'o-Opoeml5Jl62sKlr8dxsg'
}));

emailHelper.send({
		"html": '<strong>Hi</strong>',
		"from_name":"Marcelo Zapaia",
	    "subject": "Hi there",
	    "from_email": "[email protected]",
	    "to": [{  "email": "[email protected]" }]
	}).then(function(response){
		c.log('email sent');
	}).catch(function(){
		c.log(':(');
	})

Gulp

Browserify

// gulpfile.js

var gulpHelper = require('zetan/helpers/gulp');

gulp.task('js',function(){
	return gulpHelper.browserify({ 
		watch:true, // use watchify
		src:'./src/index.js', // it can be a glob pattern like './src/*.js'
		cb:function(bundle){
			bundle.pipe(gulp.dest('./js/dist'))
		}
	})
});

LESS

// process files those names end with "*.public.less"
// in the "apps" directory and place these in "public/dist/apps/{APPNAME}/{FILENAME}.css"
gulp.task('css',gulpHelper.less());

Nodemon

// run index.js with nodemon and add an "--dev" argument
gulp.task('serve',gulpHelper.serve());