Comparing version 1.0.0 to 2.0.1
266
norma.js
/* Copyright (c) 2014-2015 Richard Rodger, MIT License */ | ||
/* jshint node:true, asi:true, eqnull:true */ | ||
"use strict"; | ||
'use strict' | ||
// TODO: allow _ and $ in named args !!! doh! | ||
// #### System modules | ||
var util = require('util') | ||
// #### External modules | ||
var _ = require('lodash') | ||
var error = require('eraro')({package:'norma'}) | ||
var _ = {} | ||
_.isNaN = require('lodash.isnan') | ||
_.isRegExp = require('lodash.isregexp') | ||
_.isDate = require('lodash.isdate') | ||
_.isArguments = require('lodash.isarguments') | ||
var error = require('eraro')({ package: 'norma' }) | ||
@@ -21,32 +22,29 @@ // #### Internal modules | ||
// Default options. | ||
var defopts = { | ||
onfail:'throw', | ||
desclen:33 | ||
onfail: 'throw', | ||
desclen: 33 | ||
} | ||
// Cache of previously seen type specs. | ||
var specmap = {} | ||
// #### Compile type spec into a regexp | ||
function compile( spec ) { | ||
if( null == spec ) throw error('no_spec', 'no argument specification'); | ||
function compile(spec) { | ||
if (null == spec) throw error('no_spec', 'no argument specification') | ||
var specdef = specmap[spec] | ||
if( null != specdef ) return specdef; | ||
if (null != specdef) return specdef | ||
var respec = parse_spec( spec ) | ||
var respec = parse_spec(spec) | ||
// Build regex. | ||
var reindex = [] | ||
var index = 1 | ||
var index = 1 | ||
var restr = ['^'] | ||
var i = 0 | ||
respec.forEach(function(entry){ | ||
respec.forEach(function(entry) { | ||
restr.push('(') | ||
if( entry.type.or && 0 < entry.type.or.length ) { | ||
if (entry.type.or && 0 < entry.type.or.length) { | ||
var count = 1 | ||
@@ -58,3 +56,3 @@ | ||
entry.type.or.forEach(function(or){ | ||
entry.type.or.forEach(function(or) { | ||
restr.push('|') | ||
@@ -67,20 +65,17 @@ restr.push('(') | ||
if( '?' == entry.mod ) { | ||
if ('?' == entry.mod) { | ||
restr.push('|[UNA]?') | ||
} | ||
reindex[i]={index:index} | ||
reindex[i] = { index: index } | ||
index += count | ||
} | ||
else { | ||
if( '?' == entry.mod ) { | ||
restr.push('[UNA'+entry.type.mark+']?') | ||
} | ||
else { | ||
restr.push(entry.type.mark); | ||
} else { | ||
if ('?' == entry.mod) { | ||
restr.push('[UNA' + entry.type.mark + ']?') | ||
} else { | ||
restr.push(entry.type.mark) | ||
restr.push(entry.mod || '') | ||
} | ||
reindex[i]={index:index} | ||
reindex[i] = { index: index } | ||
} | ||
@@ -96,35 +91,49 @@ | ||
var re = new RegExp(restr.join('')) | ||
specdef = specmap[spec] = {re:re,spec:spec,respec:respec,reindex:reindex} | ||
specdef = specmap[spec] = { | ||
re: re, | ||
spec: spec, | ||
respec: respec, | ||
reindex: reindex | ||
} | ||
return specdef; | ||
return specdef | ||
} | ||
function parse_spec( spec ) { | ||
function parse_spec(spec) { | ||
try { | ||
return parser.parse( spec ) | ||
return parser.parse(spec) | ||
} catch (e) { | ||
throw error( | ||
'parse', | ||
e.message + | ||
'; spec:"' + | ||
spec + | ||
'", col:' + | ||
e.location.start.column + | ||
', line:' + | ||
e.location.start.line | ||
) | ||
} | ||
catch(e) { | ||
throw error('parse', e.message+'; spec:"'+spec+ | ||
'", col:'+e.location.start.column+', line:'+e.location.start.line) | ||
} | ||
} | ||
// #### Create output array or object with organised argument values. | ||
function processargs( specdef, options, rawargs ) { | ||
var args = Array.prototype.slice.call(rawargs||[]) | ||
var argdesc = describe( args ) | ||
function processargs(specdef, options, rawargs) { | ||
var args = Array.prototype.slice.call(rawargs || []) | ||
var argdesc = describe(args) | ||
// Match the spec regexp against the argument types regexp. | ||
var outslots = specdef.re.exec(argdesc) | ||
if( !outslots ) { | ||
if( 'throw' == options.onfail ) { | ||
if (!outslots) { | ||
if ('throw' == options.onfail) { | ||
throw error( | ||
'invalid_arguments', | ||
'invalid arguments; expected: "'+specdef.spec+ | ||
'", was: ['+argdesc+']; values: '+descargs(args,options), | ||
{args:args,specdef:specdef,options:options}) | ||
} | ||
else return null; | ||
'invalid_arguments', | ||
'invalid arguments; expected: "' + | ||
specdef.spec + | ||
'", was: [' + | ||
argdesc + | ||
']; values: ' + | ||
descargs(args, options), | ||
{ args: args, specdef: specdef, options: options } | ||
) | ||
} else return null | ||
} | ||
@@ -135,14 +144,14 @@ | ||
var out = specdef.respec.object ? {} : [] | ||
for(var i = 0, j = 0, k = 0; i < specdef.reindex.length; i++ ) { | ||
for (var i = 0, j = 0, k = 0; i < specdef.reindex.length; i++) { | ||
var indexspec = specdef.reindex[i] | ||
var val = void 0 | ||
if( !specdef.respec.object ) { | ||
if (!specdef.respec.object) { | ||
out[k] = val | ||
} | ||
if( null != indexspec.index) { | ||
if (null != indexspec.index) { | ||
var m = outslots[indexspec.index] | ||
var found = ('' !== m) | ||
if( found ) { | ||
var found = '' !== m | ||
if (found) { | ||
var iname = specdef.respec[i].name | ||
@@ -152,22 +161,26 @@ var istar = '*' === specdef.respec[i].mod | ||
if( 0 === m.length && iplus ) { | ||
if (0 === m.length && iplus) { | ||
throw error( | ||
'invalid_arguments', | ||
'invalid arguments; expected: "'+specdef.spec+ | ||
'", was: ['+argdesc+']; values: '+descargs(args,options), | ||
{args:args,specdef:specdef,options:options}) | ||
'invalid_arguments', | ||
'invalid arguments; expected: "' + | ||
specdef.spec + | ||
'", was: [' + | ||
argdesc + | ||
']; values: ' + | ||
descargs(args, options), | ||
{ args: args, specdef: specdef, options: options } | ||
) | ||
} | ||
if( 1 == m.length ) { | ||
if (1 == m.length) { | ||
val = args[j] | ||
j++ | ||
if( !specdef.respec.object ) { | ||
if (!specdef.respec.object) { | ||
out[k] = val | ||
} | ||
if( null != iname ) { | ||
if( istar || iplus ) { | ||
(out[iname] = (out[iname] || [])).push(val) | ||
} | ||
else { | ||
if (null != iname) { | ||
if (istar || iplus) { | ||
;(out[iname] = out[iname] || []).push(val) | ||
} else { | ||
out[specdef.respec[i].name] = val | ||
@@ -178,14 +191,13 @@ } | ||
k++ | ||
} | ||
else if( 1 < m.length ) { | ||
for( var mI = 0; mI < m.length; mI++ ) { | ||
} else if (1 < m.length) { | ||
for (var mI = 0; mI < m.length; mI++) { | ||
val = args[j] | ||
j++ | ||
if( !specdef.respec.object ) { | ||
if (!specdef.respec.object) { | ||
out[k] = val | ||
} | ||
if( null != iname ) { | ||
(out[iname] = (out[iname] || [])).push(val) | ||
if (null != iname) { | ||
;(out[iname] = out[iname] || []).push(val) | ||
} | ||
@@ -196,5 +208,4 @@ | ||
} | ||
} | ||
else { | ||
if( !specdef.respec.object ) { | ||
} else { | ||
if (!specdef.respec.object) { | ||
out[k] = void 0 | ||
@@ -207,7 +218,5 @@ } | ||
return out; | ||
return out | ||
} | ||
// #### Create a type description of the arguments array | ||
@@ -218,5 +227,4 @@ // Example: ["a",1] => "si". | ||
args.forEach(function(arg){ | ||
if( _.isString(arg) ) { | ||
args.forEach(function(arg) { | ||
if ('string' === typeof arg) { | ||
desc.push('s') | ||
@@ -226,30 +234,21 @@ } | ||
// Need to check for integer first. | ||
else if( (!isNaN(arg) && ((arg | 0) === parseFloat(arg))) ) { | ||
else if (!isNaN(arg) && (arg | 0) === parseFloat(arg)) { | ||
desc.push('i') | ||
} | ||
else if( _.isNaN(arg) ) { | ||
} else if (_.isNaN(arg)) { | ||
desc.push('A') | ||
} | ||
else if( Infinity === arg ) { | ||
} else if (Infinity === arg) { | ||
desc.push('Y') | ||
} | ||
else if( _.isNumber(arg) ) { | ||
} else if ('number' === typeof arg) { | ||
desc.push('n') | ||
} | ||
else if( _.isBoolean(arg) ) { | ||
} else if ('boolean' === typeof arg) { | ||
desc.push('b') | ||
} | ||
else if( _.isFunction(arg) ) { | ||
} else if ('function' === typeof arg) { | ||
desc.push('f') | ||
} | ||
else if( _.isArray(arg) ) { | ||
} else if (Array.isArray(arg)) { | ||
desc.push('a') | ||
} | ||
else if( _.isRegExp(arg) ) { | ||
} else if (_.isRegExp(arg)) { | ||
desc.push('r') | ||
} | ||
else if( _.isDate(arg) ) { | ||
} else if (_.isDate(arg)) { | ||
desc.push('d') | ||
} | ||
else if( _.isArguments(arg) ) { | ||
} else if (_.isArguments(arg)) { | ||
desc.push('g') | ||
@@ -259,13 +258,9 @@ } | ||
// Use standard Node.js API for _isError_ test. | ||
else if( util.isError(arg) ) { | ||
else if (util.isError(arg)) { | ||
desc.push('e') | ||
} | ||
else if( _.isNull(arg) ) { | ||
} else if (null === arg) { | ||
desc.push('N') | ||
} | ||
else if( _.isUndefined(arg) ) { | ||
} else if (undefined === arg) { | ||
desc.push('U') | ||
} | ||
else if( _.isObject(arg) ) { | ||
} else if ('object' === typeof arg) { | ||
desc.push('o') | ||
@@ -283,10 +278,9 @@ } | ||
// #### Describe arguments array for error message | ||
// Avoids over long messages. | ||
function descargs( args, options ) { | ||
function descargs(args, options) { | ||
var desc = [] | ||
_.each(args,function(arg){ | ||
var str = util.inspect(arg).substring(0,options.desclen) | ||
args.forEach(function(arg) { | ||
var str = util.inspect(arg).substring(0, options.desclen) | ||
desc.push(str) | ||
@@ -298,47 +292,39 @@ }) | ||
// #### Perform the actual organisation. | ||
// Options are ... optional. | ||
function handle( specdef, options, rawargs ) { | ||
if( _.isArguments(options) || _.isArray(options ) ) { | ||
function handle(specdef, options, rawargs) { | ||
if (_.isArguments(options) || Array.isArray(options)) { | ||
rawargs = options | ||
options = null | ||
} | ||
options = null == options ? defopts : _.extend({},defopts,options) | ||
options = null == options ? defopts : Object.assign({}, defopts, options) | ||
if( null == rawargs ) { | ||
if (null == rawargs) { | ||
throw error( | ||
'init', | ||
'no arguments variable; expected norma( "...", arguments ), '+ | ||
'init', | ||
'no arguments variable; expected norma( "...", arguments ), ' + | ||
'or <compiled>( arguments )', | ||
{arguments:arguments} | ||
{ arguments: arguments } | ||
) | ||
} | ||
else return processargs(specdef, options, rawargs) | ||
} else return processargs(specdef, options, rawargs) | ||
} | ||
// #### Primary API | ||
module.exports = function( spec, options, rawargs ) { | ||
var specdef = compile( spec ) | ||
return handle( specdef, options, rawargs ) | ||
module.exports = function(spec, options, rawargs) { | ||
var specdef = compile(spec) | ||
return handle(specdef, options, rawargs) | ||
} | ||
// #### Compile spec for later use | ||
// _toString_ shows you the constructed regexp (for debugging). | ||
module.exports.compile = function( spec ) { | ||
var specdef = compile( spec ) | ||
module.exports.compile = function(spec) { | ||
var specdef = compile(spec) | ||
var out = function( options, rawargs ) { | ||
return handle( specdef, options, rawargs ) | ||
var out = function(options, rawargs) { | ||
return handle(specdef, options, rawargs) | ||
} | ||
out.toString = function() { | ||
return util.inspect({spec:specdef.spec, re:''+specdef.re}) | ||
return util.inspect({ spec: specdef.spec, re: '' + specdef.re }) | ||
} | ||
return out | ||
} | ||
{ | ||
"name": "norma", | ||
"version": "1.0.0", | ||
"version": "2.0.1", | ||
"description": "A function argument organizer", | ||
@@ -10,4 +10,6 @@ "main": "norma.js", | ||
"clean": "rm -rf node_modules yarn.lock package-lock.json", | ||
"repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags", | ||
"repo-publish": "npm run repo-tag && npm publish --access public" | ||
"prettier": "prettier --write --no-semi --single-quote norma.js lib/*.js test/*.js", | ||
"reset": "npm run clean && npm i && npm test", | ||
"repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;", | ||
"repo-publish": "npm run prettier && npm test && npm run repo-tag && npm publish --registry http://registry.npmjs.org " | ||
}, | ||
@@ -37,10 +39,13 @@ "repository": { | ||
"docco": "^0.8.0", | ||
"jshint": "^2.10.2", | ||
"mocha": "^6.2.0", | ||
"jshint": "^2.10.3", | ||
"mocha": "^6.2.2", | ||
"pegjs": "^0.10.0", | ||
"uglify-js": "^3.6.0" | ||
"uglify-js": "^3.7.1" | ||
}, | ||
"dependencies": { | ||
"eraro": "^1.1.0", | ||
"lodash": "^4.17.15" | ||
"eraro": "^2.0.0", | ||
"lodash.isarguments": "^3.1.0", | ||
"lodash.isdate": "^4.0.1", | ||
"lodash.isnan": "^3.0.2", | ||
"lodash.isregexp": "^4.0.1" | ||
}, | ||
@@ -47,0 +52,0 @@ "files": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54941
1317
5
+ Addedlodash.isarguments@^3.1.0
+ Addedlodash.isdate@^4.0.1
+ Addedlodash.isnan@^3.0.2
+ Addedlodash.isregexp@^4.0.1
+ Addederaro@2.1.0(transitive)
+ Addedlodash._reinterpolate@3.0.0(transitive)
+ Addedlodash.isarguments@3.1.0(transitive)
+ Addedlodash.isdate@4.0.1(transitive)
+ Addedlodash.isnan@3.0.2(transitive)
+ Addedlodash.isregexp@4.0.1(transitive)
+ Addedlodash.template@4.5.0(transitive)
+ Addedlodash.templatesettings@4.2.0(transitive)
- Removedlodash@^4.17.15
- Removederaro@1.1.0(transitive)
- Removedlodash@4.17.21(transitive)
Updatederaro@^2.0.0