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

norma

v3.1.1

Published

A function argument organizer

Downloads

29,322

Readme

norma

A function argument organizer

Sometimes you want your functions to accept optional arguments. It makes your API nicer.

Support

If you're using this module, feel free to contact me on twitter if you have any questions! :) @rjrodger

Current Version: 0.3.0

Tested on: node 0.10.26

Build Status

Annotated Source

Gitter chat

Usage

Let's take an example. Say your the basic function signature is:

myAPI.doStuff( 'the-stuff', function( err, result ){ ... } )

But you also want to support options:

myAPI.doStuff( 'the-stuff', 
               { option1:'foo', option2:'bar'}, 
               function( err, result ){ ... } )

The callback should be the last argument. That's the style. So you have to write a bit of logic to test if the second argument is an object or a function and act appropriately. Ths is cruft code getting in the way of real work.

myAPI.doStuff = function(){
  var stuff    = arguments[0]
  var options  = 'function' == typeof(arguments[1]) ? {} : arguments[1]
  var callback = 'function' == typeof(arguments[2]) ? arguments[2] : arguments[1]
  ...
}

With this module, you specify what you want using a simple expression language:

myAPI.doStuff = function(){
  var args = norma('so?f',arguments)

  var stuff    = args[0]
  var options  = args[1] || {}
  var callback = args[2]
}

Now your arguments always come back in a well-defined array, and always at the same index.

The expression 'so?f' means match: a string, an optional object, and a function

You can also assign names:

myAPI.doStuff = function(){
  var args = norma('stuff:s options:o? callback:f',arguments)
  // args == {stuff:..., options:..., callback:...}
  args.options = args.options || {}
}

And of course, if your function is called with arguments that do not match the expression, then an error is thrown.

Support

If you're using this module, feel free to contact me on twitter if you have any questions! :) @rjrodger

Current Version: 0.2.6

Tested on: node 0.10.26

Build Status

Quick example

var norma = require('norma')

function foo() {
  var args = norma('sf', arguments)

  var content = args[0]  // s => string, required
  var cb      = args[1]  // f => function, required

  cb(null,content+'!')
}

foo('bar',function(err,out){
  console.log(out)
})

Install

npm install norma

Function Signature Expression

The expression you use to define the function argument types that you expect is a string containing individual characters that stand for JavaScript types. Each type is a single character. These are:

  • s - string
  • i - integer
  • n - number
  • b - boolean
  • f - function
  • a - array
  • o - object
  • r - regexp
  • d - date
  • g - arguments
  • e - error
  • N - null
  • U - undefined
  • A - NaN
  • Y - Infinity

You list the types you expect, in the order you expect. The norma module will return an array with each position corresponding to the position of each type letter.

This works like so:

  • "s" => [string] => [ "Foo" ]
  • "si" => [string, integer] => [ "Foo", 123 ]
  • "sbi" => [string, boolean, integer] => [ "Foo", true, 123 ]

The syntax of the expression is similar to a regular expression (but it's not one!). You can use these special characters:

  • . - match any type
  • ? - preceding type is optional (also matches null, undefined, and NaN)
      • preceding type can occur any number of times (including zero)
      • preceding type can occur any number of times (but must occur at least once)
  • | - set of alternate types that are valid in this argument position

Now you can do this:

  • "so?f" => [ string, optional object, function ] => [ "a", function(){...} ]; [ "a", {b:1}, function(){...} ]
  • "s?n" => [ optional string, number ] => [ "a", 1 ]; [ 1 ]
  • "si*" => [ string, zero or more integers... ] => [ "a" ]; [ "a", 1 ]; [ a, 1, 2 ]; [ a, 1, 2, 3 ]
  • "si+" => [ string, one or more integers... ] => [ "a", 1 ]; [ a, 1, 2 ]; [ a, 1, 2, 3 ]
  • "s.*" => [ string, anything... ] => [ "a", true ]; [ a, {}, [] ]; [ a, 3, {}, true, /hola/ ]
  • "s|if" => [ string or integer, function ] => [ "a", function(){...} ]; [ 1, function(){...} ];

You can use whitespace and commas to make things more readable:

  • "so?f" === "s o? f" === "s, o?, f"

If no match is found for a given position, undefined is used as the placeholder:

  • "si*" on [ "a" ] gives [ "a", undefined ]
  • "s.*b" on [ "a", true ] gives [ "a", undefined, true ]

Alternates can also be optional, so this works too:

  • "s|i? b" => [ optional string or integer, boolean ] => [ true ]; [ "a", true ]; [ 1, true ];

Note that you'll get an undefined as the placeholder, as usual:

  • "s|i? b" on [ true ]; [ "a", true ]; [ 1, true ]; gives [ undefined, true ]; [ "a", true ]; [ 1, true ];

You can also give arguments names. These are set as properties on the returned array, as well being assigned an index:

  • "foo:s" => [ "val", foo:"val" ] // in util.inspect output format

If you really want an object, use the form:

  • "{foo:s}" => { foo:"val" }

If you use the * modifier, and a name, then you'll get back an array listing all the matches (zero or more).

  • "{foo:s*}" => { foo: ["v1","v2",...] }

And that's it!

Compiling patterns

You can compile a pattern ahead of time:

var norma = require('norma')

var needstring = norma.compile('s')

function foo() {
  var args = needstring( arguments )
  console.log( 'string:'+args[0] ) 
}

How it Works

The parser uses PEG.js to understand the signature expression, and then it builds an internal regular expression to match the function argument types.

The source code is annotated.

Development

Edit norma-parser.pegjs to modify the grammar. Rebuild with npm run build.

Test with:

npm test