Initial commit
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
../mocha/bin/_mocha
|
||||
+1
@@ -0,0 +1 @@
|
||||
../coveralls/bin/coveralls.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../escodegen/bin/escodegen.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../escodegen/bin/esgenerate.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../esprima/bin/esparse.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../esprima/bin/esvalidate.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../handlebars/bin/handlebars
|
||||
+1
@@ -0,0 +1 @@
|
||||
../har-validator/bin/har-validator
|
||||
+1
@@ -0,0 +1 @@
|
||||
../istanbul/lib/cli.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../jade/bin/jade
|
||||
+1
@@ -0,0 +1 @@
|
||||
../js-yaml/bin/js-yaml.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../mime/cli.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../mkdirp/bin/cmd.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../mocha/bin/mocha
|
||||
+1
@@ -0,0 +1 @@
|
||||
../nopt/bin/nopt.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
../sshpk/bin/sshpk-conv
|
||||
+1
@@ -0,0 +1 @@
|
||||
../sshpk/bin/sshpk-sign
|
||||
+1
@@ -0,0 +1 @@
|
||||
../sshpk/bin/sshpk-verify
|
||||
+1
@@ -0,0 +1 @@
|
||||
../uglify-js/bin/uglifyjs
|
||||
+1
@@ -0,0 +1 @@
|
||||
../node-uuid/bin/uuid
|
||||
+1
@@ -0,0 +1 @@
|
||||
../which/bin/which
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# abbrev-js
|
||||
|
||||
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||
|
||||
Usage:
|
||||
|
||||
var abbrev = require("abbrev");
|
||||
abbrev("foo", "fool", "folding", "flop");
|
||||
|
||||
// returns:
|
||||
{ fl: 'flop'
|
||||
, flo: 'flop'
|
||||
, flop: 'flop'
|
||||
, fol: 'folding'
|
||||
, fold: 'folding'
|
||||
, foldi: 'folding'
|
||||
, foldin: 'folding'
|
||||
, folding: 'folding'
|
||||
, foo: 'foo'
|
||||
, fool: 'fool'
|
||||
}
|
||||
|
||||
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
|
||||
module.exports = exports = abbrev.abbrev = abbrev
|
||||
|
||||
abbrev.monkeyPatch = monkeyPatch
|
||||
|
||||
function monkeyPatch () {
|
||||
Object.defineProperty(Array.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(this) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
|
||||
Object.defineProperty(Object.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(Object.keys(this)) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
}
|
||||
|
||||
function abbrev (list) {
|
||||
if (arguments.length !== 1 || !Array.isArray(list)) {
|
||||
list = Array.prototype.slice.call(arguments, 0)
|
||||
}
|
||||
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
|
||||
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
|
||||
}
|
||||
|
||||
// sort them lexicographically, so that they're next to their nearest kin
|
||||
args = args.sort(lexSort)
|
||||
|
||||
// walk through each, seeing how much it has in common with the next and previous
|
||||
var abbrevs = {}
|
||||
, prev = ""
|
||||
for (var i = 0, l = args.length ; i < l ; i ++) {
|
||||
var current = args[i]
|
||||
, next = args[i + 1] || ""
|
||||
, nextMatches = true
|
||||
, prevMatches = true
|
||||
if (current === next) continue
|
||||
for (var j = 0, cl = current.length ; j < cl ; j ++) {
|
||||
var curChar = current.charAt(j)
|
||||
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||
if (!nextMatches && !prevMatches) {
|
||||
j ++
|
||||
break
|
||||
}
|
||||
}
|
||||
prev = current
|
||||
if (j === cl) {
|
||||
abbrevs[current] = current
|
||||
continue
|
||||
}
|
||||
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
|
||||
abbrevs[a] = current
|
||||
a += current.charAt(j)
|
||||
}
|
||||
}
|
||||
return abbrevs
|
||||
}
|
||||
|
||||
function lexSort (a, b) {
|
||||
return a === b ? 0 : a > b ? 1 : -1
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"abbrev@1.0.x",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/istanbul"
|
||||
]
|
||||
],
|
||||
"_from": "abbrev@>=1.0.0 <1.1.0",
|
||||
"_id": "abbrev@1.0.9",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/abbrev",
|
||||
"_nodeVersion": "4.4.4",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-16-east.internal.npmjs.com",
|
||||
"tmp": "tmp/abbrev-1.0.9.tgz_1466016055839_0.7825860097073019"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "i@izs.me",
|
||||
"name": "isaacs"
|
||||
},
|
||||
"_npmVersion": "3.9.1",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "abbrev",
|
||||
"raw": "abbrev@1.0.x",
|
||||
"rawSpec": "1.0.x",
|
||||
"scope": null,
|
||||
"spec": ">=1.0.0 <1.1.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/istanbul",
|
||||
"/nopt"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
|
||||
"_shasum": "91b4792588a7738c25f35dd6f63752a2f8776135",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "abbrev@1.0.x",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/istanbul",
|
||||
"author": {
|
||||
"email": "i@izs.me",
|
||||
"name": "Isaac Z. Schlueter"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/isaacs/abbrev-js/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"devDependencies": {
|
||||
"tap": "^5.7.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "91b4792588a7738c25f35dd6f63752a2f8776135",
|
||||
"tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
|
||||
},
|
||||
"files": [
|
||||
"abbrev.js"
|
||||
],
|
||||
"gitHead": "c386cd9dbb1d8d7581718c54d4ba944cc9298d6f",
|
||||
"homepage": "https://github.com/isaacs/abbrev-js#readme",
|
||||
"license": "ISC",
|
||||
"main": "abbrev.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "isaacs",
|
||||
"email": "i@izs.me"
|
||||
}
|
||||
],
|
||||
"name": "abbrev",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test.js --cov"
|
||||
},
|
||||
"version": "1.0.9"
|
||||
}
|
||||
+212
@@ -0,0 +1,212 @@
|
||||
1.3.3 / 2016-05-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.11
|
||||
- deps: mime-db@~1.23.0
|
||||
* deps: negotiator@0.6.1
|
||||
- perf: improve `Accept` parsing speed
|
||||
- perf: improve `Accept-Charset` parsing speed
|
||||
- perf: improve `Accept-Encoding` parsing speed
|
||||
- perf: improve `Accept-Language` parsing speed
|
||||
|
||||
1.3.2 / 2016-03-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.10
|
||||
- Fix extension of `application/dash+xml`
|
||||
- Update primary extension for `audio/mp4`
|
||||
- deps: mime-db@~1.22.0
|
||||
|
||||
1.3.1 / 2016-01-19
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.9
|
||||
- deps: mime-db@~1.21.0
|
||||
|
||||
1.3.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.7
|
||||
- deps: mime-db@~1.19.0
|
||||
* deps: negotiator@0.6.0
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Lazy-load modules from main entry point
|
||||
- perf: delay type concatenation until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove closures getting spec properties
|
||||
- perf: remove a closure from media type parsing
|
||||
- perf: remove property delete from media type parsing
|
||||
|
||||
1.2.13 / 2015-09-06
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.6
|
||||
- deps: mime-db@~1.18.0
|
||||
|
||||
1.2.12 / 2015-07-30
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.4
|
||||
- deps: mime-db@~1.16.0
|
||||
|
||||
1.2.11 / 2015-07-16
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.3
|
||||
- deps: mime-db@~1.15.0
|
||||
|
||||
1.2.10 / 2015-07-01
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.2
|
||||
- deps: mime-db@~1.14.0
|
||||
|
||||
1.2.9 / 2015-06-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.1
|
||||
- perf: fix deopt during mapping
|
||||
|
||||
1.2.8 / 2015-06-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.0
|
||||
- deps: mime-db@~1.13.0
|
||||
* perf: avoid argument reassignment & argument slice
|
||||
* perf: avoid negotiator recursive construction
|
||||
* perf: enable strict mode
|
||||
* perf: remove unnecessary bitwise operator
|
||||
|
||||
1.2.7 / 2015-05-10
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.3
|
||||
- Fix media type parameter matching to be case-insensitive
|
||||
|
||||
1.2.6 / 2015-05-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.11
|
||||
- deps: mime-db@~1.9.1
|
||||
* deps: negotiator@0.5.2
|
||||
- Fix comparing media types with quoted values
|
||||
- Fix splitting media types with quoted commas
|
||||
|
||||
1.2.5 / 2015-03-13
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.10
|
||||
- deps: mime-db@~1.8.0
|
||||
|
||||
1.2.4 / 2015-02-14
|
||||
==================
|
||||
|
||||
* Support Node.js 0.6
|
||||
* deps: mime-types@~2.0.9
|
||||
- deps: mime-db@~1.7.0
|
||||
* deps: negotiator@0.5.1
|
||||
- Fix preference sorting to be stable for long acceptable lists
|
||||
|
||||
1.2.3 / 2015-01-31
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.8
|
||||
- deps: mime-db@~1.6.0
|
||||
|
||||
1.2.2 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.7
|
||||
- deps: mime-db@~1.5.0
|
||||
|
||||
1.2.1 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.5
|
||||
- deps: mime-db@~1.3.1
|
||||
|
||||
1.2.0 / 2014-12-19
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.0
|
||||
- Fix list return order when large accepted list
|
||||
- Fix missing identity encoding when q=0 exists
|
||||
- Remove dynamic building of Negotiator class
|
||||
|
||||
1.1.4 / 2014-12-10
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.4
|
||||
- deps: mime-db@~1.3.0
|
||||
|
||||
1.1.3 / 2014-11-09
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.3
|
||||
- deps: mime-db@~1.2.0
|
||||
|
||||
1.1.2 / 2014-10-14
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.9
|
||||
- Fix error when media type has invalid parameter
|
||||
|
||||
1.1.1 / 2014-09-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.2
|
||||
- deps: mime-db@~1.1.0
|
||||
* deps: negotiator@0.4.8
|
||||
- Fix all negotiations to be case-insensitive
|
||||
- Stable sort preferences of same quality according to client order
|
||||
|
||||
1.1.0 / 2014-09-02
|
||||
==================
|
||||
|
||||
* update `mime-types`
|
||||
|
||||
1.0.7 / 2014-07-04
|
||||
==================
|
||||
|
||||
* Fix wrong type returned from `type` when match after unknown extension
|
||||
|
||||
1.0.6 / 2014-06-24
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.7
|
||||
|
||||
1.0.5 / 2014-06-20
|
||||
==================
|
||||
|
||||
* fix crash when unknown extension given
|
||||
|
||||
1.0.4 / 2014-06-19
|
||||
==================
|
||||
|
||||
* use `mime-types`
|
||||
|
||||
1.0.3 / 2014-06-11
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.6
|
||||
- Order by specificity when quality is the same
|
||||
|
||||
1.0.2 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix interpretation when header not in request
|
||||
* deps: pin negotiator@0.4.5
|
||||
|
||||
1.0.1 / 2014-01-18
|
||||
==================
|
||||
|
||||
* Identity encoding isn't always acceptable
|
||||
* deps: negotiator@~0.4.0
|
||||
|
||||
1.0.0 / 2013-12-27
|
||||
==================
|
||||
|
||||
* Genesis
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
# accepts
|
||||
|
||||
[![NPM Version][npm-image]][npm-url]
|
||||
[![NPM Downloads][downloads-image]][downloads-url]
|
||||
[![Node.js Version][node-version-image]][node-version-url]
|
||||
[![Build Status][travis-image]][travis-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator). Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||
|
||||
In addition to negotiator, it allows:
|
||||
|
||||
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` as well as `('text/html', 'application/json')`.
|
||||
- Allows type shorthands such as `json`.
|
||||
- Returns `false` when no types match
|
||||
- Treats non-existent headers as `*`
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install accepts
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
```
|
||||
|
||||
### accepts(req)
|
||||
|
||||
Create a new `Accepts` object for the given `req`.
|
||||
|
||||
#### .charset(charsets)
|
||||
|
||||
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .charsets()
|
||||
|
||||
Return the charsets that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .encoding(encodings)
|
||||
|
||||
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .encodings()
|
||||
|
||||
Return the encodings that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .language(languages)
|
||||
|
||||
Return the first accepted language. If nothing in `languages` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .languages()
|
||||
|
||||
Return the languages that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .type(types)
|
||||
|
||||
Return the first accepted type (and it is returned as the same text as what
|
||||
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||
is returned.
|
||||
|
||||
The `types` array can contain full MIME types or file extensions. Any value
|
||||
that is not a full MIME types is passed to `require('mime-types').lookup`.
|
||||
|
||||
#### .types()
|
||||
|
||||
Return the types that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple type negotiation
|
||||
|
||||
This simple example shows how to use `accepts` to return a different typed
|
||||
respond body based on what the client wants to accept. The server lists it's
|
||||
preferences in order and will get back the best match between the client and
|
||||
server.
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
var http = require('http')
|
||||
|
||||
function app(req, res) {
|
||||
var accept = accepts(req)
|
||||
|
||||
// the order of this list is significant; should be server preferred order
|
||||
switch(accept.type(['json', 'html'])) {
|
||||
case 'json':
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.write('{"hello":"world!"}')
|
||||
break
|
||||
case 'html':
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.write('<b>hello, world!</b>')
|
||||
break
|
||||
default:
|
||||
// the fallback is text/plain, so no need to specify it above
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.write('hello, world!')
|
||||
break
|
||||
}
|
||||
|
||||
res.end()
|
||||
}
|
||||
|
||||
http.createServer(app).listen(3000)
|
||||
```
|
||||
|
||||
You can test this out with the cURL program:
|
||||
```sh
|
||||
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/accepts.svg
|
||||
[npm-url]: https://npmjs.org/package/accepts
|
||||
[node-version-image]: https://img.shields.io/node/v/accepts.svg
|
||||
[node-version-url]: http://nodejs.org/download/
|
||||
[travis-image]: https://img.shields.io/travis/jshttp/accepts/master.svg
|
||||
[travis-url]: https://travis-ci.org/jshttp/accepts
|
||||
[coveralls-image]: https://img.shields.io/coveralls/jshttp/accepts/master.svg
|
||||
[coveralls-url]: https://coveralls.io/r/jshttp/accepts
|
||||
[downloads-image]: https://img.shields.io/npm/dm/accepts.svg
|
||||
[downloads-url]: https://npmjs.org/package/accepts
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
/*!
|
||||
* accepts
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var Negotiator = require('negotiator')
|
||||
var mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = Accepts
|
||||
|
||||
/**
|
||||
* Create a new Accepts object for the given req.
|
||||
*
|
||||
* @param {object} req
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Accepts(req) {
|
||||
if (!(this instanceof Accepts))
|
||||
return new Accepts(req)
|
||||
|
||||
this.headers = req.headers
|
||||
this.negotiator = new Negotiator(req)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `undefined`, in which
|
||||
* case you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* The `type` value may be a single mime type string
|
||||
* such as "application/json", the extension name
|
||||
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // Accept: text/html
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
* this.types('text/html');
|
||||
* // => "text/html"
|
||||
* this.types('json', 'text');
|
||||
* // => "json"
|
||||
* this.types('application/json');
|
||||
* // => "application/json"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('image/png');
|
||||
* this.types('png');
|
||||
* // => undefined
|
||||
*
|
||||
* // Accept: text/*;q=.5, application/json
|
||||
* this.types(['html', 'json']);
|
||||
* this.types('html', 'json');
|
||||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} types...
|
||||
* @return {String|Array|Boolean}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.type =
|
||||
Accepts.prototype.types = function (types_) {
|
||||
var types = types_
|
||||
|
||||
// support flattened arguments
|
||||
if (types && !Array.isArray(types)) {
|
||||
types = new Array(arguments.length)
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
types[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no types, return all requested types
|
||||
if (!types || types.length === 0) {
|
||||
return this.negotiator.mediaTypes()
|
||||
}
|
||||
|
||||
if (!this.headers.accept) return types[0];
|
||||
var mimes = types.map(extToMime);
|
||||
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime));
|
||||
var first = accepts[0];
|
||||
if (!first) return false;
|
||||
return types[mimes.indexOf(first)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted encodings or best fit based on `encodings`.
|
||||
*
|
||||
* Given `Accept-Encoding: gzip, deflate`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @param {String|Array} encodings...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.encoding =
|
||||
Accepts.prototype.encodings = function (encodings_) {
|
||||
var encodings = encodings_
|
||||
|
||||
// support flattened arguments
|
||||
if (encodings && !Array.isArray(encodings)) {
|
||||
encodings = new Array(arguments.length)
|
||||
for (var i = 0; i < encodings.length; i++) {
|
||||
encodings[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no encodings, return all requested encodings
|
||||
if (!encodings || encodings.length === 0) {
|
||||
return this.negotiator.encodings()
|
||||
}
|
||||
|
||||
return this.negotiator.encodings(encodings)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted charsets or best fit based on `charsets`.
|
||||
*
|
||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||
*
|
||||
* @param {String|Array} charsets...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.charset =
|
||||
Accepts.prototype.charsets = function (charsets_) {
|
||||
var charsets = charsets_
|
||||
|
||||
// support flattened arguments
|
||||
if (charsets && !Array.isArray(charsets)) {
|
||||
charsets = new Array(arguments.length)
|
||||
for (var i = 0; i < charsets.length; i++) {
|
||||
charsets[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no charsets, return all requested charsets
|
||||
if (!charsets || charsets.length === 0) {
|
||||
return this.negotiator.charsets()
|
||||
}
|
||||
|
||||
return this.negotiator.charsets(charsets)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted languages or best fit based on `langs`.
|
||||
*
|
||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['es', 'pt', 'en']
|
||||
*
|
||||
* @param {String|Array} langs...
|
||||
* @return {Array|String}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.lang =
|
||||
Accepts.prototype.langs =
|
||||
Accepts.prototype.language =
|
||||
Accepts.prototype.languages = function (languages_) {
|
||||
var languages = languages_
|
||||
|
||||
// support flattened arguments
|
||||
if (languages && !Array.isArray(languages)) {
|
||||
languages = new Array(arguments.length)
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
languages[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no languages, return all requested languages
|
||||
if (!languages || languages.length === 0) {
|
||||
return this.negotiator.languages()
|
||||
}
|
||||
|
||||
return this.negotiator.languages(languages)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert extnames to mime.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function extToMime(type) {
|
||||
return type.indexOf('/') === -1
|
||||
? mime.lookup(type)
|
||||
: type
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mime is valid.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function validMime(type) {
|
||||
return typeof type === 'string';
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"accepts@~1.3.3",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/express"
|
||||
]
|
||||
],
|
||||
"_from": "accepts@>=1.3.3 <1.4.0",
|
||||
"_id": "accepts@1.3.3",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/accepts",
|
||||
"_nodeVersion": "4.4.3",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-16-east.internal.npmjs.com",
|
||||
"tmp": "tmp/accepts-1.3.3.tgz_1462251932032_0.7092335098423064"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "doug@somethingdoug.com",
|
||||
"name": "dougwilson"
|
||||
},
|
||||
"_npmVersion": "2.15.1",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "accepts",
|
||||
"raw": "accepts@~1.3.3",
|
||||
"rawSpec": "~1.3.3",
|
||||
"scope": null,
|
||||
"spec": ">=1.3.3 <1.4.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/express"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
|
||||
"_shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "accepts@~1.3.3",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/express",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jshttp/accepts/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Douglas Christopher Wilson",
|
||||
"email": "doug@somethingdoug.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Ong",
|
||||
"email": "me@jongleberry.com",
|
||||
"url": "http://jongleberry.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.11",
|
||||
"negotiator": "0.6.1"
|
||||
},
|
||||
"description": "Higher-level content negotiation",
|
||||
"devDependencies": {
|
||||
"istanbul": "0.4.3",
|
||||
"mocha": "~1.21.5"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "c3ca7434938648c3e0d9c1e328dd68b622c284ca",
|
||||
"tarball": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
},
|
||||
"files": [
|
||||
"HISTORY.md",
|
||||
"LICENSE",
|
||||
"index.js"
|
||||
],
|
||||
"gitHead": "3e925b1e65ed7da2798849683d49814680dfa426",
|
||||
"homepage": "https://github.com/jshttp/accepts#readme",
|
||||
"keywords": [
|
||||
"accept",
|
||||
"accepts",
|
||||
"content",
|
||||
"negotiation"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "dougwilson",
|
||||
"email": "doug@somethingdoug.com"
|
||||
}
|
||||
],
|
||||
"name": "accepts",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jshttp/accepts.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
|
||||
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
|
||||
},
|
||||
"version": "1.3.3"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
# align-text [](http://badge.fury.io/js/align-text) [](https://travis-ci.org/jonschlinkert/align-text)
|
||||
|
||||
> Align the text in a string.
|
||||
|
||||
**Examples**
|
||||
|
||||
Align text values in an array:
|
||||
|
||||
```js
|
||||
align([1, 2, 3, 100]);
|
||||
//=> [' 1', ' 2', ' 3', '100']
|
||||
```
|
||||
|
||||
Or [do stuff like this](./example.js):
|
||||
|
||||
[](./example.js)
|
||||
|
||||
Visit [the example](./example.js) to see how this works.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i align-text --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var align = require('align-text');
|
||||
align(text, callback_function_or_integer);
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
* `text` can be a **string or array**. If a string is passed, a string will be returned. If an array is passed, an array will be returned.
|
||||
* `callback|integer`: if an integer, the text will be indented by that amount. If a function, it must return an integer representing the amount of leading indentation to use as `align` loops over each line.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
align(text, 4);
|
||||
```
|
||||
|
||||
Would align:
|
||||
|
||||
```
|
||||
abc
|
||||
abc
|
||||
abc
|
||||
```
|
||||
|
||||
To:
|
||||
|
||||
```
|
||||
abc
|
||||
abc
|
||||
abc
|
||||
```
|
||||
|
||||
## callback
|
||||
|
||||
### params
|
||||
|
||||
The callback is used to determine the indentation of each line and gets the following params:
|
||||
|
||||
* `len` the length of the "current" line
|
||||
* `longest` the length of the longest line
|
||||
* `line` the current line (string) being aligned
|
||||
* `lines` the array of all lines
|
||||
|
||||
### return
|
||||
|
||||
The callback may return:
|
||||
|
||||
* an integer that represents the number of spaces to use for padding,
|
||||
* or an object with the following properties:
|
||||
- `indent`: **{Number}** the amount of indentation to use. Default is `0` when an object is returned.
|
||||
- `character`: **{String}** the character to use for indentation. Default is `''` (empty string) when an object is returned.
|
||||
- `prefix`: **{String}** leading characters to use at the beginning of each line. `''` (empty string) when an object is returned.
|
||||
|
||||
**Integer example:**
|
||||
|
||||
```js
|
||||
// calculate half the difference between the length
|
||||
// of the current line and the longest line
|
||||
function centerAlign(len, longest, line, lines) {
|
||||
return Math.floor((longest - len) / 2);
|
||||
}
|
||||
```
|
||||
|
||||
**Object example:**
|
||||
|
||||
```js
|
||||
function centerAlign(len, longest, line, lines) {
|
||||
return {
|
||||
character: '\t',
|
||||
indent: Math.floor((longest - len) / 2),
|
||||
prefix: '~ ',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage examples
|
||||
|
||||
### Center align
|
||||
|
||||
Using the `centerAlign` function from above:
|
||||
|
||||
```js
|
||||
align(text, centerAlign);
|
||||
```
|
||||
|
||||
Would align this text:
|
||||
|
||||
```js
|
||||
Lorem ipsum dolor sit amet
|
||||
consectetur adipiscin
|
||||
elit, sed do eiusmod tempor incididun
|
||||
ut labore et dolor
|
||||
magna aliqua. Ut enim ad mini
|
||||
veniam, quis
|
||||
```
|
||||
|
||||
Resulting in this:
|
||||
|
||||
```
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing
|
||||
elit, sed do eiusmod tempor incididunt
|
||||
ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim
|
||||
veniam, quis
|
||||
```
|
||||
|
||||
**Customize**
|
||||
|
||||
If you wanted to add more padding on the left, just pass the number in the callback.
|
||||
|
||||
For example, to add 4 spaces before every line:
|
||||
|
||||
```js
|
||||
function centerAlign(len, longest, line, lines) {
|
||||
return 4 + Math.floor((longest - len) / 2);
|
||||
}
|
||||
```
|
||||
|
||||
Would result in:
|
||||
|
||||
```
|
||||
Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing
|
||||
elit, sed do eiusmod tempor incididunt
|
||||
ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim
|
||||
veniam, quis
|
||||
```
|
||||
|
||||
### Bullets
|
||||
|
||||
```js
|
||||
align(text, function (len, max, line, lines) {
|
||||
return {prefix: ' - '};
|
||||
});
|
||||
```
|
||||
|
||||
Would return:
|
||||
|
||||
```
|
||||
- Lorem ipsum dolor sit amet,
|
||||
- consectetur adipiscing
|
||||
- elit, sed do eiusmod tempor incididunt
|
||||
- ut labore et dolore
|
||||
- magna aliqua. Ut enim ad minim
|
||||
- veniam, quis
|
||||
```
|
||||
|
||||
### Different indent character
|
||||
|
||||
```js
|
||||
align(text, function (len, max, line, lines) {
|
||||
return {
|
||||
indent: Math.floor((max - len) / 2),
|
||||
character: '~',
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
Would return
|
||||
|
||||
```
|
||||
~~~~~Lorem ipsum dolor sit amet,
|
||||
~~~~~~~~consectetur adipiscing
|
||||
elit, sed do eiusmod tempor incididunt
|
||||
~~~~~~~~~ut labore et dolore
|
||||
~~~~magna aliqua. Ut enim ad minim
|
||||
~~~~~~~~~~~~~veniam, quis
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
* [center-align](https://github.com/jonschlinkert/center-align): Center-align the text in a string.
|
||||
* [justify](https://github.com/bahamas10/node-justify): Left or right (or both) justify text using a custom width and character
|
||||
* [longest](https://github.com/jonschlinkert/longest): Get the longest item in an array.
|
||||
* [right-align](https://github.com/jonschlinkert/right-align): Right-align the text in a string.
|
||||
* [repeat-string](https://github.com/jonschlinkert/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string.
|
||||
* [word-wrap](https://github.com/jonschlinkert/word-wrap): Wrap words to a specified length.
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/align-text/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 [Jon Schlinkert](https://github.com/jonschlinkert)
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on June 09, 2015._
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*!
|
||||
* align-text <https://github.com/jonschlinkert/align-text>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var typeOf = require('kind-of');
|
||||
var repeat = require('repeat-string');
|
||||
var longest = require('longest');
|
||||
|
||||
module.exports = function alignText(val, fn) {
|
||||
var lines, type = typeOf(val);
|
||||
|
||||
if (type === 'array') {
|
||||
lines = val;
|
||||
} else if (type === 'string') {
|
||||
lines = val.split(/(?:\r\n|\n)/);
|
||||
} else {
|
||||
throw new TypeError('align-text expects a string or array.');
|
||||
}
|
||||
|
||||
var fnType = typeOf(fn);
|
||||
var len = lines.length;
|
||||
var max = longest(lines);
|
||||
var res = [], i = 0;
|
||||
|
||||
while (len--) {
|
||||
var line = String(lines[i++]);
|
||||
var diff;
|
||||
|
||||
if (fnType === 'function') {
|
||||
diff = fn(line.length, max.length, line, lines, i);
|
||||
} else if (fnType === 'number') {
|
||||
diff = fn;
|
||||
} else {
|
||||
diff = max.length - line.length;
|
||||
}
|
||||
|
||||
if (typeOf(diff) === 'number') {
|
||||
res.push(repeat(' ', diff) + line);
|
||||
} else if (typeOf(diff) === 'object') {
|
||||
var result = repeat(diff.character || ' ', diff.indent || 0);
|
||||
res.push((diff.prefix || '') + result + line);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'array') return res;
|
||||
return res.join('\n');
|
||||
};
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"align-text@^0.1.3",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/center-align"
|
||||
]
|
||||
],
|
||||
"_from": "align-text@>=0.1.3 <0.2.0",
|
||||
"_id": "align-text@0.1.4",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/align-text",
|
||||
"_nodeVersion": "5.5.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-9-west.internal.npmjs.com",
|
||||
"tmp": "tmp/align-text-0.1.4.tgz_1454377856920_0.9624228512402624"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "snnskwtnb@gmail.com",
|
||||
"name": "shinnn"
|
||||
},
|
||||
"_npmVersion": "3.6.0",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "align-text",
|
||||
"raw": "align-text@^0.1.3",
|
||||
"rawSpec": "^0.1.3",
|
||||
"scope": null,
|
||||
"spec": ">=0.1.3 <0.2.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/center-align",
|
||||
"/right-align"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
|
||||
"_shasum": "0cd90a561093f35d0a99256c22b7069433fad117",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "align-text@^0.1.3",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/center-align",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/align-text/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"kind-of": "^3.0.2",
|
||||
"longest": "^1.0.1",
|
||||
"repeat-string": "^1.5.2"
|
||||
},
|
||||
"description": "Align the text in a string.",
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*",
|
||||
"word-wrap": "^1.0.3"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "0cd90a561093f35d0a99256c22b7069433fad117",
|
||||
"tarball": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"gitHead": "7f08e823a54c6bda319d875895813537a66a4c5e",
|
||||
"homepage": "https://github.com/jonschlinkert/align-text",
|
||||
"keywords": [
|
||||
"align",
|
||||
"align-center",
|
||||
"alignment",
|
||||
"center",
|
||||
"center-align",
|
||||
"indent",
|
||||
"pad",
|
||||
"padding",
|
||||
"right",
|
||||
"right-align",
|
||||
"text",
|
||||
"typography"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
{
|
||||
"name": "shinnn",
|
||||
"email": "snnskwtnb@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "align-text",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/align-text.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "0.1.4"
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
amdefine is released under two licenses: new BSD, and MIT. You may pick the
|
||||
license that best suits your development needs. The text of both licenses are
|
||||
provided below.
|
||||
|
||||
|
||||
The "New" BSD License:
|
||||
----------------------
|
||||
|
||||
Copyright (c) 2011-2016, The Dojo Foundation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the Dojo Foundation nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
|
||||
MIT License
|
||||
-----------
|
||||
|
||||
Copyright (c) 2011-2016, The Dojo Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
# amdefine
|
||||
|
||||
A module that can be used to implement AMD's define() in Node. This allows you
|
||||
to code to the AMD API and have the module work in node programs without
|
||||
requiring those other programs to use AMD.
|
||||
|
||||
## Usage
|
||||
|
||||
**1)** Update your package.json to indicate amdefine as a dependency:
|
||||
|
||||
```javascript
|
||||
"dependencies": {
|
||||
"amdefine": ">=0.1.0"
|
||||
}
|
||||
```
|
||||
|
||||
Then run `npm install` to get amdefine into your project.
|
||||
|
||||
**2)** At the top of each module that uses define(), place this code:
|
||||
|
||||
```javascript
|
||||
if (typeof define !== 'function') { var define = require('amdefine')(module) }
|
||||
```
|
||||
|
||||
**Only use these snippets** when loading amdefine. If you preserve the basic structure,
|
||||
with the braces, it will be stripped out when using the [RequireJS optimizer](#optimizer).
|
||||
|
||||
You can add spaces, line breaks and even require amdefine with a local path, but
|
||||
keep the rest of the structure to get the stripping behavior.
|
||||
|
||||
As you may know, because `if` statements in JavaScript don't have their own scope, the var
|
||||
declaration in the above snippet is made whether the `if` expression is truthy or not. If
|
||||
RequireJS is loaded then the declaration is superfluous because `define` is already already
|
||||
declared in the same scope in RequireJS. Fortunately JavaScript handles multiple `var`
|
||||
declarations of the same variable in the same scope gracefully.
|
||||
|
||||
If you want to deliver amdefine.js with your code rather than specifying it as a dependency
|
||||
with npm, then just download the latest release and refer to it using a relative path:
|
||||
|
||||
[Latest Version](https://github.com/jrburke/amdefine/raw/latest/amdefine.js)
|
||||
|
||||
### amdefine/intercept
|
||||
|
||||
Consider this very experimental.
|
||||
|
||||
Instead of pasting the piece of text for the amdefine setup of a `define`
|
||||
variable in each module you create or consume, you can use `amdefine/intercept`
|
||||
instead. It will automatically insert the above snippet in each .js file loaded
|
||||
by Node.
|
||||
|
||||
**Warning**: you should only use this if you are creating an application that
|
||||
is consuming AMD style defined()'d modules that are distributed via npm and want
|
||||
to run that code in Node.
|
||||
|
||||
For library code where you are not sure if it will be used by others in Node or
|
||||
in the browser, then explicitly depending on amdefine and placing the code
|
||||
snippet above is suggested path, instead of using `amdefine/intercept`. The
|
||||
intercept module affects all .js files loaded in the Node app, and it is
|
||||
inconsiderate to modify global state like that unless you are also controlling
|
||||
the top level app.
|
||||
|
||||
#### Why distribute AMD-style modules via npm?
|
||||
|
||||
npm has a lot of weaknesses for front-end use (installed layout is not great,
|
||||
should have better support for the `baseUrl + moduleID + '.js' style of loading,
|
||||
single file JS installs), but some people want a JS package manager and are
|
||||
willing to live with those constraints. If that is you, but still want to author
|
||||
in AMD style modules to get dynamic require([]), better direct source usage and
|
||||
powerful loader plugin support in the browser, then this tool can help.
|
||||
|
||||
#### amdefine/intercept usage
|
||||
|
||||
Just require it in your top level app module (for example index.js, server.js):
|
||||
|
||||
```javascript
|
||||
require('amdefine/intercept');
|
||||
```
|
||||
|
||||
The module does not return a value, so no need to assign the result to a local
|
||||
variable.
|
||||
|
||||
Then just require() code as you normally would with Node's require(). Any .js
|
||||
loaded after the intercept require will have the amdefine check injected in
|
||||
the .js source as it is loaded. It does not modify the source on disk, just
|
||||
prepends some content to the text of the module as it is loaded by Node.
|
||||
|
||||
#### How amdefine/intercept works
|
||||
|
||||
It overrides the `Module._extensions['.js']` in Node to automatically prepend
|
||||
the amdefine snippet above. So, it will affect any .js file loaded by your
|
||||
app.
|
||||
|
||||
## define() usage
|
||||
|
||||
It is best if you use the anonymous forms of define() in your module:
|
||||
|
||||
```javascript
|
||||
define(function (require) {
|
||||
var dependency = require('dependency');
|
||||
});
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```javascript
|
||||
define(['dependency'], function (dependency) {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
## RequireJS optimizer integration. <a name="optimizer"></name>
|
||||
|
||||
Version 1.0.3 of the [RequireJS optimizer](http://requirejs.org/docs/optimization.html)
|
||||
will have support for stripping the `if (typeof define !== 'function')` check
|
||||
mentioned above, so you can include this snippet for code that runs in the
|
||||
browser, but avoid taking the cost of the if() statement once the code is
|
||||
optimized for deployment.
|
||||
|
||||
## Node 0.4 Support
|
||||
|
||||
If you want to support Node 0.4, then add `require` as the second parameter to amdefine:
|
||||
|
||||
```javascript
|
||||
//Only if you want Node 0.4. If using 0.5 or later, use the above snippet.
|
||||
if (typeof define !== 'function') { var define = require('amdefine')(module, require) }
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
### Synchronous vs Asynchronous
|
||||
|
||||
amdefine creates a define() function that is callable by your code. It will
|
||||
execute and trace dependencies and call the factory function *synchronously*,
|
||||
to keep the behavior in line with Node's synchronous dependency tracing.
|
||||
|
||||
The exception: calling AMD's callback-style require() from inside a factory
|
||||
function. The require callback is called on process.nextTick():
|
||||
|
||||
```javascript
|
||||
define(function (require) {
|
||||
require(['a'], function(a) {
|
||||
//'a' is loaded synchronously, but
|
||||
//this callback is called on process.nextTick().
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Loader Plugins
|
||||
|
||||
Loader plugins are supported as long as they call their load() callbacks
|
||||
synchronously. So ones that do network requests will not work. However plugins
|
||||
like [text](http://requirejs.org/docs/api.html#text) can load text files locally.
|
||||
|
||||
The plugin API's `load.fromText()` is **not supported** in amdefine, so this means
|
||||
transpiler plugins like the [CoffeeScript loader plugin](https://github.com/jrburke/require-cs)
|
||||
will not work. This may be fixable, but it is a bit complex, and I do not have
|
||||
enough node-fu to figure it out yet. See the source for amdefine.js if you want
|
||||
to get an idea of the issues involved.
|
||||
|
||||
## Tests
|
||||
|
||||
To run the tests, cd to **tests** and run:
|
||||
|
||||
```
|
||||
node all.js
|
||||
node all-intercept.js
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
New BSD and MIT. Check the LICENSE file for all the details.
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
/** vim: et:ts=4:sw=4:sts=4
|
||||
* @license amdefine 1.0.1 Copyright (c) 2011-2016, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/jrburke/amdefine for details
|
||||
*/
|
||||
|
||||
/*jslint node: true */
|
||||
/*global module, process */
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Creates a define for node.
|
||||
* @param {Object} module the "module" object that is defined by Node for the
|
||||
* current module.
|
||||
* @param {Function} [requireFn]. Node's require function for the current module.
|
||||
* It only needs to be passed in Node versions before 0.5, when module.require
|
||||
* did not exist.
|
||||
* @returns {Function} a define function that is usable for the current node
|
||||
* module.
|
||||
*/
|
||||
function amdefine(module, requireFn) {
|
||||
'use strict';
|
||||
var defineCache = {},
|
||||
loaderCache = {},
|
||||
alreadyCalled = false,
|
||||
path = require('path'),
|
||||
makeRequire, stringRequire;
|
||||
|
||||
/**
|
||||
* Trims the . and .. from an array of path segments.
|
||||
* It will keep a leading path segment if a .. will become
|
||||
* the first path segment, to help with module name lookups,
|
||||
* which act like paths, but can be remapped. But the end result,
|
||||
* all paths that use this function should look normalized.
|
||||
* NOTE: this method MODIFIES the input array.
|
||||
* @param {Array} ary the array of path segments.
|
||||
*/
|
||||
function trimDots(ary) {
|
||||
var i, part;
|
||||
for (i = 0; ary[i]; i+= 1) {
|
||||
part = ary[i];
|
||||
if (part === '.') {
|
||||
ary.splice(i, 1);
|
||||
i -= 1;
|
||||
} else if (part === '..') {
|
||||
if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
|
||||
//End of the line. Keep at least one non-dot
|
||||
//path segment at the front so it can be mapped
|
||||
//correctly to disk. Otherwise, there is likely
|
||||
//no path mapping for a path starting with '..'.
|
||||
//This can still fail, but catches the most reasonable
|
||||
//uses of ..
|
||||
break;
|
||||
} else if (i > 0) {
|
||||
ary.splice(i - 1, 2);
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function normalize(name, baseName) {
|
||||
var baseParts;
|
||||
|
||||
//Adjust any relative paths.
|
||||
if (name && name.charAt(0) === '.') {
|
||||
//If have a base name, try to normalize against it,
|
||||
//otherwise, assume it is a top-level require that will
|
||||
//be relative to baseUrl in the end.
|
||||
if (baseName) {
|
||||
baseParts = baseName.split('/');
|
||||
baseParts = baseParts.slice(0, baseParts.length - 1);
|
||||
baseParts = baseParts.concat(name.split('/'));
|
||||
trimDots(baseParts);
|
||||
name = baseParts.join('/');
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the normalize() function passed to a loader plugin's
|
||||
* normalize method.
|
||||
*/
|
||||
function makeNormalize(relName) {
|
||||
return function (name) {
|
||||
return normalize(name, relName);
|
||||
};
|
||||
}
|
||||
|
||||
function makeLoad(id) {
|
||||
function load(value) {
|
||||
loaderCache[id] = value;
|
||||
}
|
||||
|
||||
load.fromText = function (id, text) {
|
||||
//This one is difficult because the text can/probably uses
|
||||
//define, and any relative paths and requires should be relative
|
||||
//to that id was it would be found on disk. But this would require
|
||||
//bootstrapping a module/require fairly deeply from node core.
|
||||
//Not sure how best to go about that yet.
|
||||
throw new Error('amdefine does not implement load.fromText');
|
||||
};
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
makeRequire = function (systemRequire, exports, module, relId) {
|
||||
function amdRequire(deps, callback) {
|
||||
if (typeof deps === 'string') {
|
||||
//Synchronous, single module require('')
|
||||
return stringRequire(systemRequire, exports, module, deps, relId);
|
||||
} else {
|
||||
//Array of dependencies with a callback.
|
||||
|
||||
//Convert the dependencies to modules.
|
||||
deps = deps.map(function (depName) {
|
||||
return stringRequire(systemRequire, exports, module, depName, relId);
|
||||
});
|
||||
|
||||
//Wait for next tick to call back the require call.
|
||||
if (callback) {
|
||||
process.nextTick(function () {
|
||||
callback.apply(null, deps);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amdRequire.toUrl = function (filePath) {
|
||||
if (filePath.indexOf('.') === 0) {
|
||||
return normalize(filePath, path.dirname(module.filename));
|
||||
} else {
|
||||
return filePath;
|
||||
}
|
||||
};
|
||||
|
||||
return amdRequire;
|
||||
};
|
||||
|
||||
//Favor explicit value, passed in if the module wants to support Node 0.4.
|
||||
requireFn = requireFn || function req() {
|
||||
return module.require.apply(module, arguments);
|
||||
};
|
||||
|
||||
function runFactory(id, deps, factory) {
|
||||
var r, e, m, result;
|
||||
|
||||
if (id) {
|
||||
e = loaderCache[id] = {};
|
||||
m = {
|
||||
id: id,
|
||||
uri: __filename,
|
||||
exports: e
|
||||
};
|
||||
r = makeRequire(requireFn, e, m, id);
|
||||
} else {
|
||||
//Only support one define call per file
|
||||
if (alreadyCalled) {
|
||||
throw new Error('amdefine with no module ID cannot be called more than once per file.');
|
||||
}
|
||||
alreadyCalled = true;
|
||||
|
||||
//Use the real variables from node
|
||||
//Use module.exports for exports, since
|
||||
//the exports in here is amdefine exports.
|
||||
e = module.exports;
|
||||
m = module;
|
||||
r = makeRequire(requireFn, e, m, module.id);
|
||||
}
|
||||
|
||||
//If there are dependencies, they are strings, so need
|
||||
//to convert them to dependency values.
|
||||
if (deps) {
|
||||
deps = deps.map(function (depName) {
|
||||
return r(depName);
|
||||
});
|
||||
}
|
||||
|
||||
//Call the factory with the right dependencies.
|
||||
if (typeof factory === 'function') {
|
||||
result = factory.apply(m.exports, deps);
|
||||
} else {
|
||||
result = factory;
|
||||
}
|
||||
|
||||
if (result !== undefined) {
|
||||
m.exports = result;
|
||||
if (id) {
|
||||
loaderCache[id] = m.exports;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stringRequire = function (systemRequire, exports, module, id, relId) {
|
||||
//Split the ID by a ! so that
|
||||
var index = id.indexOf('!'),
|
||||
originalId = id,
|
||||
prefix, plugin;
|
||||
|
||||
if (index === -1) {
|
||||
id = normalize(id, relId);
|
||||
|
||||
//Straight module lookup. If it is one of the special dependencies,
|
||||
//deal with it, otherwise, delegate to node.
|
||||
if (id === 'require') {
|
||||
return makeRequire(systemRequire, exports, module, relId);
|
||||
} else if (id === 'exports') {
|
||||
return exports;
|
||||
} else if (id === 'module') {
|
||||
return module;
|
||||
} else if (loaderCache.hasOwnProperty(id)) {
|
||||
return loaderCache[id];
|
||||
} else if (defineCache[id]) {
|
||||
runFactory.apply(null, defineCache[id]);
|
||||
return loaderCache[id];
|
||||
} else {
|
||||
if(systemRequire) {
|
||||
return systemRequire(originalId);
|
||||
} else {
|
||||
throw new Error('No module with ID: ' + id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//There is a plugin in play.
|
||||
prefix = id.substring(0, index);
|
||||
id = id.substring(index + 1, id.length);
|
||||
|
||||
plugin = stringRequire(systemRequire, exports, module, prefix, relId);
|
||||
|
||||
if (plugin.normalize) {
|
||||
id = plugin.normalize(id, makeNormalize(relId));
|
||||
} else {
|
||||
//Normalize the ID normally.
|
||||
id = normalize(id, relId);
|
||||
}
|
||||
|
||||
if (loaderCache[id]) {
|
||||
return loaderCache[id];
|
||||
} else {
|
||||
plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});
|
||||
|
||||
return loaderCache[id];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Create a define function specific to the module asking for amdefine.
|
||||
function define(id, deps, factory) {
|
||||
if (Array.isArray(id)) {
|
||||
factory = deps;
|
||||
deps = id;
|
||||
id = undefined;
|
||||
} else if (typeof id !== 'string') {
|
||||
factory = id;
|
||||
id = deps = undefined;
|
||||
}
|
||||
|
||||
if (deps && !Array.isArray(deps)) {
|
||||
factory = deps;
|
||||
deps = undefined;
|
||||
}
|
||||
|
||||
if (!deps) {
|
||||
deps = ['require', 'exports', 'module'];
|
||||
}
|
||||
|
||||
//Set up properties for this module. If an ID, then use
|
||||
//internal cache. If no ID, then use the external variables
|
||||
//for this node module.
|
||||
if (id) {
|
||||
//Put the module in deep freeze until there is a
|
||||
//require call for it.
|
||||
defineCache[id] = [id, deps, factory];
|
||||
} else {
|
||||
runFactory(id, deps, factory);
|
||||
}
|
||||
}
|
||||
|
||||
//define.require, which has access to all the values in the
|
||||
//cache. Useful for AMD modules that all have IDs in the file,
|
||||
//but need to finally export a value to node based on one of those
|
||||
//IDs.
|
||||
define.require = function (id) {
|
||||
if (loaderCache[id]) {
|
||||
return loaderCache[id];
|
||||
}
|
||||
|
||||
if (defineCache[id]) {
|
||||
runFactory.apply(null, defineCache[id]);
|
||||
return loaderCache[id];
|
||||
}
|
||||
};
|
||||
|
||||
define.amd = {};
|
||||
|
||||
return define;
|
||||
}
|
||||
|
||||
module.exports = amdefine;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*jshint node: true */
|
||||
var inserted,
|
||||
Module = require('module'),
|
||||
fs = require('fs'),
|
||||
existingExtFn = Module._extensions['.js'],
|
||||
amdefineRegExp = /amdefine\.js/;
|
||||
|
||||
inserted = "if (typeof define !== 'function') {var define = require('amdefine')(module)}";
|
||||
|
||||
//From the node/lib/module.js source:
|
||||
function stripBOM(content) {
|
||||
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
||||
// because the buffer-to-string conversion in `fs.readFileSync()`
|
||||
// translates it to FEFF, the UTF-16 BOM.
|
||||
if (content.charCodeAt(0) === 0xFEFF) {
|
||||
content = content.slice(1);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
//Also adapted from the node/lib/module.js source:
|
||||
function intercept(module, filename) {
|
||||
var content = stripBOM(fs.readFileSync(filename, 'utf8'));
|
||||
|
||||
if (!amdefineRegExp.test(module.id)) {
|
||||
content = inserted + content;
|
||||
}
|
||||
|
||||
module._compile(content, filename);
|
||||
}
|
||||
|
||||
intercept._id = 'amdefine/intercept';
|
||||
|
||||
if (!existingExtFn._id || existingExtFn._id !== intercept._id) {
|
||||
Module._extensions['.js'] = intercept;
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"amdefine@>=0.0.4",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/source-map"
|
||||
]
|
||||
],
|
||||
"_from": "amdefine@>=0.0.4",
|
||||
"_id": "amdefine@1.0.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/amdefine",
|
||||
"_nodeVersion": "6.7.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-18-east.internal.npmjs.com",
|
||||
"tmp": "tmp/amdefine-1.0.1.tgz_1478062849665_0.19916908955201507"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "jrburke@gmail.com",
|
||||
"name": "jrburke"
|
||||
},
|
||||
"_npmVersion": "3.10.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "amdefine",
|
||||
"raw": "amdefine@>=0.0.4",
|
||||
"rawSpec": ">=0.0.4",
|
||||
"scope": null,
|
||||
"spec": ">=0.0.4",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/handlebars/source-map",
|
||||
"/source-map"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
||||
"_shasum": "4a5282ac164729e93619bcfd3ad151f817ce91f5",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "amdefine@>=0.0.4",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/source-map",
|
||||
"author": {
|
||||
"email": "jrburke@gmail.com",
|
||||
"name": "James Burke",
|
||||
"url": "http://github.com/jrburke"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jrburke/amdefine/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Provide AMD's define() API for declaring modules in the AMD format",
|
||||
"devDependencies": {},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "4a5282ac164729e93619bcfd3ad151f817ce91f5",
|
||||
"tarball": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.2"
|
||||
},
|
||||
"gitHead": "e59edc9da24404ec7937098e3992f8fb0e260be7",
|
||||
"homepage": "http://github.com/jrburke/amdefine",
|
||||
"license": "BSD-3-Clause OR MIT",
|
||||
"main": "./amdefine.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jrburke",
|
||||
"email": "jrburke@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "amdefine",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jrburke/amdefine.git"
|
||||
},
|
||||
"scripts": {},
|
||||
"version": "1.0.1"
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"ansi-regex@^2.0.0",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/has-ansi"
|
||||
]
|
||||
],
|
||||
"_from": "ansi-regex@>=2.0.0 <3.0.0",
|
||||
"_id": "ansi-regex@2.0.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/ansi-regex",
|
||||
"_nodeVersion": "0.12.5",
|
||||
"_npmUser": {
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"name": "sindresorhus"
|
||||
},
|
||||
"_npmVersion": "2.11.2",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "ansi-regex",
|
||||
"raw": "ansi-regex@^2.0.0",
|
||||
"rawSpec": "^2.0.0",
|
||||
"scope": null,
|
||||
"spec": ">=2.0.0 <3.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/has-ansi",
|
||||
"/strip-ansi"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
|
||||
"_shasum": "c5061b6e0ef8a81775e50f5d66151bf6bf371107",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "ansi-regex@^2.0.0",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/has-ansi",
|
||||
"author": {
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"name": "Sindre Sorhus",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/ansi-regex/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Regular expression for matching ANSI escape codes",
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "c5061b6e0ef8a81775e50f5d66151bf6bf371107",
|
||||
"tarball": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"gitHead": "57c3f2941a73079fa8b081e02a522e3d29913e2f",
|
||||
"homepage": "https://github.com/sindresorhus/ansi-regex",
|
||||
"keywords": [
|
||||
"256",
|
||||
"ansi",
|
||||
"cli",
|
||||
"color",
|
||||
"colors",
|
||||
"colour",
|
||||
"command-line",
|
||||
"console",
|
||||
"escape",
|
||||
"find",
|
||||
"formatting",
|
||||
"match",
|
||||
"pattern",
|
||||
"re",
|
||||
"regex",
|
||||
"regexp",
|
||||
"rgb",
|
||||
"shell",
|
||||
"string",
|
||||
"styles",
|
||||
"terminal",
|
||||
"test",
|
||||
"text",
|
||||
"tty",
|
||||
"xterm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "jbnicolai",
|
||||
"email": "jappelman@xebia.com"
|
||||
}
|
||||
],
|
||||
"name": "ansi-regex",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sindresorhus/ansi-regex.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha test/test.js",
|
||||
"view-supported": "node test/viewCodes.js"
|
||||
},
|
||||
"version": "2.0.0"
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# ansi-regex [](https://travis-ci.org/sindresorhus/ansi-regex)
|
||||
|
||||
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-regex
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansiRegex = require('ansi-regex');
|
||||
|
||||
ansiRegex().test('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
ansiRegex().test('cake');
|
||||
//=> false
|
||||
|
||||
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
|
||||
//=> ['\u001b[4m', '\u001b[0m']
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
function assembleStyles () {
|
||||
var styles = {
|
||||
modifiers: {
|
||||
reset: [0, 0],
|
||||
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
|
||||
dim: [2, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
inverse: [7, 27],
|
||||
hidden: [8, 28],
|
||||
strikethrough: [9, 29]
|
||||
},
|
||||
colors: {
|
||||
black: [30, 39],
|
||||
red: [31, 39],
|
||||
green: [32, 39],
|
||||
yellow: [33, 39],
|
||||
blue: [34, 39],
|
||||
magenta: [35, 39],
|
||||
cyan: [36, 39],
|
||||
white: [37, 39],
|
||||
gray: [90, 39]
|
||||
},
|
||||
bgColors: {
|
||||
bgBlack: [40, 49],
|
||||
bgRed: [41, 49],
|
||||
bgGreen: [42, 49],
|
||||
bgYellow: [43, 49],
|
||||
bgBlue: [44, 49],
|
||||
bgMagenta: [45, 49],
|
||||
bgCyan: [46, 49],
|
||||
bgWhite: [47, 49]
|
||||
}
|
||||
};
|
||||
|
||||
// fix humans
|
||||
styles.colors.grey = styles.colors.gray;
|
||||
|
||||
Object.keys(styles).forEach(function (groupName) {
|
||||
var group = styles[groupName];
|
||||
|
||||
Object.keys(group).forEach(function (styleName) {
|
||||
var style = group[styleName];
|
||||
|
||||
styles[styleName] = group[styleName] = {
|
||||
open: '\u001b[' + style[0] + 'm',
|
||||
close: '\u001b[' + style[1] + 'm'
|
||||
};
|
||||
});
|
||||
|
||||
Object.defineProperty(styles, groupName, {
|
||||
value: group,
|
||||
enumerable: false
|
||||
});
|
||||
});
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
Object.defineProperty(module, 'exports', {
|
||||
enumerable: true,
|
||||
get: assembleStyles
|
||||
});
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"ansi-styles@^2.2.1",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/chalk"
|
||||
]
|
||||
],
|
||||
"_from": "ansi-styles@>=2.2.1 <3.0.0",
|
||||
"_id": "ansi-styles@2.2.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/ansi-styles",
|
||||
"_nodeVersion": "4.3.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-12-west.internal.npmjs.com",
|
||||
"tmp": "tmp/ansi-styles-2.2.1.tgz_1459197317833_0.9694824463222176"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"name": "sindresorhus"
|
||||
},
|
||||
"_npmVersion": "3.8.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "ansi-styles",
|
||||
"raw": "ansi-styles@^2.2.1",
|
||||
"rawSpec": "^2.2.1",
|
||||
"scope": null,
|
||||
"spec": ">=2.2.1 <3.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/chalk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"_shasum": "b432dd3358b634cf75e1e4664368240533c1ddbe",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "ansi-styles@^2.2.1",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/chalk",
|
||||
"author": {
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"name": "Sindre Sorhus",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/chalk/ansi-styles/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "ANSI escape codes for styling strings in the terminal",
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "b432dd3358b634cf75e1e4664368240533c1ddbe",
|
||||
"tarball": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"gitHead": "95c59b23be760108b6530ca1c89477c21b258032",
|
||||
"homepage": "https://github.com/chalk/ansi-styles#readme",
|
||||
"keywords": [
|
||||
"256",
|
||||
"ansi",
|
||||
"cli",
|
||||
"color",
|
||||
"colors",
|
||||
"colour",
|
||||
"command-line",
|
||||
"console",
|
||||
"escape",
|
||||
"formatting",
|
||||
"log",
|
||||
"logging",
|
||||
"rgb",
|
||||
"shell",
|
||||
"string",
|
||||
"styles",
|
||||
"terminal",
|
||||
"text",
|
||||
"tty",
|
||||
"xterm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "sindresorhus",
|
||||
"email": "sindresorhus@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "ansi-styles",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/chalk/ansi-styles.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "2.2.1"
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# ansi-styles [](https://travis-ci.org/chalk/ansi-styles)
|
||||
|
||||
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
|
||||
|
||||
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-styles
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansi = require('ansi-styles');
|
||||
|
||||
console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
Each style has an `open` and `close` property.
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### Modifiers
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## Advanced usage
|
||||
|
||||
By default you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
|
||||
|
||||
- `ansi.modifiers`
|
||||
- `ansi.colors`
|
||||
- `ansi.bgColors`
|
||||
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
console.log(ansi.colors.green.open);
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
1.0.9 / 2016-09-29
|
||||
------------------
|
||||
|
||||
- Rerelease after 1.0.8 - deps cleanup.
|
||||
|
||||
|
||||
1.0.8 / 2016-09-29
|
||||
------------------
|
||||
|
||||
- Maintenance (deps bump, fix node 6.5+ tests, coverage report).
|
||||
|
||||
|
||||
1.0.7 / 2016-03-17
|
||||
------------------
|
||||
|
||||
- Teach `addArgument` to accept string arg names. #97, @tomxtobin.
|
||||
|
||||
|
||||
1.0.6 / 2016-02-06
|
||||
------------------
|
||||
|
||||
- Maintenance: moved to eslint & updated CS.
|
||||
|
||||
|
||||
1.0.5 / 2016-02-05
|
||||
------------------
|
||||
|
||||
- Removed lodash dependency to significantly reduce install size.
|
||||
Thanks to @mourner.
|
||||
|
||||
|
||||
1.0.4 / 2016-01-17
|
||||
------------------
|
||||
|
||||
- Maintenance: lodash update to 4.0.0.
|
||||
|
||||
|
||||
1.0.3 / 2015-10-27
|
||||
------------------
|
||||
|
||||
- Fix parse `=` in args: `--examplepath="C:\myfolder\env=x64"`. #84, @CatWithApple.
|
||||
|
||||
|
||||
1.0.2 / 2015-03-22
|
||||
------------------
|
||||
|
||||
- Relaxed lodash version dependency.
|
||||
|
||||
|
||||
1.0.1 / 2015-02-20
|
||||
------------------
|
||||
|
||||
- Changed dependencies to be compatible with ancient nodejs.
|
||||
|
||||
|
||||
1.0.0 / 2015-02-19
|
||||
------------------
|
||||
|
||||
- Maintenance release.
|
||||
- Replaced `underscore` with `lodash`.
|
||||
- Bumped version to 1.0.0 to better reflect semver meaning.
|
||||
- HISTORY.md -> CHANGELOG.md
|
||||
|
||||
|
||||
0.1.16 / 2013-12-01
|
||||
-------------------
|
||||
|
||||
- Maintenance release. Updated dependencies and docs.
|
||||
|
||||
|
||||
0.1.15 / 2013-05-13
|
||||
-------------------
|
||||
|
||||
- Fixed #55, @trebor89
|
||||
|
||||
|
||||
0.1.14 / 2013-05-12
|
||||
-------------------
|
||||
|
||||
- Fixed #62, @maxtaco
|
||||
|
||||
|
||||
0.1.13 / 2013-04-08
|
||||
-------------------
|
||||
|
||||
- Added `.npmignore` to reduce package size
|
||||
|
||||
|
||||
0.1.12 / 2013-02-10
|
||||
-------------------
|
||||
|
||||
- Fixed conflictHandler (#46), @hpaulj
|
||||
|
||||
|
||||
0.1.11 / 2013-02-07
|
||||
-------------------
|
||||
|
||||
- Multiple bugfixes, @hpaulj
|
||||
- Added 70+ tests (ported from python), @hpaulj
|
||||
- Added conflictHandler, @applepicke
|
||||
- Added fromfilePrefixChar, @hpaulj
|
||||
|
||||
|
||||
0.1.10 / 2012-12-30
|
||||
-------------------
|
||||
|
||||
- Added [mutual exclusion](http://docs.python.org/dev/library/argparse.html#mutual-exclusion)
|
||||
support, thanks to @hpaulj
|
||||
- Fixed options check for `storeConst` & `appendConst` actions, thanks to @hpaulj
|
||||
|
||||
|
||||
0.1.9 / 2012-12-27
|
||||
------------------
|
||||
|
||||
- Fixed option dest interferens with other options (issue #23), thanks to @hpaulj
|
||||
- Fixed default value behavior with `*` positionals, thanks to @hpaulj
|
||||
- Improve `getDefault()` behavior, thanks to @hpaulj
|
||||
- Imrove negative argument parsing, thanks to @hpaulj
|
||||
|
||||
|
||||
0.1.8 / 2012-12-01
|
||||
------------------
|
||||
|
||||
- Fixed parser parents (issue #19), thanks to @hpaulj
|
||||
- Fixed negative argument parse (issue #20), thanks to @hpaulj
|
||||
|
||||
|
||||
0.1.7 / 2012-10-14
|
||||
------------------
|
||||
|
||||
- Fixed 'choices' argument parse (issue #16)
|
||||
- Fixed stderr output (issue #15)
|
||||
|
||||
|
||||
0.1.6 / 2012-09-09
|
||||
------------------
|
||||
|
||||
- Fixed check for conflict of options (thanks to @tomxtobin)
|
||||
|
||||
|
||||
0.1.5 / 2012-09-03
|
||||
------------------
|
||||
|
||||
- Fix parser #setDefaults method (thanks to @tomxtobin)
|
||||
|
||||
|
||||
0.1.4 / 2012-07-30
|
||||
------------------
|
||||
|
||||
- Fixed pseudo-argument support (thanks to @CGamesPlay)
|
||||
- Fixed addHelp default (should be true), if not set (thanks to @benblank)
|
||||
|
||||
|
||||
0.1.3 / 2012-06-27
|
||||
------------------
|
||||
|
||||
- Fixed formatter api name: Formatter -> HelpFormatter
|
||||
|
||||
|
||||
0.1.2 / 2012-05-29
|
||||
------------------
|
||||
|
||||
- Added basic tests
|
||||
- Removed excess whitespace in help
|
||||
- Fixed error reporting, when parcer with subcommands
|
||||
called with empty arguments
|
||||
|
||||
|
||||
0.1.1 / 2012-05-23
|
||||
------------------
|
||||
|
||||
- Fixed line wrapping in help formatter
|
||||
- Added better error reporting on invalid arguments
|
||||
|
||||
|
||||
0.1.0 / 2012-05-16
|
||||
------------------
|
||||
|
||||
- First release.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (C) 2012 by Vitaly Puzrin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
argparse
|
||||
========
|
||||
|
||||
[](http://travis-ci.org/nodeca/argparse)
|
||||
[](https://www.npmjs.org/package/argparse)
|
||||
|
||||
CLI arguments parser for node.js. Javascript port of python's
|
||||
[argparse](http://docs.python.org/dev/library/argparse.html) module
|
||||
(original version 3.2). That's a full port, except some very rare options,
|
||||
recorded in issue tracker.
|
||||
|
||||
**NB. Difference with original.**
|
||||
|
||||
- Method names changed to camelCase. See [generated docs](http://nodeca.github.com/argparse/).
|
||||
- Use `defaultValue` instead of `default`.
|
||||
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
test.js file:
|
||||
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var ArgumentParser = require('../lib/argparse').ArgumentParser;
|
||||
var parser = new ArgumentParser({
|
||||
version: '0.0.1',
|
||||
addHelp:true,
|
||||
description: 'Argparse example'
|
||||
});
|
||||
parser.addArgument(
|
||||
[ '-f', '--foo' ],
|
||||
{
|
||||
help: 'foo bar'
|
||||
}
|
||||
);
|
||||
parser.addArgument(
|
||||
[ '-b', '--bar' ],
|
||||
{
|
||||
help: 'bar foo'
|
||||
}
|
||||
);
|
||||
parser.addArgument(
|
||||
'--baz',
|
||||
{
|
||||
help: 'baz bar'
|
||||
}
|
||||
);
|
||||
var args = parser.parseArgs();
|
||||
console.dir(args);
|
||||
```
|
||||
|
||||
Display help:
|
||||
|
||||
```
|
||||
$ ./test.js -h
|
||||
usage: example.js [-h] [-v] [-f FOO] [-b BAR] [--baz BAZ]
|
||||
|
||||
Argparse example
|
||||
|
||||
Optional arguments:
|
||||
-h, --help Show this help message and exit.
|
||||
-v, --version Show program's version number and exit.
|
||||
-f FOO, --foo FOO foo bar
|
||||
-b BAR, --bar BAR bar foo
|
||||
--baz BAZ baz bar
|
||||
```
|
||||
|
||||
Parse arguments:
|
||||
|
||||
```
|
||||
$ ./test.js -f=3 --bar=4 --baz 5
|
||||
{ foo: '3', bar: '4', baz: '5' }
|
||||
```
|
||||
|
||||
More [examples](https://github.com/nodeca/argparse/tree/master/examples).
|
||||
|
||||
|
||||
ArgumentParser objects
|
||||
======================
|
||||
|
||||
```
|
||||
new ArgumentParser({paramters hash});
|
||||
```
|
||||
|
||||
Creates a new ArgumentParser object.
|
||||
|
||||
**Supported params:**
|
||||
|
||||
- ```description``` - Text to display before the argument help.
|
||||
- ```epilog``` - Text to display after the argument help.
|
||||
- ```addHelp``` - Add a -h/–help option to the parser. (default: true)
|
||||
- ```argumentDefault``` - Set the global default value for arguments. (default: null)
|
||||
- ```parents``` - A list of ArgumentParser objects whose arguments should also be included.
|
||||
- ```prefixChars``` - The set of characters that prefix optional arguments. (default: ‘-‘)
|
||||
- ```formatterClass``` - A class for customizing the help output.
|
||||
- ```prog``` - The name of the program (default: `path.basename(process.argv[1])`)
|
||||
- ```usage``` - The string describing the program usage (default: generated)
|
||||
- ```conflictHandler``` - Usually unnecessary, defines strategy for resolving conflicting optionals.
|
||||
|
||||
**Not supportied yet**
|
||||
|
||||
- ```fromfilePrefixChars``` - The set of characters that prefix files from which additional arguments should be read.
|
||||
|
||||
|
||||
Details in [original ArgumentParser guide](http://docs.python.org/dev/library/argparse.html#argumentparser-objects)
|
||||
|
||||
|
||||
addArgument() method
|
||||
====================
|
||||
|
||||
```
|
||||
ArgumentParser.addArgument(name or flag or [name] or [flags...], {options})
|
||||
```
|
||||
|
||||
Defines how a single command-line argument should be parsed.
|
||||
|
||||
- ```name or flag or [name] or [flags...]``` - Either a positional name
|
||||
(e.g., `'foo'`), a single option (e.g., `'-f'` or `'--foo'`), an array
|
||||
of a single positional name (e.g., `['foo']`), or an array of options
|
||||
(e.g., `['-f', '--foo']`).
|
||||
|
||||
Options:
|
||||
|
||||
- ```action``` - The basic type of action to be taken when this argument is encountered at the command line.
|
||||
- ```nargs```- The number of command-line arguments that should be consumed.
|
||||
- ```constant``` - A constant value required by some action and nargs selections.
|
||||
- ```defaultValue``` - The value produced if the argument is absent from the command line.
|
||||
- ```type``` - The type to which the command-line argument should be converted.
|
||||
- ```choices``` - A container of the allowable values for the argument.
|
||||
- ```required``` - Whether or not the command-line option may be omitted (optionals only).
|
||||
- ```help``` - A brief description of what the argument does.
|
||||
- ```metavar``` - A name for the argument in usage messages.
|
||||
- ```dest``` - The name of the attribute to be added to the object returned by parseArgs().
|
||||
|
||||
Details in [original add_argument guide](http://docs.python.org/dev/library/argparse.html#the-add-argument-method)
|
||||
|
||||
|
||||
Action (some details)
|
||||
================
|
||||
|
||||
ArgumentParser objects associate command-line arguments with actions.
|
||||
These actions can do just about anything with the command-line arguments associated
|
||||
with them, though most actions simply add an attribute to the object returned by
|
||||
parseArgs(). The action keyword argument specifies how the command-line arguments
|
||||
should be handled. The supported actions are:
|
||||
|
||||
- ```store``` - Just stores the argument’s value. This is the default action.
|
||||
- ```storeConst``` - Stores value, specified by the const keyword argument.
|
||||
(Note that the const keyword argument defaults to the rather unhelpful None.)
|
||||
The 'storeConst' action is most commonly used with optional arguments, that
|
||||
specify some sort of flag.
|
||||
- ```storeTrue``` and ```storeFalse``` - Stores values True and False
|
||||
respectively. These are special cases of 'storeConst'.
|
||||
- ```append``` - Stores a list, and appends each argument value to the list.
|
||||
This is useful to allow an option to be specified multiple times.
|
||||
- ```appendConst``` - Stores a list, and appends value, specified by the
|
||||
const keyword argument to the list. (Note, that the const keyword argument defaults
|
||||
is None.) The 'appendConst' action is typically used when multiple arguments need
|
||||
to store constants to the same list.
|
||||
- ```count``` - Counts the number of times a keyword argument occurs. For example,
|
||||
used for increasing verbosity levels.
|
||||
- ```help``` - Prints a complete help message for all the options in the current
|
||||
parser and then exits. By default a help action is automatically added to the parser.
|
||||
See ArgumentParser for details of how the output is created.
|
||||
- ```version``` - Prints version information and exit. Expects a `version=`
|
||||
keyword argument in the addArgument() call.
|
||||
|
||||
Details in [original action guide](http://docs.python.org/dev/library/argparse.html#action)
|
||||
|
||||
|
||||
Sub-commands
|
||||
============
|
||||
|
||||
ArgumentParser.addSubparsers()
|
||||
|
||||
Many programs split their functionality into a number of sub-commands, for
|
||||
example, the svn program can invoke sub-commands like `svn checkout`, `svn update`,
|
||||
and `svn commit`. Splitting up functionality this way can be a particularly good
|
||||
idea when a program performs several different functions which require different
|
||||
kinds of command-line arguments. `ArgumentParser` supports creation of such
|
||||
sub-commands with `addSubparsers()` method. The `addSubparsers()` method is
|
||||
normally called with no arguments and returns an special action object.
|
||||
This object has a single method `addParser()`, which takes a command name and
|
||||
any `ArgumentParser` constructor arguments, and returns an `ArgumentParser` object
|
||||
that can be modified as usual.
|
||||
|
||||
Example:
|
||||
|
||||
sub_commands.js
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var ArgumentParser = require('../lib/argparse').ArgumentParser;
|
||||
var parser = new ArgumentParser({
|
||||
version: '0.0.1',
|
||||
addHelp:true,
|
||||
description: 'Argparse examples: sub-commands',
|
||||
});
|
||||
|
||||
var subparsers = parser.addSubparsers({
|
||||
title:'subcommands',
|
||||
dest:"subcommand_name"
|
||||
});
|
||||
|
||||
var bar = subparsers.addParser('c1', {addHelp:true});
|
||||
bar.addArgument(
|
||||
[ '-f', '--foo' ],
|
||||
{
|
||||
action: 'store',
|
||||
help: 'foo3 bar3'
|
||||
}
|
||||
);
|
||||
var bar = subparsers.addParser(
|
||||
'c2',
|
||||
{aliases:['co'], addHelp:true}
|
||||
);
|
||||
bar.addArgument(
|
||||
[ '-b', '--bar' ],
|
||||
{
|
||||
action: 'store',
|
||||
type: 'int',
|
||||
help: 'foo3 bar3'
|
||||
}
|
||||
);
|
||||
|
||||
var args = parser.parseArgs();
|
||||
console.dir(args);
|
||||
|
||||
```
|
||||
|
||||
Details in [original sub-commands guide](http://docs.python.org/dev/library/argparse.html#sub-commands)
|
||||
|
||||
|
||||
Contributors
|
||||
============
|
||||
|
||||
- [Eugene Shkuropat](https://github.com/shkuropat)
|
||||
- [Paul Jacobson](https://github.com/hpaulj)
|
||||
|
||||
[others](https://github.com/nodeca/argparse/graphs/contributors)
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Copyright (c) 2012 [Vitaly Puzrin](https://github.com/puzrin).
|
||||
Released under the MIT license. See
|
||||
[LICENSE](https://github.com/nodeca/argparse/blob/master/LICENSE) for details.
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./lib/argparse');
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* class Action
|
||||
*
|
||||
* Base class for all actions
|
||||
* Do not call in your code, use this class only for inherits your own action
|
||||
*
|
||||
* Information about how to convert command line strings to Javascript objects.
|
||||
* Action objects are used by an ArgumentParser to represent the information
|
||||
* needed to parse a single argument from one or more strings from the command
|
||||
* line. The keyword arguments to the Action constructor are also all attributes
|
||||
* of Action instances.
|
||||
*
|
||||
* #####Alowed keywords:
|
||||
*
|
||||
* - `store`
|
||||
* - `storeConstant`
|
||||
* - `storeTrue`
|
||||
* - `storeFalse`
|
||||
* - `append`
|
||||
* - `appendConstant`
|
||||
* - `count`
|
||||
* - `help`
|
||||
* - `version`
|
||||
*
|
||||
* Information about action options see [[Action.new]]
|
||||
*
|
||||
* See also [original guide](http://docs.python.org/dev/library/argparse.html#action)
|
||||
*
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
// Constants
|
||||
var c = require('./const');
|
||||
|
||||
|
||||
/**
|
||||
* new Action(options)
|
||||
*
|
||||
* Base class for all actions. Used only for inherits
|
||||
*
|
||||
*
|
||||
* ##### Options:
|
||||
*
|
||||
* - `optionStrings` A list of command-line option strings for the action.
|
||||
* - `dest` Attribute to hold the created object(s)
|
||||
* - `nargs` The number of command-line arguments that should be consumed.
|
||||
* By default, one argument will be consumed and a single value will be
|
||||
* produced.
|
||||
* - `constant` Default value for an action with no value.
|
||||
* - `defaultValue` The value to be produced if the option is not specified.
|
||||
* - `type` Cast to 'string'|'int'|'float'|'complex'|function (string). If
|
||||
* None, 'string'.
|
||||
* - `choices` The choices available.
|
||||
* - `required` True if the action must always be specified at the command
|
||||
* line.
|
||||
* - `help` The help describing the argument.
|
||||
* - `metavar` The name to be used for the option's argument with the help
|
||||
* string. If None, the 'dest' value will be used as the name.
|
||||
*
|
||||
* ##### nargs supported values:
|
||||
*
|
||||
* - `N` (an integer) consumes N arguments (and produces a list)
|
||||
* - `?` consumes zero or one arguments
|
||||
* - `*` consumes zero or more arguments (and produces a list)
|
||||
* - `+` consumes one or more arguments (and produces a list)
|
||||
*
|
||||
* Note: that the difference between the default and nargs=1 is that with the
|
||||
* default, a single value will be produced, while with nargs=1, a list
|
||||
* containing a single value will be produced.
|
||||
**/
|
||||
var Action = module.exports = function Action(options) {
|
||||
options = options || {};
|
||||
this.optionStrings = options.optionStrings || [];
|
||||
this.dest = options.dest;
|
||||
this.nargs = typeof options.nargs !== 'undefined' ? options.nargs : null;
|
||||
this.constant = typeof options.constant !== 'undefined' ? options.constant : null;
|
||||
this.defaultValue = options.defaultValue;
|
||||
this.type = typeof options.type !== 'undefined' ? options.type : null;
|
||||
this.choices = typeof options.choices !== 'undefined' ? options.choices : null;
|
||||
this.required = typeof options.required !== 'undefined' ? options.required : false;
|
||||
this.help = typeof options.help !== 'undefined' ? options.help : null;
|
||||
this.metavar = typeof options.metavar !== 'undefined' ? options.metavar : null;
|
||||
|
||||
if (!(this.optionStrings instanceof Array)) {
|
||||
throw new Error('optionStrings should be an array');
|
||||
}
|
||||
if (typeof this.required !== 'undefined' && typeof this.required !== 'boolean') {
|
||||
throw new Error('required should be a boolean');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Action#getName -> String
|
||||
*
|
||||
* Tells action name
|
||||
**/
|
||||
Action.prototype.getName = function () {
|
||||
if (this.optionStrings.length > 0) {
|
||||
return this.optionStrings.join('/');
|
||||
} else if (this.metavar !== null && this.metavar !== c.SUPPRESS) {
|
||||
return this.metavar;
|
||||
} else if (typeof this.dest !== 'undefined' && this.dest !== c.SUPPRESS) {
|
||||
return this.dest;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Action#isOptional -> Boolean
|
||||
*
|
||||
* Return true if optional
|
||||
**/
|
||||
Action.prototype.isOptional = function () {
|
||||
return !this.isPositional();
|
||||
};
|
||||
|
||||
/**
|
||||
* Action#isPositional -> Boolean
|
||||
*
|
||||
* Return true if positional
|
||||
**/
|
||||
Action.prototype.isPositional = function () {
|
||||
return (this.optionStrings.length === 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Action#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Should be implemented in inherited classes
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* ActionCount.prototype.call = function (parser, namespace, values, optionString) {
|
||||
* namespace.set(this.dest, (namespace[this.dest] || 0) + 1);
|
||||
* };
|
||||
*
|
||||
**/
|
||||
Action.prototype.call = function () {
|
||||
throw new Error('.call() not defined');// Not Implemented error
|
||||
};
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*:nodoc:*
|
||||
* class ActionAppend
|
||||
*
|
||||
* This action stores a list, and appends each argument value to the list.
|
||||
* This is useful to allow an option to be specified multiple times.
|
||||
* This class inherided from [[Action]]
|
||||
*
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionAppend(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
* Note: options.nargs should be optional for constants
|
||||
* and more then zero for other
|
||||
**/
|
||||
var ActionAppend = module.exports = function ActionAppend(options) {
|
||||
options = options || {};
|
||||
if (this.nargs <= 0) {
|
||||
throw new Error('nargs for append actions must be > 0; if arg ' +
|
||||
'strings are not supplying the value to append, ' +
|
||||
'the append const action may be more appropriate');
|
||||
}
|
||||
if (!!this.constant && this.nargs !== c.OPTIONAL) {
|
||||
throw new Error('nargs must be OPTIONAL to supply const');
|
||||
}
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionAppend, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionAppend#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Save result in namespace object
|
||||
**/
|
||||
ActionAppend.prototype.call = function (parser, namespace, values) {
|
||||
var items = (namespace[this.dest] || []).slice();
|
||||
items.push(values);
|
||||
namespace.set(this.dest, items);
|
||||
};
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*:nodoc:*
|
||||
* class ActionAppendConstant
|
||||
*
|
||||
* This stores a list, and appends the value specified by
|
||||
* the const keyword argument to the list.
|
||||
* (Note that the const keyword argument defaults to null.)
|
||||
* The 'appendConst' action is typically useful when multiple
|
||||
* arguments need to store constants to the same list.
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../../action');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionAppendConstant(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionAppendConstant = module.exports = function ActionAppendConstant(options) {
|
||||
options = options || {};
|
||||
options.nargs = 0;
|
||||
if (typeof options.constant === 'undefined') {
|
||||
throw new Error('constant option is required for appendAction');
|
||||
}
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionAppendConstant, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionAppendConstant#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Save result in namespace object
|
||||
**/
|
||||
ActionAppendConstant.prototype.call = function (parser, namespace) {
|
||||
var items = [].concat(namespace[this.dest] || []);
|
||||
items.push(this.constant);
|
||||
namespace.set(this.dest, items);
|
||||
};
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*:nodoc:*
|
||||
* class ActionCount
|
||||
*
|
||||
* This counts the number of times a keyword argument occurs.
|
||||
* For example, this is useful for increasing verbosity levels
|
||||
*
|
||||
* This class inherided from [[Action]]
|
||||
*
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionCount(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionCount = module.exports = function ActionCount(options) {
|
||||
options = options || {};
|
||||
options.nargs = 0;
|
||||
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionCount, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionCount#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Save result in namespace object
|
||||
**/
|
||||
ActionCount.prototype.call = function (parser, namespace) {
|
||||
namespace.set(this.dest, (namespace[this.dest] || 0) + 1);
|
||||
};
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*:nodoc:*
|
||||
* class ActionHelp
|
||||
*
|
||||
* Support action for printing help
|
||||
* This class inherided from [[Action]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionHelp(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionHelp = module.exports = function ActionHelp(options) {
|
||||
options = options || {};
|
||||
if (options.defaultValue !== null) {
|
||||
options.defaultValue = options.defaultValue;
|
||||
} else {
|
||||
options.defaultValue = c.SUPPRESS;
|
||||
}
|
||||
options.dest = (options.dest !== null ? options.dest : c.SUPPRESS);
|
||||
options.nargs = 0;
|
||||
Action.call(this, options);
|
||||
|
||||
};
|
||||
util.inherits(ActionHelp, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionHelp#call(parser, namespace, values, optionString)
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Print help and exit
|
||||
**/
|
||||
ActionHelp.prototype.call = function (parser) {
|
||||
parser.printHelp();
|
||||
parser.exit();
|
||||
};
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*:nodoc:*
|
||||
* class ActionStore
|
||||
*
|
||||
* This action just stores the argument’s value. This is the default action.
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
*
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionStore(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionStore = module.exports = function ActionStore(options) {
|
||||
options = options || {};
|
||||
if (this.nargs <= 0) {
|
||||
throw new Error('nargs for store actions must be > 0; if you ' +
|
||||
'have nothing to store, actions such as store ' +
|
||||
'true or store const may be more appropriate');
|
||||
|
||||
}
|
||||
if (typeof this.constant !== 'undefined' && this.nargs !== c.OPTIONAL) {
|
||||
throw new Error('nargs must be OPTIONAL to supply const');
|
||||
}
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionStore, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionStore#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Save result in namespace object
|
||||
**/
|
||||
ActionStore.prototype.call = function (parser, namespace, values) {
|
||||
namespace.set(this.dest, values);
|
||||
};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*:nodoc:*
|
||||
* class ActionStoreConstant
|
||||
*
|
||||
* This action stores the value specified by the const keyword argument.
|
||||
* (Note that the const keyword argument defaults to the rather unhelpful null.)
|
||||
* The 'store_const' action is most commonly used with optional
|
||||
* arguments that specify some sort of flag.
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../../action');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionStoreConstant(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionStoreConstant = module.exports = function ActionStoreConstant(options) {
|
||||
options = options || {};
|
||||
options.nargs = 0;
|
||||
if (typeof options.constant === 'undefined') {
|
||||
throw new Error('constant option is required for storeAction');
|
||||
}
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionStoreConstant, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionStoreConstant#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Save result in namespace object
|
||||
**/
|
||||
ActionStoreConstant.prototype.call = function (parser, namespace) {
|
||||
namespace.set(this.dest, this.constant);
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*:nodoc:*
|
||||
* class ActionStoreFalse
|
||||
*
|
||||
* This action store the values False respectively.
|
||||
* This is special cases of 'storeConst'
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var ActionStoreConstant = require('./constant');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionStoreFalse(options)
|
||||
* - options (object): hash of options see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionStoreFalse = module.exports = function ActionStoreFalse(options) {
|
||||
options = options || {};
|
||||
options.constant = false;
|
||||
options.defaultValue = options.defaultValue !== null ? options.defaultValue : true;
|
||||
ActionStoreConstant.call(this, options);
|
||||
};
|
||||
util.inherits(ActionStoreFalse, ActionStoreConstant);
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*:nodoc:*
|
||||
* class ActionStoreTrue
|
||||
*
|
||||
* This action store the values True respectively.
|
||||
* This isspecial cases of 'storeConst'
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var ActionStoreConstant = require('./constant');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionStoreTrue(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionStoreTrue = module.exports = function ActionStoreTrue(options) {
|
||||
options = options || {};
|
||||
options.constant = true;
|
||||
options.defaultValue = options.defaultValue !== null ? options.defaultValue : false;
|
||||
ActionStoreConstant.call(this, options);
|
||||
};
|
||||
util.inherits(ActionStoreTrue, ActionStoreConstant);
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/** internal
|
||||
* class ActionSubparsers
|
||||
*
|
||||
* Support the creation of such sub-commands with the addSubparsers()
|
||||
*
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var format = require('util').format;
|
||||
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
// Errors
|
||||
var argumentErrorHelper = require('../argument/error');
|
||||
|
||||
|
||||
/*:nodoc:*
|
||||
* new ChoicesPseudoAction(name, help)
|
||||
*
|
||||
* Create pseudo action for correct help text
|
||||
*
|
||||
**/
|
||||
function ChoicesPseudoAction(name, help) {
|
||||
var options = {
|
||||
optionStrings: [],
|
||||
dest: name,
|
||||
help: help
|
||||
};
|
||||
|
||||
Action.call(this, options);
|
||||
}
|
||||
|
||||
util.inherits(ChoicesPseudoAction, Action);
|
||||
|
||||
/**
|
||||
* new ActionSubparsers(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
function ActionSubparsers(options) {
|
||||
options = options || {};
|
||||
options.dest = options.dest || c.SUPPRESS;
|
||||
options.nargs = c.PARSER;
|
||||
|
||||
this.debug = (options.debug === true);
|
||||
|
||||
this._progPrefix = options.prog;
|
||||
this._parserClass = options.parserClass;
|
||||
this._nameParserMap = {};
|
||||
this._choicesActions = [];
|
||||
|
||||
options.choices = this._nameParserMap;
|
||||
Action.call(this, options);
|
||||
}
|
||||
|
||||
util.inherits(ActionSubparsers, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionSubparsers#addParser(name, options) -> ArgumentParser
|
||||
* - name (string): sub-command name
|
||||
* - options (object): see [[ArgumentParser.new]]
|
||||
*
|
||||
* Note:
|
||||
* addParser supports an additional aliases option,
|
||||
* which allows multiple strings to refer to the same subparser.
|
||||
* This example, like svn, aliases co as a shorthand for checkout
|
||||
*
|
||||
**/
|
||||
ActionSubparsers.prototype.addParser = function (name, options) {
|
||||
var parser;
|
||||
|
||||
var self = this;
|
||||
|
||||
options = options || {};
|
||||
|
||||
options.debug = (this.debug === true);
|
||||
|
||||
// set program from the existing prefix
|
||||
if (!options.prog) {
|
||||
options.prog = this._progPrefix + ' ' + name;
|
||||
}
|
||||
|
||||
var aliases = options.aliases || [];
|
||||
|
||||
// create a pseudo-action to hold the choice help
|
||||
if (!!options.help || typeof options.help === 'string') {
|
||||
var help = options.help;
|
||||
delete options.help;
|
||||
|
||||
var choiceAction = new ChoicesPseudoAction(name, help);
|
||||
this._choicesActions.push(choiceAction);
|
||||
}
|
||||
|
||||
// create the parser and add it to the map
|
||||
parser = new this._parserClass(options);
|
||||
this._nameParserMap[name] = parser;
|
||||
|
||||
// make parser available under aliases also
|
||||
aliases.forEach(function (alias) {
|
||||
self._nameParserMap[alias] = parser;
|
||||
});
|
||||
|
||||
return parser;
|
||||
};
|
||||
|
||||
ActionSubparsers.prototype._getSubactions = function () {
|
||||
return this._choicesActions;
|
||||
};
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionSubparsers#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Call the action. Parse input aguments
|
||||
**/
|
||||
ActionSubparsers.prototype.call = function (parser, namespace, values) {
|
||||
var parserName = values[0];
|
||||
var argStrings = values.slice(1);
|
||||
|
||||
// set the parser name if requested
|
||||
if (this.dest !== c.SUPPRESS) {
|
||||
namespace[this.dest] = parserName;
|
||||
}
|
||||
|
||||
// select the parser
|
||||
if (this._nameParserMap[parserName]) {
|
||||
parser = this._nameParserMap[parserName];
|
||||
} else {
|
||||
throw argumentErrorHelper(format(
|
||||
'Unknown parser "%s" (choices: [%s]).',
|
||||
parserName,
|
||||
Object.keys(this._nameParserMap).join(', ')
|
||||
));
|
||||
}
|
||||
|
||||
// parse all the remaining options into the namespace
|
||||
parser.parseArgs(argStrings, namespace);
|
||||
};
|
||||
|
||||
module.exports = ActionSubparsers;
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*:nodoc:*
|
||||
* class ActionVersion
|
||||
*
|
||||
* Support action for printing program version
|
||||
* This class inherited from [[Action]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var Action = require('../action');
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
var c = require('../const');
|
||||
|
||||
/*:nodoc:*
|
||||
* new ActionVersion(options)
|
||||
* - options (object): options hash see [[Action.new]]
|
||||
*
|
||||
**/
|
||||
var ActionVersion = module.exports = function ActionVersion(options) {
|
||||
options = options || {};
|
||||
options.defaultValue = (options.defaultValue ? options.defaultValue : c.SUPPRESS);
|
||||
options.dest = (options.dest || c.SUPPRESS);
|
||||
options.nargs = 0;
|
||||
this.version = options.version;
|
||||
Action.call(this, options);
|
||||
};
|
||||
util.inherits(ActionVersion, Action);
|
||||
|
||||
/*:nodoc:*
|
||||
* ActionVersion#call(parser, namespace, values, optionString) -> Void
|
||||
* - parser (ArgumentParser): current parser
|
||||
* - namespace (Namespace): namespace for output data
|
||||
* - values (Array): parsed values
|
||||
* - optionString (Array): input option string(not parsed)
|
||||
*
|
||||
* Print version and exit
|
||||
**/
|
||||
ActionVersion.prototype.call = function (parser) {
|
||||
var version = this.version || parser.version;
|
||||
var formatter = parser._getFormatter();
|
||||
formatter.addText(version);
|
||||
parser.exit(0, formatter.formatHelp());
|
||||
};
|
||||
+482
@@ -0,0 +1,482 @@
|
||||
/** internal
|
||||
* class ActionContainer
|
||||
*
|
||||
* Action container. Parent for [[ArgumentParser]] and [[ArgumentGroup]]
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
var format = require('util').format;
|
||||
|
||||
// Constants
|
||||
var c = require('./const');
|
||||
|
||||
var $$ = require('./utils');
|
||||
|
||||
//Actions
|
||||
var ActionHelp = require('./action/help');
|
||||
var ActionAppend = require('./action/append');
|
||||
var ActionAppendConstant = require('./action/append/constant');
|
||||
var ActionCount = require('./action/count');
|
||||
var ActionStore = require('./action/store');
|
||||
var ActionStoreConstant = require('./action/store/constant');
|
||||
var ActionStoreTrue = require('./action/store/true');
|
||||
var ActionStoreFalse = require('./action/store/false');
|
||||
var ActionVersion = require('./action/version');
|
||||
var ActionSubparsers = require('./action/subparsers');
|
||||
|
||||
// Errors
|
||||
var argumentErrorHelper = require('./argument/error');
|
||||
|
||||
/**
|
||||
* new ActionContainer(options)
|
||||
*
|
||||
* Action container. Parent for [[ArgumentParser]] and [[ArgumentGroup]]
|
||||
*
|
||||
* ##### Options:
|
||||
*
|
||||
* - `description` -- A description of what the program does
|
||||
* - `prefixChars` -- Characters that prefix optional arguments
|
||||
* - `argumentDefault` -- The default value for all arguments
|
||||
* - `conflictHandler` -- The conflict handler to use for duplicate arguments
|
||||
**/
|
||||
var ActionContainer = module.exports = function ActionContainer(options) {
|
||||
options = options || {};
|
||||
|
||||
this.description = options.description;
|
||||
this.argumentDefault = options.argumentDefault;
|
||||
this.prefixChars = options.prefixChars || '';
|
||||
this.conflictHandler = options.conflictHandler;
|
||||
|
||||
// set up registries
|
||||
this._registries = {};
|
||||
|
||||
// register actions
|
||||
this.register('action', null, ActionStore);
|
||||
this.register('action', 'store', ActionStore);
|
||||
this.register('action', 'storeConst', ActionStoreConstant);
|
||||
this.register('action', 'storeTrue', ActionStoreTrue);
|
||||
this.register('action', 'storeFalse', ActionStoreFalse);
|
||||
this.register('action', 'append', ActionAppend);
|
||||
this.register('action', 'appendConst', ActionAppendConstant);
|
||||
this.register('action', 'count', ActionCount);
|
||||
this.register('action', 'help', ActionHelp);
|
||||
this.register('action', 'version', ActionVersion);
|
||||
this.register('action', 'parsers', ActionSubparsers);
|
||||
|
||||
// raise an exception if the conflict handler is invalid
|
||||
this._getHandler();
|
||||
|
||||
// action storage
|
||||
this._actions = [];
|
||||
this._optionStringActions = {};
|
||||
|
||||
// groups
|
||||
this._actionGroups = [];
|
||||
this._mutuallyExclusiveGroups = [];
|
||||
|
||||
// defaults storage
|
||||
this._defaults = {};
|
||||
|
||||
// determines whether an "option" looks like a negative number
|
||||
// -1, -1.5 -5e+4
|
||||
this._regexpNegativeNumber = new RegExp('^[-]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$');
|
||||
|
||||
// whether or not there are any optionals that look like negative
|
||||
// numbers -- uses a list so it can be shared and edited
|
||||
this._hasNegativeNumberOptionals = [];
|
||||
};
|
||||
|
||||
// Groups must be required, then ActionContainer already defined
|
||||
var ArgumentGroup = require('./argument/group');
|
||||
var MutuallyExclusiveGroup = require('./argument/exclusive');
|
||||
|
||||
//
|
||||
// Registration methods
|
||||
//
|
||||
|
||||
/**
|
||||
* ActionContainer#register(registryName, value, object) -> Void
|
||||
* - registryName (String) : object type action|type
|
||||
* - value (string) : keyword
|
||||
* - object (Object|Function) : handler
|
||||
*
|
||||
* Register handlers
|
||||
**/
|
||||
ActionContainer.prototype.register = function (registryName, value, object) {
|
||||
this._registries[registryName] = this._registries[registryName] || {};
|
||||
this._registries[registryName][value] = object;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._registryGet = function (registryName, value, defaultValue) {
|
||||
if (arguments.length < 3) {
|
||||
defaultValue = null;
|
||||
}
|
||||
return this._registries[registryName][value] || defaultValue;
|
||||
};
|
||||
|
||||
//
|
||||
// Namespace default accessor methods
|
||||
//
|
||||
|
||||
/**
|
||||
* ActionContainer#setDefaults(options) -> Void
|
||||
* - options (object):hash of options see [[Action.new]]
|
||||
*
|
||||
* Set defaults
|
||||
**/
|
||||
ActionContainer.prototype.setDefaults = function (options) {
|
||||
options = options || {};
|
||||
for (var property in options) {
|
||||
if ($$.has(options, property)) {
|
||||
this._defaults[property] = options[property];
|
||||
}
|
||||
}
|
||||
|
||||
// if these defaults match any existing arguments, replace the previous
|
||||
// default on the object with the new one
|
||||
this._actions.forEach(function (action) {
|
||||
if ($$.has(options, action.dest)) {
|
||||
action.defaultValue = options[action.dest];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* ActionContainer#getDefault(dest) -> Mixed
|
||||
* - dest (string): action destination
|
||||
*
|
||||
* Return action default value
|
||||
**/
|
||||
ActionContainer.prototype.getDefault = function (dest) {
|
||||
var result = $$.has(this._defaults, dest) ? this._defaults[dest] : null;
|
||||
|
||||
this._actions.forEach(function (action) {
|
||||
if (action.dest === dest && $$.has(action, 'defaultValue')) {
|
||||
result = action.defaultValue;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
//
|
||||
// Adding argument actions
|
||||
//
|
||||
|
||||
/**
|
||||
* ActionContainer#addArgument(args, options) -> Object
|
||||
* - args (String|Array): argument key, or array of argument keys
|
||||
* - options (Object): action objects see [[Action.new]]
|
||||
*
|
||||
* #### Examples
|
||||
* - addArgument([ '-f', '--foo' ], { action: 'store', defaultValue: 1, ... })
|
||||
* - addArgument([ 'bar' ], { action: 'store', nargs: 1, ... })
|
||||
* - addArgument('--baz', { action: 'store', nargs: 1, ... })
|
||||
**/
|
||||
ActionContainer.prototype.addArgument = function (args, options) {
|
||||
args = args;
|
||||
options = options || {};
|
||||
|
||||
if (typeof args === 'string') {
|
||||
args = [ args ];
|
||||
}
|
||||
if (!Array.isArray(args)) {
|
||||
throw new TypeError('addArgument first argument should be a string or an array');
|
||||
}
|
||||
if (typeof options !== 'object' || Array.isArray(options)) {
|
||||
throw new TypeError('addArgument second argument should be a hash');
|
||||
}
|
||||
|
||||
// if no positional args are supplied or only one is supplied and
|
||||
// it doesn't look like an option string, parse a positional argument
|
||||
if (!args || args.length === 1 && this.prefixChars.indexOf(args[0][0]) < 0) {
|
||||
if (args && !!options.dest) {
|
||||
throw new Error('dest supplied twice for positional argument');
|
||||
}
|
||||
options = this._getPositional(args, options);
|
||||
|
||||
// otherwise, we're adding an optional argument
|
||||
} else {
|
||||
options = this._getOptional(args, options);
|
||||
}
|
||||
|
||||
// if no default was supplied, use the parser-level default
|
||||
if (typeof options.defaultValue === 'undefined') {
|
||||
var dest = options.dest;
|
||||
if ($$.has(this._defaults, dest)) {
|
||||
options.defaultValue = this._defaults[dest];
|
||||
} else if (typeof this.argumentDefault !== 'undefined') {
|
||||
options.defaultValue = this.argumentDefault;
|
||||
}
|
||||
}
|
||||
|
||||
// create the action object, and add it to the parser
|
||||
var ActionClass = this._popActionClass(options);
|
||||
if (typeof ActionClass !== 'function') {
|
||||
throw new Error(format('Unknown action "%s".', ActionClass));
|
||||
}
|
||||
var action = new ActionClass(options);
|
||||
|
||||
// throw an error if the action type is not callable
|
||||
var typeFunction = this._registryGet('type', action.type, action.type);
|
||||
if (typeof typeFunction !== 'function') {
|
||||
throw new Error(format('"%s" is not callable', typeFunction));
|
||||
}
|
||||
|
||||
return this._addAction(action);
|
||||
};
|
||||
|
||||
/**
|
||||
* ActionContainer#addArgumentGroup(options) -> ArgumentGroup
|
||||
* - options (Object): hash of options see [[ArgumentGroup.new]]
|
||||
*
|
||||
* Create new arguments groups
|
||||
**/
|
||||
ActionContainer.prototype.addArgumentGroup = function (options) {
|
||||
var group = new ArgumentGroup(this, options);
|
||||
this._actionGroups.push(group);
|
||||
return group;
|
||||
};
|
||||
|
||||
/**
|
||||
* ActionContainer#addMutuallyExclusiveGroup(options) -> ArgumentGroup
|
||||
* - options (Object): {required: false}
|
||||
*
|
||||
* Create new mutual exclusive groups
|
||||
**/
|
||||
ActionContainer.prototype.addMutuallyExclusiveGroup = function (options) {
|
||||
var group = new MutuallyExclusiveGroup(this, options);
|
||||
this._mutuallyExclusiveGroups.push(group);
|
||||
return group;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._addAction = function (action) {
|
||||
var self = this;
|
||||
|
||||
// resolve any conflicts
|
||||
this._checkConflict(action);
|
||||
|
||||
// add to actions list
|
||||
this._actions.push(action);
|
||||
action.container = this;
|
||||
|
||||
// index the action by any option strings it has
|
||||
action.optionStrings.forEach(function (optionString) {
|
||||
self._optionStringActions[optionString] = action;
|
||||
});
|
||||
|
||||
// set the flag if any option strings look like negative numbers
|
||||
action.optionStrings.forEach(function (optionString) {
|
||||
if (optionString.match(self._regexpNegativeNumber)) {
|
||||
if (!self._hasNegativeNumberOptionals.some(Boolean)) {
|
||||
self._hasNegativeNumberOptionals.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// return the created action
|
||||
return action;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._removeAction = function (action) {
|
||||
var actionIndex = this._actions.indexOf(action);
|
||||
if (actionIndex >= 0) {
|
||||
this._actions.splice(actionIndex, 1);
|
||||
}
|
||||
};
|
||||
|
||||
ActionContainer.prototype._addContainerActions = function (container) {
|
||||
// collect groups by titles
|
||||
var titleGroupMap = {};
|
||||
this._actionGroups.forEach(function (group) {
|
||||
if (titleGroupMap[group.title]) {
|
||||
throw new Error(format('Cannot merge actions - two groups are named "%s".', group.title));
|
||||
}
|
||||
titleGroupMap[group.title] = group;
|
||||
});
|
||||
|
||||
// map each action to its group
|
||||
var groupMap = {};
|
||||
function actionHash(action) {
|
||||
// unique (hopefully?) string suitable as dictionary key
|
||||
return action.getName();
|
||||
}
|
||||
container._actionGroups.forEach(function (group) {
|
||||
// if a group with the title exists, use that, otherwise
|
||||
// create a new group matching the container's group
|
||||
if (!titleGroupMap[group.title]) {
|
||||
titleGroupMap[group.title] = this.addArgumentGroup({
|
||||
title: group.title,
|
||||
description: group.description
|
||||
});
|
||||
}
|
||||
|
||||
// map the actions to their new group
|
||||
group._groupActions.forEach(function (action) {
|
||||
groupMap[actionHash(action)] = titleGroupMap[group.title];
|
||||
});
|
||||
}, this);
|
||||
|
||||
// add container's mutually exclusive groups
|
||||
// NOTE: if add_mutually_exclusive_group ever gains title= and
|
||||
// description= then this code will need to be expanded as above
|
||||
var mutexGroup;
|
||||
container._mutuallyExclusiveGroups.forEach(function (group) {
|
||||
mutexGroup = this.addMutuallyExclusiveGroup({
|
||||
required: group.required
|
||||
});
|
||||
// map the actions to their new mutex group
|
||||
group._groupActions.forEach(function (action) {
|
||||
groupMap[actionHash(action)] = mutexGroup;
|
||||
});
|
||||
}, this); // forEach takes a 'this' argument
|
||||
|
||||
// add all actions to this container or their group
|
||||
container._actions.forEach(function (action) {
|
||||
var key = actionHash(action);
|
||||
if (groupMap[key]) {
|
||||
groupMap[key]._addAction(action);
|
||||
} else {
|
||||
this._addAction(action);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ActionContainer.prototype._getPositional = function (dest, options) {
|
||||
if (Array.isArray(dest)) {
|
||||
dest = dest[0];
|
||||
}
|
||||
// make sure required is not specified
|
||||
if (options.required) {
|
||||
throw new Error('"required" is an invalid argument for positionals.');
|
||||
}
|
||||
|
||||
// mark positional arguments as required if at least one is
|
||||
// always required
|
||||
if (options.nargs !== c.OPTIONAL && options.nargs !== c.ZERO_OR_MORE) {
|
||||
options.required = true;
|
||||
}
|
||||
if (options.nargs === c.ZERO_OR_MORE && typeof options.defaultValue === 'undefined') {
|
||||
options.required = true;
|
||||
}
|
||||
|
||||
// return the keyword arguments with no option strings
|
||||
options.dest = dest;
|
||||
options.optionStrings = [];
|
||||
return options;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._getOptional = function (args, options) {
|
||||
var prefixChars = this.prefixChars;
|
||||
var optionStrings = [];
|
||||
var optionStringsLong = [];
|
||||
|
||||
// determine short and long option strings
|
||||
args.forEach(function (optionString) {
|
||||
// error on strings that don't start with an appropriate prefix
|
||||
if (prefixChars.indexOf(optionString[0]) < 0) {
|
||||
throw new Error(format('Invalid option string "%s": must start with a "%s".',
|
||||
optionString,
|
||||
prefixChars
|
||||
));
|
||||
}
|
||||
|
||||
// strings starting with two prefix characters are long options
|
||||
optionStrings.push(optionString);
|
||||
if (optionString.length > 1 && prefixChars.indexOf(optionString[1]) >= 0) {
|
||||
optionStringsLong.push(optionString);
|
||||
}
|
||||
});
|
||||
|
||||
// infer dest, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
|
||||
var dest = options.dest || null;
|
||||
delete options.dest;
|
||||
|
||||
if (!dest) {
|
||||
var optionStringDest = optionStringsLong.length ? optionStringsLong[0] : optionStrings[0];
|
||||
dest = $$.trimChars(optionStringDest, this.prefixChars);
|
||||
|
||||
if (dest.length === 0) {
|
||||
throw new Error(
|
||||
format('dest= is required for options like "%s"', optionStrings.join(', '))
|
||||
);
|
||||
}
|
||||
dest = dest.replace(/-/g, '_');
|
||||
}
|
||||
|
||||
// return the updated keyword arguments
|
||||
options.dest = dest;
|
||||
options.optionStrings = optionStrings;
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._popActionClass = function (options, defaultValue) {
|
||||
defaultValue = defaultValue || null;
|
||||
|
||||
var action = (options.action || defaultValue);
|
||||
delete options.action;
|
||||
|
||||
var actionClass = this._registryGet('action', action, action);
|
||||
return actionClass;
|
||||
};
|
||||
|
||||
ActionContainer.prototype._getHandler = function () {
|
||||
var handlerString = this.conflictHandler;
|
||||
var handlerFuncName = '_handleConflict' + $$.capitalize(handlerString);
|
||||
var func = this[handlerFuncName];
|
||||
if (typeof func === 'undefined') {
|
||||
var msg = 'invalid conflict resolution value: ' + handlerString;
|
||||
throw new Error(msg);
|
||||
} else {
|
||||
return func;
|
||||
}
|
||||
};
|
||||
|
||||
ActionContainer.prototype._checkConflict = function (action) {
|
||||
var optionStringActions = this._optionStringActions;
|
||||
var conflictOptionals = [];
|
||||
|
||||
// find all options that conflict with this option
|
||||
// collect pairs, the string, and an existing action that it conflicts with
|
||||
action.optionStrings.forEach(function (optionString) {
|
||||
var conflOptional = optionStringActions[optionString];
|
||||
if (typeof conflOptional !== 'undefined') {
|
||||
conflictOptionals.push([ optionString, conflOptional ]);
|
||||
}
|
||||
});
|
||||
|
||||
if (conflictOptionals.length > 0) {
|
||||
var conflictHandler = this._getHandler();
|
||||
conflictHandler.call(this, action, conflictOptionals);
|
||||
}
|
||||
};
|
||||
|
||||
ActionContainer.prototype._handleConflictError = function (action, conflOptionals) {
|
||||
var conflicts = conflOptionals.map(function (pair) { return pair[0]; });
|
||||
conflicts = conflicts.join(', ');
|
||||
throw argumentErrorHelper(
|
||||
action,
|
||||
format('Conflicting option string(s): %s', conflicts)
|
||||
);
|
||||
};
|
||||
|
||||
ActionContainer.prototype._handleConflictResolve = function (action, conflOptionals) {
|
||||
// remove all conflicting options
|
||||
var self = this;
|
||||
conflOptionals.forEach(function (pair) {
|
||||
var optionString = pair[0];
|
||||
var conflictingAction = pair[1];
|
||||
// remove the conflicting option string
|
||||
var i = conflictingAction.optionStrings.indexOf(optionString);
|
||||
if (i >= 0) {
|
||||
conflictingAction.optionStrings.splice(i, 1);
|
||||
}
|
||||
delete self._optionStringActions[optionString];
|
||||
// if the option now has no option string, remove it from the
|
||||
// container holding it
|
||||
if (conflictingAction.optionStrings.length === 0) {
|
||||
conflictingAction.container._removeAction(conflictingAction);
|
||||
}
|
||||
});
|
||||
};
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
module.exports.ArgumentParser = require('./argument_parser.js');
|
||||
module.exports.Namespace = require('./namespace');
|
||||
module.exports.Action = require('./action');
|
||||
module.exports.HelpFormatter = require('./help/formatter.js');
|
||||
module.exports.Const = require('./const.js');
|
||||
|
||||
module.exports.ArgumentDefaultsHelpFormatter =
|
||||
require('./help/added_formatters.js').ArgumentDefaultsHelpFormatter;
|
||||
module.exports.RawDescriptionHelpFormatter =
|
||||
require('./help/added_formatters.js').RawDescriptionHelpFormatter;
|
||||
module.exports.RawTextHelpFormatter =
|
||||
require('./help/added_formatters.js').RawTextHelpFormatter;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
var format = require('util').format;
|
||||
|
||||
|
||||
var ERR_CODE = 'ARGError';
|
||||
|
||||
/*:nodoc:*
|
||||
* argumentError(argument, message) -> TypeError
|
||||
* - argument (Object): action with broken argument
|
||||
* - message (String): error message
|
||||
*
|
||||
* Error format helper. An error from creating or using an argument
|
||||
* (optional or positional). The string value of this exception
|
||||
* is the message, augmented with information
|
||||
* about the argument that caused it.
|
||||
*
|
||||
* #####Example
|
||||
*
|
||||
* var argumentErrorHelper = require('./argument/error');
|
||||
* if (conflictOptionals.length > 0) {
|
||||
* throw argumentErrorHelper(
|
||||
* action,
|
||||
* format('Conflicting option string(s): %s', conflictOptionals.join(', '))
|
||||
* );
|
||||
* }
|
||||
*
|
||||
**/
|
||||
module.exports = function (argument, message) {
|
||||
var argumentName = null;
|
||||
var errMessage;
|
||||
var err;
|
||||
|
||||
if (argument.getName) {
|
||||
argumentName = argument.getName();
|
||||
} else {
|
||||
argumentName = '' + argument;
|
||||
}
|
||||
|
||||
if (!argumentName) {
|
||||
errMessage = message;
|
||||
} else {
|
||||
errMessage = format('argument "%s": %s', argumentName, message);
|
||||
}
|
||||
|
||||
err = new TypeError(errMessage);
|
||||
err.code = ERR_CODE;
|
||||
return err;
|
||||
};
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/** internal
|
||||
* class MutuallyExclusiveGroup
|
||||
*
|
||||
* Group arguments.
|
||||
* By default, ArgumentParser groups command-line arguments
|
||||
* into “positional arguments” and “optional arguments”
|
||||
* when displaying help messages. When there is a better
|
||||
* conceptual grouping of arguments than this default one,
|
||||
* appropriate groups can be created using the addArgumentGroup() method
|
||||
*
|
||||
* This class inherited from [[ArgumentContainer]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var ArgumentGroup = require('./group');
|
||||
|
||||
/**
|
||||
* new MutuallyExclusiveGroup(container, options)
|
||||
* - container (object): main container
|
||||
* - options (object): options.required -> true/false
|
||||
*
|
||||
* `required` could be an argument itself, but making it a property of
|
||||
* the options argument is more consistent with the JS adaptation of the Python)
|
||||
**/
|
||||
var MutuallyExclusiveGroup = module.exports = function MutuallyExclusiveGroup(container, options) {
|
||||
var required;
|
||||
options = options || {};
|
||||
required = options.required || false;
|
||||
ArgumentGroup.call(this, container);
|
||||
this.required = required;
|
||||
|
||||
};
|
||||
util.inherits(MutuallyExclusiveGroup, ArgumentGroup);
|
||||
|
||||
|
||||
MutuallyExclusiveGroup.prototype._addAction = function (action) {
|
||||
var msg;
|
||||
if (action.required) {
|
||||
msg = 'mutually exclusive arguments must be optional';
|
||||
throw new Error(msg);
|
||||
}
|
||||
action = this._container._addAction(action);
|
||||
this._groupActions.push(action);
|
||||
return action;
|
||||
};
|
||||
|
||||
|
||||
MutuallyExclusiveGroup.prototype._removeAction = function (action) {
|
||||
this._container._removeAction(action);
|
||||
this._groupActions.remove(action);
|
||||
};
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/** internal
|
||||
* class ArgumentGroup
|
||||
*
|
||||
* Group arguments.
|
||||
* By default, ArgumentParser groups command-line arguments
|
||||
* into “positional arguments” and “optional arguments”
|
||||
* when displaying help messages. When there is a better
|
||||
* conceptual grouping of arguments than this default one,
|
||||
* appropriate groups can be created using the addArgumentGroup() method
|
||||
*
|
||||
* This class inherited from [[ArgumentContainer]]
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var ActionContainer = require('../action_container');
|
||||
|
||||
|
||||
/**
|
||||
* new ArgumentGroup(container, options)
|
||||
* - container (object): main container
|
||||
* - options (object): hash of group options
|
||||
*
|
||||
* #### options
|
||||
* - **prefixChars** group name prefix
|
||||
* - **argumentDefault** default argument value
|
||||
* - **title** group title
|
||||
* - **description** group description
|
||||
*
|
||||
**/
|
||||
var ArgumentGroup = module.exports = function ArgumentGroup(container, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
// add any missing keyword arguments by checking the container
|
||||
options.conflictHandler = (options.conflictHandler || container.conflictHandler);
|
||||
options.prefixChars = (options.prefixChars || container.prefixChars);
|
||||
options.argumentDefault = (options.argumentDefault || container.argumentDefault);
|
||||
|
||||
ActionContainer.call(this, options);
|
||||
|
||||
// group attributes
|
||||
this.title = options.title;
|
||||
this._groupActions = [];
|
||||
|
||||
// share most attributes with the container
|
||||
this._container = container;
|
||||
this._registries = container._registries;
|
||||
this._actions = container._actions;
|
||||
this._optionStringActions = container._optionStringActions;
|
||||
this._defaults = container._defaults;
|
||||
this._hasNegativeNumberOptionals = container._hasNegativeNumberOptionals;
|
||||
this._mutuallyExclusiveGroups = container._mutuallyExclusiveGroups;
|
||||
};
|
||||
util.inherits(ArgumentGroup, ActionContainer);
|
||||
|
||||
|
||||
ArgumentGroup.prototype._addAction = function (action) {
|
||||
// Parent add action
|
||||
action = ActionContainer.prototype._addAction.call(this, action);
|
||||
this._groupActions.push(action);
|
||||
return action;
|
||||
};
|
||||
|
||||
|
||||
ArgumentGroup.prototype._removeAction = function (action) {
|
||||
// Parent remove action
|
||||
ActionContainer.prototype._removeAction.call(this, action);
|
||||
var actionIndex = this._groupActions.indexOf(action);
|
||||
if (actionIndex >= 0) {
|
||||
this._groupActions.splice(actionIndex, 1);
|
||||
}
|
||||
};
|
||||
|
||||
+1161
File diff suppressed because it is too large
Load Diff
+21
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports.EOL = '\n';
|
||||
|
||||
module.exports.SUPPRESS = '==SUPPRESS==';
|
||||
|
||||
module.exports.OPTIONAL = '?';
|
||||
|
||||
module.exports.ZERO_OR_MORE = '*';
|
||||
|
||||
module.exports.ONE_OR_MORE = '+';
|
||||
|
||||
module.exports.PARSER = 'A...';
|
||||
|
||||
module.exports.REMAINDER = '...';
|
||||
|
||||
module.exports._UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args';
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
var $$ = require('../utils');
|
||||
var HelpFormatter = require('./formatter.js');
|
||||
|
||||
/**
|
||||
* new RawDescriptionHelpFormatter(options)
|
||||
* new ArgumentParser({formatterClass: argparse.RawDescriptionHelpFormatter, ...})
|
||||
*
|
||||
* Help message formatter which adds default values to argument help.
|
||||
*
|
||||
* Only the name of this class is considered a public API. All the methods
|
||||
* provided by the class are considered an implementation detail.
|
||||
**/
|
||||
|
||||
function ArgumentDefaultsHelpFormatter(options) {
|
||||
HelpFormatter.call(this, options);
|
||||
}
|
||||
|
||||
util.inherits(ArgumentDefaultsHelpFormatter, HelpFormatter);
|
||||
|
||||
ArgumentDefaultsHelpFormatter.prototype._getHelpString = function (action) {
|
||||
var help = action.help;
|
||||
if (action.help.indexOf('%(defaultValue)s') === -1) {
|
||||
if (action.defaultValue !== c.SUPPRESS) {
|
||||
var defaulting_nargs = [ c.OPTIONAL, c.ZERO_OR_MORE ];
|
||||
if (action.isOptional() || (defaulting_nargs.indexOf(action.nargs) >= 0)) {
|
||||
help += ' (default: %(defaultValue)s)';
|
||||
}
|
||||
}
|
||||
}
|
||||
return help;
|
||||
};
|
||||
|
||||
module.exports.ArgumentDefaultsHelpFormatter = ArgumentDefaultsHelpFormatter;
|
||||
|
||||
/**
|
||||
* new RawDescriptionHelpFormatter(options)
|
||||
* new ArgumentParser({formatterClass: argparse.RawDescriptionHelpFormatter, ...})
|
||||
*
|
||||
* Help message formatter which retains any formatting in descriptions.
|
||||
*
|
||||
* Only the name of this class is considered a public API. All the methods
|
||||
* provided by the class are considered an implementation detail.
|
||||
**/
|
||||
|
||||
function RawDescriptionHelpFormatter(options) {
|
||||
HelpFormatter.call(this, options);
|
||||
}
|
||||
|
||||
util.inherits(RawDescriptionHelpFormatter, HelpFormatter);
|
||||
|
||||
RawDescriptionHelpFormatter.prototype._fillText = function (text, width, indent) {
|
||||
var lines = text.split('\n');
|
||||
lines = lines.map(function (line) {
|
||||
return $$.trimEnd(indent + line);
|
||||
});
|
||||
return lines.join('\n');
|
||||
};
|
||||
module.exports.RawDescriptionHelpFormatter = RawDescriptionHelpFormatter;
|
||||
|
||||
/**
|
||||
* new RawTextHelpFormatter(options)
|
||||
* new ArgumentParser({formatterClass: argparse.RawTextHelpFormatter, ...})
|
||||
*
|
||||
* Help message formatter which retains formatting of all help text.
|
||||
*
|
||||
* Only the name of this class is considered a public API. All the methods
|
||||
* provided by the class are considered an implementation detail.
|
||||
**/
|
||||
|
||||
function RawTextHelpFormatter(options) {
|
||||
RawDescriptionHelpFormatter.call(this, options);
|
||||
}
|
||||
|
||||
util.inherits(RawTextHelpFormatter, RawDescriptionHelpFormatter);
|
||||
|
||||
RawTextHelpFormatter.prototype._splitLines = function (text) {
|
||||
return text.split('\n');
|
||||
};
|
||||
|
||||
module.exports.RawTextHelpFormatter = RawTextHelpFormatter;
|
||||
+795
@@ -0,0 +1,795 @@
|
||||
/**
|
||||
* class HelpFormatter
|
||||
*
|
||||
* Formatter for generating usage messages and argument help strings. Only the
|
||||
* name of this class is considered a public API. All the methods provided by
|
||||
* the class are considered an implementation detail.
|
||||
*
|
||||
* Do not call in your code, use this class only for inherits your own forvatter
|
||||
*
|
||||
* ToDo add [additonal formatters][1]
|
||||
*
|
||||
* [1]:http://docs.python.org/dev/library/argparse.html#formatter-class
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var sprintf = require('sprintf-js').sprintf;
|
||||
|
||||
// Constants
|
||||
var c = require('../const');
|
||||
|
||||
var $$ = require('../utils');
|
||||
|
||||
|
||||
/*:nodoc:* internal
|
||||
* new Support(parent, heding)
|
||||
* - parent (object): parent section
|
||||
* - heading (string): header string
|
||||
*
|
||||
**/
|
||||
function Section(parent, heading) {
|
||||
this._parent = parent;
|
||||
this._heading = heading;
|
||||
this._items = [];
|
||||
}
|
||||
|
||||
/*:nodoc:* internal
|
||||
* Section#addItem(callback) -> Void
|
||||
* - callback (array): tuple with function and args
|
||||
*
|
||||
* Add function for single element
|
||||
**/
|
||||
Section.prototype.addItem = function (callback) {
|
||||
this._items.push(callback);
|
||||
};
|
||||
|
||||
/*:nodoc:* internal
|
||||
* Section#formatHelp(formatter) -> string
|
||||
* - formatter (HelpFormatter): current formatter
|
||||
*
|
||||
* Form help section string
|
||||
*
|
||||
**/
|
||||
Section.prototype.formatHelp = function (formatter) {
|
||||
var itemHelp, heading;
|
||||
|
||||
// format the indented section
|
||||
if (this._parent) {
|
||||
formatter._indent();
|
||||
}
|
||||
|
||||
itemHelp = this._items.map(function (item) {
|
||||
var obj, func, args;
|
||||
|
||||
obj = formatter;
|
||||
func = item[0];
|
||||
args = item[1];
|
||||
return func.apply(obj, args);
|
||||
});
|
||||
itemHelp = formatter._joinParts(itemHelp);
|
||||
|
||||
if (this._parent) {
|
||||
formatter._dedent();
|
||||
}
|
||||
|
||||
// return nothing if the section was empty
|
||||
if (!itemHelp) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// add the heading if the section was non-empty
|
||||
heading = '';
|
||||
if (this._heading && this._heading !== c.SUPPRESS) {
|
||||
var currentIndent = formatter.currentIndent;
|
||||
heading = $$.repeat(' ', currentIndent) + this._heading + ':' + c.EOL;
|
||||
}
|
||||
|
||||
// join the section-initialize newline, the heading and the help
|
||||
return formatter._joinParts([ c.EOL, heading, itemHelp, c.EOL ]);
|
||||
};
|
||||
|
||||
/**
|
||||
* new HelpFormatter(options)
|
||||
*
|
||||
* #### Options:
|
||||
* - `prog`: program name
|
||||
* - `indentIncriment`: indent step, default value 2
|
||||
* - `maxHelpPosition`: max help position, default value = 24
|
||||
* - `width`: line width
|
||||
*
|
||||
**/
|
||||
var HelpFormatter = module.exports = function HelpFormatter(options) {
|
||||
options = options || {};
|
||||
|
||||
this._prog = options.prog;
|
||||
|
||||
this._maxHelpPosition = options.maxHelpPosition || 24;
|
||||
this._width = (options.width || ((process.env.COLUMNS || 80) - 2));
|
||||
|
||||
this._currentIndent = 0;
|
||||
this._indentIncriment = options.indentIncriment || 2;
|
||||
this._level = 0;
|
||||
this._actionMaxLength = 0;
|
||||
|
||||
this._rootSection = new Section(null);
|
||||
this._currentSection = this._rootSection;
|
||||
|
||||
this._whitespaceMatcher = new RegExp('\\s+', 'g');
|
||||
this._longBreakMatcher = new RegExp(c.EOL + c.EOL + c.EOL + '+', 'g');
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._indent = function () {
|
||||
this._currentIndent += this._indentIncriment;
|
||||
this._level += 1;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._dedent = function () {
|
||||
this._currentIndent -= this._indentIncriment;
|
||||
this._level -= 1;
|
||||
if (this._currentIndent < 0) {
|
||||
throw new Error('Indent decreased below 0.');
|
||||
}
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._addItem = function (func, args) {
|
||||
this._currentSection.addItem([ func, args ]);
|
||||
};
|
||||
|
||||
//
|
||||
// Message building methods
|
||||
//
|
||||
|
||||
/**
|
||||
* HelpFormatter#startSection(heading) -> Void
|
||||
* - heading (string): header string
|
||||
*
|
||||
* Start new help section
|
||||
*
|
||||
* See alse [code example][1]
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.startSection(actionGroup.title);
|
||||
* formatter.addText(actionGroup.description);
|
||||
* formatter.addArguments(actionGroup._groupActions);
|
||||
* formatter.endSection();
|
||||
*
|
||||
**/
|
||||
HelpFormatter.prototype.startSection = function (heading) {
|
||||
this._indent();
|
||||
var section = new Section(this._currentSection, heading);
|
||||
var func = section.formatHelp.bind(section);
|
||||
this._addItem(func, [ this ]);
|
||||
this._currentSection = section;
|
||||
};
|
||||
|
||||
/**
|
||||
* HelpFormatter#endSection -> Void
|
||||
*
|
||||
* End help section
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.startSection(actionGroup.title);
|
||||
* formatter.addText(actionGroup.description);
|
||||
* formatter.addArguments(actionGroup._groupActions);
|
||||
* formatter.endSection();
|
||||
**/
|
||||
HelpFormatter.prototype.endSection = function () {
|
||||
this._currentSection = this._currentSection._parent;
|
||||
this._dedent();
|
||||
};
|
||||
|
||||
/**
|
||||
* HelpFormatter#addText(text) -> Void
|
||||
* - text (string): plain text
|
||||
*
|
||||
* Add plain text into current section
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.startSection(actionGroup.title);
|
||||
* formatter.addText(actionGroup.description);
|
||||
* formatter.addArguments(actionGroup._groupActions);
|
||||
* formatter.endSection();
|
||||
*
|
||||
**/
|
||||
HelpFormatter.prototype.addText = function (text) {
|
||||
if (text && text !== c.SUPPRESS) {
|
||||
this._addItem(this._formatText, [ text ]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* HelpFormatter#addUsage(usage, actions, groups, prefix) -> Void
|
||||
* - usage (string): usage text
|
||||
* - actions (array): actions list
|
||||
* - groups (array): groups list
|
||||
* - prefix (string): usage prefix
|
||||
*
|
||||
* Add usage data into current section
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.addUsage(this.usage, this._actions, []);
|
||||
* return formatter.formatHelp();
|
||||
*
|
||||
**/
|
||||
HelpFormatter.prototype.addUsage = function (usage, actions, groups, prefix) {
|
||||
if (usage !== c.SUPPRESS) {
|
||||
this._addItem(this._formatUsage, [ usage, actions, groups, prefix ]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* HelpFormatter#addArgument(action) -> Void
|
||||
* - action (object): action
|
||||
*
|
||||
* Add argument into current section
|
||||
*
|
||||
* Single variant of [[HelpFormatter#addArguments]]
|
||||
**/
|
||||
HelpFormatter.prototype.addArgument = function (action) {
|
||||
if (action.help !== c.SUPPRESS) {
|
||||
var self = this;
|
||||
|
||||
// find all invocations
|
||||
var invocations = [ this._formatActionInvocation(action) ];
|
||||
var invocationLength = invocations[0].length;
|
||||
|
||||
var actionLength;
|
||||
|
||||
if (action._getSubactions) {
|
||||
this._indent();
|
||||
action._getSubactions().forEach(function (subaction) {
|
||||
|
||||
var invocationNew = self._formatActionInvocation(subaction);
|
||||
invocations.push(invocationNew);
|
||||
invocationLength = Math.max(invocationLength, invocationNew.length);
|
||||
|
||||
});
|
||||
this._dedent();
|
||||
}
|
||||
|
||||
// update the maximum item length
|
||||
actionLength = invocationLength + this._currentIndent;
|
||||
this._actionMaxLength = Math.max(this._actionMaxLength, actionLength);
|
||||
|
||||
// add the item to the list
|
||||
this._addItem(this._formatAction, [ action ]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* HelpFormatter#addArguments(actions) -> Void
|
||||
* - actions (array): actions list
|
||||
*
|
||||
* Mass add arguments into current section
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.startSection(actionGroup.title);
|
||||
* formatter.addText(actionGroup.description);
|
||||
* formatter.addArguments(actionGroup._groupActions);
|
||||
* formatter.endSection();
|
||||
*
|
||||
**/
|
||||
HelpFormatter.prototype.addArguments = function (actions) {
|
||||
var self = this;
|
||||
actions.forEach(function (action) {
|
||||
self.addArgument(action);
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Help-formatting methods
|
||||
//
|
||||
|
||||
/**
|
||||
* HelpFormatter#formatHelp -> string
|
||||
*
|
||||
* Format help
|
||||
*
|
||||
* ##### Example
|
||||
*
|
||||
* formatter.addText(this.epilog);
|
||||
* return formatter.formatHelp();
|
||||
*
|
||||
**/
|
||||
HelpFormatter.prototype.formatHelp = function () {
|
||||
var help = this._rootSection.formatHelp(this);
|
||||
if (help) {
|
||||
help = help.replace(this._longBreakMatcher, c.EOL + c.EOL);
|
||||
help = $$.trimChars(help, c.EOL) + c.EOL;
|
||||
}
|
||||
return help;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._joinParts = function (partStrings) {
|
||||
return partStrings.filter(function (part) {
|
||||
return (part && part !== c.SUPPRESS);
|
||||
}).join('');
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatUsage = function (usage, actions, groups, prefix) {
|
||||
if (!prefix && typeof prefix !== 'string') {
|
||||
prefix = 'usage: ';
|
||||
}
|
||||
|
||||
actions = actions || [];
|
||||
groups = groups || [];
|
||||
|
||||
|
||||
// if usage is specified, use that
|
||||
if (usage) {
|
||||
usage = sprintf(usage, { prog: this._prog });
|
||||
|
||||
// if no optionals or positionals are available, usage is just prog
|
||||
} else if (!usage && actions.length === 0) {
|
||||
usage = this._prog;
|
||||
|
||||
// if optionals and positionals are available, calculate usage
|
||||
} else if (!usage) {
|
||||
var prog = this._prog;
|
||||
var optionals = [];
|
||||
var positionals = [];
|
||||
var actionUsage;
|
||||
var textWidth;
|
||||
|
||||
// split optionals from positionals
|
||||
actions.forEach(function (action) {
|
||||
if (action.isOptional()) {
|
||||
optionals.push(action);
|
||||
} else {
|
||||
positionals.push(action);
|
||||
}
|
||||
});
|
||||
|
||||
// build full usage string
|
||||
actionUsage = this._formatActionsUsage([].concat(optionals, positionals), groups);
|
||||
usage = [ prog, actionUsage ].join(' ');
|
||||
|
||||
// wrap the usage parts if it's too long
|
||||
textWidth = this._width - this._currentIndent;
|
||||
if ((prefix.length + usage.length) > textWidth) {
|
||||
|
||||
// break usage into wrappable parts
|
||||
var regexpPart = new RegExp('\\(.*?\\)+|\\[.*?\\]+|\\S+', 'g');
|
||||
var optionalUsage = this._formatActionsUsage(optionals, groups);
|
||||
var positionalUsage = this._formatActionsUsage(positionals, groups);
|
||||
|
||||
|
||||
var optionalParts = optionalUsage.match(regexpPart);
|
||||
var positionalParts = positionalUsage.match(regexpPart) || [];
|
||||
|
||||
if (optionalParts.join(' ') !== optionalUsage) {
|
||||
throw new Error('assert "optionalParts.join(\' \') === optionalUsage"');
|
||||
}
|
||||
if (positionalParts.join(' ') !== positionalUsage) {
|
||||
throw new Error('assert "positionalParts.join(\' \') === positionalUsage"');
|
||||
}
|
||||
|
||||
// helper for wrapping lines
|
||||
/*eslint-disable func-style*/ // node 0.10 compat
|
||||
var _getLines = function (parts, indent, prefix) {
|
||||
var lines = [];
|
||||
var line = [];
|
||||
|
||||
var lineLength = prefix ? prefix.length - 1 : indent.length - 1;
|
||||
|
||||
parts.forEach(function (part) {
|
||||
if (lineLength + 1 + part.length > textWidth) {
|
||||
lines.push(indent + line.join(' '));
|
||||
line = [];
|
||||
lineLength = indent.length - 1;
|
||||
}
|
||||
line.push(part);
|
||||
lineLength += part.length + 1;
|
||||
});
|
||||
|
||||
if (line) {
|
||||
lines.push(indent + line.join(' '));
|
||||
}
|
||||
if (prefix) {
|
||||
lines[0] = lines[0].substr(indent.length);
|
||||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
var lines, indent, parts;
|
||||
// if prog is short, follow it with optionals or positionals
|
||||
if (prefix.length + prog.length <= 0.75 * textWidth) {
|
||||
indent = $$.repeat(' ', (prefix.length + prog.length + 1));
|
||||
if (optionalParts) {
|
||||
lines = [].concat(
|
||||
_getLines([ prog ].concat(optionalParts), indent, prefix),
|
||||
_getLines(positionalParts, indent)
|
||||
);
|
||||
} else if (positionalParts) {
|
||||
lines = _getLines([ prog ].concat(positionalParts), indent, prefix);
|
||||
} else {
|
||||
lines = [ prog ];
|
||||
}
|
||||
|
||||
// if prog is long, put it on its own line
|
||||
} else {
|
||||
indent = $$.repeat(' ', prefix.length);
|
||||
parts = optionalParts + positionalParts;
|
||||
lines = _getLines(parts, indent);
|
||||
if (lines.length > 1) {
|
||||
lines = [].concat(
|
||||
_getLines(optionalParts, indent),
|
||||
_getLines(positionalParts, indent)
|
||||
);
|
||||
}
|
||||
lines = [ prog ] + lines;
|
||||
}
|
||||
// join lines into usage
|
||||
usage = lines.join(c.EOL);
|
||||
}
|
||||
}
|
||||
|
||||
// prefix with 'usage:'
|
||||
return prefix + usage + c.EOL + c.EOL;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatActionsUsage = function (actions, groups) {
|
||||
// find group indices and identify actions in groups
|
||||
var groupActions = [];
|
||||
var inserts = [];
|
||||
var self = this;
|
||||
|
||||
groups.forEach(function (group) {
|
||||
var end;
|
||||
var i;
|
||||
|
||||
var start = actions.indexOf(group._groupActions[0]);
|
||||
if (start >= 0) {
|
||||
end = start + group._groupActions.length;
|
||||
|
||||
//if (actions.slice(start, end) === group._groupActions) {
|
||||
if ($$.arrayEqual(actions.slice(start, end), group._groupActions)) {
|
||||
group._groupActions.forEach(function (action) {
|
||||
groupActions.push(action);
|
||||
});
|
||||
|
||||
if (!group.required) {
|
||||
if (inserts[start]) {
|
||||
inserts[start] += ' [';
|
||||
} else {
|
||||
inserts[start] = '[';
|
||||
}
|
||||
inserts[end] = ']';
|
||||
} else {
|
||||
if (inserts[start]) {
|
||||
inserts[start] += ' (';
|
||||
} else {
|
||||
inserts[start] = '(';
|
||||
}
|
||||
inserts[end] = ')';
|
||||
}
|
||||
for (i = start + 1; i < end; i += 1) {
|
||||
inserts[i] = '|';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// collect all actions format strings
|
||||
var parts = [];
|
||||
|
||||
actions.forEach(function (action, actionIndex) {
|
||||
var part;
|
||||
var optionString;
|
||||
var argsDefault;
|
||||
var argsString;
|
||||
|
||||
// suppressed arguments are marked with None
|
||||
// remove | separators for suppressed arguments
|
||||
if (action.help === c.SUPPRESS) {
|
||||
parts.push(null);
|
||||
if (inserts[actionIndex] === '|') {
|
||||
inserts.splice(actionIndex, actionIndex);
|
||||
} else if (inserts[actionIndex + 1] === '|') {
|
||||
inserts.splice(actionIndex + 1, actionIndex + 1);
|
||||
}
|
||||
|
||||
// produce all arg strings
|
||||
} else if (!action.isOptional()) {
|
||||
part = self._formatArgs(action, action.dest);
|
||||
|
||||
// if it's in a group, strip the outer []
|
||||
if (groupActions.indexOf(action) >= 0) {
|
||||
if (part[0] === '[' && part[part.length - 1] === ']') {
|
||||
part = part.slice(1, -1);
|
||||
}
|
||||
}
|
||||
// add the action string to the list
|
||||
parts.push(part);
|
||||
|
||||
// produce the first way to invoke the option in brackets
|
||||
} else {
|
||||
optionString = action.optionStrings[0];
|
||||
|
||||
// if the Optional doesn't take a value, format is: -s or --long
|
||||
if (action.nargs === 0) {
|
||||
part = '' + optionString;
|
||||
|
||||
// if the Optional takes a value, format is: -s ARGS or --long ARGS
|
||||
} else {
|
||||
argsDefault = action.dest.toUpperCase();
|
||||
argsString = self._formatArgs(action, argsDefault);
|
||||
part = optionString + ' ' + argsString;
|
||||
}
|
||||
// make it look optional if it's not required or in a group
|
||||
if (!action.required && groupActions.indexOf(action) < 0) {
|
||||
part = '[' + part + ']';
|
||||
}
|
||||
// add the action string to the list
|
||||
parts.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
// insert things at the necessary indices
|
||||
for (var i = inserts.length - 1; i >= 0; --i) {
|
||||
if (inserts[i] !== null) {
|
||||
parts.splice(i, 0, inserts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// join all the action items with spaces
|
||||
var text = parts.filter(function (part) {
|
||||
return !!part;
|
||||
}).join(' ');
|
||||
|
||||
// clean up separators for mutually exclusive groups
|
||||
text = text.replace(/([\[(]) /g, '$1'); // remove spaces
|
||||
text = text.replace(/ ([\])])/g, '$1');
|
||||
text = text.replace(/\[ *\]/g, ''); // remove empty groups
|
||||
text = text.replace(/\( *\)/g, '');
|
||||
text = text.replace(/\(([^|]*)\)/g, '$1'); // remove () from single action groups
|
||||
|
||||
text = text.trim();
|
||||
|
||||
// return the text
|
||||
return text;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatText = function (text) {
|
||||
text = sprintf(text, { prog: this._prog });
|
||||
var textWidth = this._width - this._currentIndent;
|
||||
var indentIncriment = $$.repeat(' ', this._currentIndent);
|
||||
return this._fillText(text, textWidth, indentIncriment) + c.EOL + c.EOL;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatAction = function (action) {
|
||||
var self = this;
|
||||
|
||||
var helpText;
|
||||
var helpLines;
|
||||
var parts;
|
||||
var indentFirst;
|
||||
|
||||
// determine the required width and the entry label
|
||||
var helpPosition = Math.min(this._actionMaxLength + 2, this._maxHelpPosition);
|
||||
var helpWidth = this._width - helpPosition;
|
||||
var actionWidth = helpPosition - this._currentIndent - 2;
|
||||
var actionHeader = this._formatActionInvocation(action);
|
||||
|
||||
// no help; start on same line and add a final newline
|
||||
if (!action.help) {
|
||||
actionHeader = $$.repeat(' ', this._currentIndent) + actionHeader + c.EOL;
|
||||
|
||||
// short action name; start on the same line and pad two spaces
|
||||
} else if (actionHeader.length <= actionWidth) {
|
||||
actionHeader = $$.repeat(' ', this._currentIndent) +
|
||||
actionHeader +
|
||||
' ' +
|
||||
$$.repeat(' ', actionWidth - actionHeader.length);
|
||||
indentFirst = 0;
|
||||
|
||||
// long action name; start on the next line
|
||||
} else {
|
||||
actionHeader = $$.repeat(' ', this._currentIndent) + actionHeader + c.EOL;
|
||||
indentFirst = helpPosition;
|
||||
}
|
||||
|
||||
// collect the pieces of the action help
|
||||
parts = [ actionHeader ];
|
||||
|
||||
// if there was help for the action, add lines of help text
|
||||
if (action.help) {
|
||||
helpText = this._expandHelp(action);
|
||||
helpLines = this._splitLines(helpText, helpWidth);
|
||||
parts.push($$.repeat(' ', indentFirst) + helpLines[0] + c.EOL);
|
||||
helpLines.slice(1).forEach(function (line) {
|
||||
parts.push($$.repeat(' ', helpPosition) + line + c.EOL);
|
||||
});
|
||||
|
||||
// or add a newline if the description doesn't end with one
|
||||
} else if (actionHeader.charAt(actionHeader.length - 1) !== c.EOL) {
|
||||
parts.push(c.EOL);
|
||||
}
|
||||
// if there are any sub-actions, add their help as well
|
||||
if (action._getSubactions) {
|
||||
this._indent();
|
||||
action._getSubactions().forEach(function (subaction) {
|
||||
parts.push(self._formatAction(subaction));
|
||||
});
|
||||
this._dedent();
|
||||
}
|
||||
// return a single string
|
||||
return this._joinParts(parts);
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatActionInvocation = function (action) {
|
||||
if (!action.isOptional()) {
|
||||
var format_func = this._metavarFormatter(action, action.dest);
|
||||
var metavars = format_func(1);
|
||||
return metavars[0];
|
||||
}
|
||||
|
||||
var parts = [];
|
||||
var argsDefault;
|
||||
var argsString;
|
||||
|
||||
// if the Optional doesn't take a value, format is: -s, --long
|
||||
if (action.nargs === 0) {
|
||||
parts = parts.concat(action.optionStrings);
|
||||
|
||||
// if the Optional takes a value, format is: -s ARGS, --long ARGS
|
||||
} else {
|
||||
argsDefault = action.dest.toUpperCase();
|
||||
argsString = this._formatArgs(action, argsDefault);
|
||||
action.optionStrings.forEach(function (optionString) {
|
||||
parts.push(optionString + ' ' + argsString);
|
||||
});
|
||||
}
|
||||
return parts.join(', ');
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._metavarFormatter = function (action, metavarDefault) {
|
||||
var result;
|
||||
|
||||
if (action.metavar || action.metavar === '') {
|
||||
result = action.metavar;
|
||||
} else if (action.choices) {
|
||||
var choices = action.choices;
|
||||
|
||||
if (typeof choices === 'string') {
|
||||
choices = choices.split('').join(', ');
|
||||
} else if (Array.isArray(choices)) {
|
||||
choices = choices.join(',');
|
||||
} else {
|
||||
choices = Object.keys(choices).join(',');
|
||||
}
|
||||
result = '{' + choices + '}';
|
||||
} else {
|
||||
result = metavarDefault;
|
||||
}
|
||||
|
||||
return function (size) {
|
||||
if (Array.isArray(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var metavars = [];
|
||||
for (var i = 0; i < size; i += 1) {
|
||||
metavars.push(result);
|
||||
}
|
||||
return metavars;
|
||||
};
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._formatArgs = function (action, metavarDefault) {
|
||||
var result;
|
||||
var metavars;
|
||||
|
||||
var buildMetavar = this._metavarFormatter(action, metavarDefault);
|
||||
|
||||
switch (action.nargs) {
|
||||
/*eslint-disable no-undefined*/
|
||||
case undefined:
|
||||
case null:
|
||||
metavars = buildMetavar(1);
|
||||
result = '' + metavars[0];
|
||||
break;
|
||||
case c.OPTIONAL:
|
||||
metavars = buildMetavar(1);
|
||||
result = '[' + metavars[0] + ']';
|
||||
break;
|
||||
case c.ZERO_OR_MORE:
|
||||
metavars = buildMetavar(2);
|
||||
result = '[' + metavars[0] + ' [' + metavars[1] + ' ...]]';
|
||||
break;
|
||||
case c.ONE_OR_MORE:
|
||||
metavars = buildMetavar(2);
|
||||
result = '' + metavars[0] + ' [' + metavars[1] + ' ...]';
|
||||
break;
|
||||
case c.REMAINDER:
|
||||
result = '...';
|
||||
break;
|
||||
case c.PARSER:
|
||||
metavars = buildMetavar(1);
|
||||
result = metavars[0] + ' ...';
|
||||
break;
|
||||
default:
|
||||
metavars = buildMetavar(action.nargs);
|
||||
result = metavars.join(' ');
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._expandHelp = function (action) {
|
||||
var params = { prog: this._prog };
|
||||
|
||||
Object.keys(action).forEach(function (actionProperty) {
|
||||
var actionValue = action[actionProperty];
|
||||
|
||||
if (actionValue !== c.SUPPRESS) {
|
||||
params[actionProperty] = actionValue;
|
||||
}
|
||||
});
|
||||
|
||||
if (params.choices) {
|
||||
if (typeof params.choices === 'string') {
|
||||
params.choices = params.choices.split('').join(', ');
|
||||
} else if (Array.isArray(params.choices)) {
|
||||
params.choices = params.choices.join(', ');
|
||||
} else {
|
||||
params.choices = Object.keys(params.choices).join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf(this._getHelpString(action), params);
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._splitLines = function (text, width) {
|
||||
var lines = [];
|
||||
var delimiters = [ ' ', '.', ',', '!', '?' ];
|
||||
var re = new RegExp('[' + delimiters.join('') + '][^' + delimiters.join('') + ']*$');
|
||||
|
||||
text = text.replace(/[\n\|\t]/g, ' ');
|
||||
|
||||
text = text.trim();
|
||||
text = text.replace(this._whitespaceMatcher, ' ');
|
||||
|
||||
// Wraps the single paragraph in text (a string) so every line
|
||||
// is at most width characters long.
|
||||
text.split(c.EOL).forEach(function (line) {
|
||||
if (width >= line.length) {
|
||||
lines.push(line);
|
||||
return;
|
||||
}
|
||||
|
||||
var wrapStart = 0;
|
||||
var wrapEnd = width;
|
||||
var delimiterIndex = 0;
|
||||
while (wrapEnd <= line.length) {
|
||||
if (wrapEnd !== line.length && delimiters.indexOf(line[wrapEnd] < -1)) {
|
||||
delimiterIndex = (re.exec(line.substring(wrapStart, wrapEnd)) || {}).index;
|
||||
wrapEnd = wrapStart + delimiterIndex + 1;
|
||||
}
|
||||
lines.push(line.substring(wrapStart, wrapEnd));
|
||||
wrapStart = wrapEnd;
|
||||
wrapEnd += width;
|
||||
}
|
||||
if (wrapStart < line.length) {
|
||||
lines.push(line.substring(wrapStart, wrapEnd));
|
||||
}
|
||||
});
|
||||
|
||||
return lines;
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._fillText = function (text, width, indent) {
|
||||
var lines = this._splitLines(text, width);
|
||||
lines = lines.map(function (line) {
|
||||
return indent + line;
|
||||
});
|
||||
return lines.join(c.EOL);
|
||||
};
|
||||
|
||||
HelpFormatter.prototype._getHelpString = function (action) {
|
||||
return action.help;
|
||||
};
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* class Namespace
|
||||
*
|
||||
* Simple object for storing attributes. Implements equality by attribute names
|
||||
* and values, and provides a simple string representation.
|
||||
*
|
||||
* See also [original guide][1]
|
||||
*
|
||||
* [1]:http://docs.python.org/dev/library/argparse.html#the-namespace-object
|
||||
**/
|
||||
'use strict';
|
||||
|
||||
var $$ = require('./utils');
|
||||
|
||||
/**
|
||||
* new Namespace(options)
|
||||
* - options(object): predefined propertis for result object
|
||||
*
|
||||
**/
|
||||
var Namespace = module.exports = function Namespace(options) {
|
||||
$$.extend(this, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Namespace#isset(key) -> Boolean
|
||||
* - key (string|number): property name
|
||||
*
|
||||
* Tells whenever `namespace` contains given `key` or not.
|
||||
**/
|
||||
Namespace.prototype.isset = function (key) {
|
||||
return $$.has(this, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Namespace#set(key, value) -> self
|
||||
* -key (string|number|object): propery name
|
||||
* -value (mixed): new property value
|
||||
*
|
||||
* Set the property named key with value.
|
||||
* If key object then set all key properties to namespace object
|
||||
**/
|
||||
Namespace.prototype.set = function (key, value) {
|
||||
if (typeof (key) === 'object') {
|
||||
$$.extend(this, key);
|
||||
} else {
|
||||
this[key] = value;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Namespace#get(key, defaultValue) -> mixed
|
||||
* - key (string|number): property name
|
||||
* - defaultValue (mixed): default value
|
||||
*
|
||||
* Return the property key or defaulValue if not set
|
||||
**/
|
||||
Namespace.prototype.get = function (key, defaultValue) {
|
||||
return !this[key] ? defaultValue : this[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Namespace#unset(key, defaultValue) -> mixed
|
||||
* - key (string|number): property name
|
||||
* - defaultValue (mixed): default value
|
||||
*
|
||||
* Return data[key](and delete it) or defaultValue
|
||||
**/
|
||||
Namespace.prototype.unset = function (key, defaultValue) {
|
||||
var value = this[key];
|
||||
if (value !== null) {
|
||||
delete this[key];
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
exports.repeat = function (str, num) {
|
||||
var result = '';
|
||||
for (var i = 0; i < num; i++) { result += str; }
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.arrayEqual = function (a, b) {
|
||||
if (a.length !== b.length) { return false; }
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) { return false; }
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.trimChars = function (str, chars) {
|
||||
var start = 0;
|
||||
var end = str.length - 1;
|
||||
while (chars.indexOf(str.charAt(start)) >= 0) { start++; }
|
||||
while (chars.indexOf(str.charAt(end)) >= 0) { end--; }
|
||||
return str.slice(start, end + 1);
|
||||
};
|
||||
|
||||
exports.capitalize = function (str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
};
|
||||
|
||||
exports.arrayUnion = function () {
|
||||
var result = [];
|
||||
for (var i = 0, values = {}; i < arguments.length; i++) {
|
||||
var arr = arguments[i];
|
||||
for (var j = 0; j < arr.length; j++) {
|
||||
if (!values[arr[j]]) {
|
||||
values[arr[j]] = true;
|
||||
result.push(arr[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
function has(obj, key) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
exports.has = has;
|
||||
|
||||
exports.extend = function (dest, src) {
|
||||
for (var i in src) {
|
||||
if (has(src, i)) { dest[i] = src[i]; }
|
||||
}
|
||||
};
|
||||
|
||||
exports.trimEnd = function (str) {
|
||||
return str.replace(/\s+$/g, '');
|
||||
};
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"argparse@^1.0.7",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/js-yaml"
|
||||
]
|
||||
],
|
||||
"_from": "argparse@>=1.0.7 <2.0.0",
|
||||
"_id": "argparse@1.0.9",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/argparse",
|
||||
"_nodeVersion": "6.5.0",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "packages-12-west.internal.npmjs.com",
|
||||
"tmp": "tmp/argparse-1.0.9.tgz_1475177461025_0.33920647646300495"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "vitaly@rcdesign.ru",
|
||||
"name": "vitaly"
|
||||
},
|
||||
"_npmVersion": "3.10.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "argparse",
|
||||
"raw": "argparse@^1.0.7",
|
||||
"rawSpec": "^1.0.7",
|
||||
"scope": null,
|
||||
"spec": ">=1.0.7 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/js-yaml"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
|
||||
"_shasum": "73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "argparse@^1.0.7",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/js-yaml",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nodeca/argparse/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Eugene Shkuropat"
|
||||
},
|
||||
{
|
||||
"name": "Paul Jacobson"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
},
|
||||
"description": "Very powerful CLI arguments parser. Native port of argparse - python's options parsing library",
|
||||
"devDependencies": {
|
||||
"eslint": "^2.13.1",
|
||||
"istanbul": "^0.4.5",
|
||||
"mocha": "^3.1.0",
|
||||
"ndoc": "^5.0.1"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86",
|
||||
"tarball": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib/"
|
||||
],
|
||||
"gitHead": "acb39f2d726b90d2eadf9e6574a938d6250ad248",
|
||||
"homepage": "https://github.com/nodeca/argparse#readme",
|
||||
"keywords": [
|
||||
"argparse",
|
||||
"args",
|
||||
"cli",
|
||||
"option",
|
||||
"parser"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "vitaly",
|
||||
"email": "vitaly@rcdesign.ru"
|
||||
}
|
||||
],
|
||||
"name": "argparse",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nodeca/argparse.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"version": "1.0.9"
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
# Array Flatten
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![NPM downloads][downloads-image]][downloads-url]
|
||||
[![Build status][travis-image]][travis-url]
|
||||
[![Test coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install array-flatten --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var flatten = require('array-flatten')
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
|
||||
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
|
||||
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
|
||||
|
||||
(function () {
|
||||
flatten(arguments) //=> [1, 2, 3]
|
||||
})(1, [2, 3])
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
|
||||
[npm-url]: https://npmjs.org/package/array-flatten
|
||||
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
|
||||
[downloads-url]: https://npmjs.org/package/array-flatten
|
||||
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
|
||||
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
|
||||
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
|
||||
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Expose `arrayFlatten`.
|
||||
*/
|
||||
module.exports = arrayFlatten
|
||||
|
||||
/**
|
||||
* Recursive flatten function with depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenWithDepth (array, result, depth) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (depth > 0 && Array.isArray(value)) {
|
||||
flattenWithDepth(value, result, depth - 1)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive flatten function. Omitting depth is slightly faster.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenForever (array, result) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
flattenForever(value, result)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array, with the ability to define a depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function arrayFlatten (array, depth) {
|
||||
if (depth == null) {
|
||||
return flattenForever(array, [])
|
||||
}
|
||||
|
||||
return flattenWithDepth(array, [], depth)
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"array-flatten@1.1.1",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/express"
|
||||
]
|
||||
],
|
||||
"_from": "array-flatten@1.1.1",
|
||||
"_id": "array-flatten@1.1.1",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/array-flatten",
|
||||
"_nodeVersion": "2.3.3",
|
||||
"_npmUser": {
|
||||
"email": "hello@blakeembrey.com",
|
||||
"name": "blakeembrey"
|
||||
},
|
||||
"_npmVersion": "2.11.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "array-flatten",
|
||||
"raw": "array-flatten@1.1.1",
|
||||
"rawSpec": "1.1.1",
|
||||
"scope": null,
|
||||
"spec": "1.1.1",
|
||||
"type": "version"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/express"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"_shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "array-flatten@1.1.1",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/express",
|
||||
"author": {
|
||||
"email": "hello@blakeembrey.com",
|
||||
"name": "Blake Embrey",
|
||||
"url": "http://blakeembrey.me"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/blakeembrey/array-flatten/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"description": "Flatten an array of nested arrays into a single flat array",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.3.13",
|
||||
"mocha": "^2.2.4",
|
||||
"pre-commit": "^1.0.7",
|
||||
"standard": "^3.7.3"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "9a5f699051b1e7073328f2a008968b64ea2955d2",
|
||||
"tarball": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"array-flatten.js"
|
||||
],
|
||||
"gitHead": "1963a9189229d408e1e8f585a00c8be9edbd1803",
|
||||
"homepage": "https://github.com/blakeembrey/array-flatten",
|
||||
"keywords": [
|
||||
"arguments",
|
||||
"array",
|
||||
"depth",
|
||||
"flatten"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "array-flatten.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "blakeembrey",
|
||||
"email": "hello@blakeembrey.com"
|
||||
}
|
||||
],
|
||||
"name": "array-flatten",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blakeembrey/array-flatten.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "istanbul cover _mocha -- -R spec"
|
||||
},
|
||||
"version": "1.1.1"
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
*.log
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.8
|
||||
- 0.10
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011 Mark Cavage, All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
node-asn1 is a library for encoding and decoding ASN.1 datatypes in pure JS.
|
||||
Currently BER encoding is supported; at some point I'll likely have to do DER.
|
||||
|
||||
## Usage
|
||||
|
||||
Mostly, if you're *actually* needing to read and write ASN.1, you probably don't
|
||||
need this readme to explain what and why. If you have no idea what ASN.1 is,
|
||||
see this: ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc
|
||||
|
||||
The source is pretty much self-explanatory, and has read/write methods for the
|
||||
common types out there.
|
||||
|
||||
### Decoding
|
||||
|
||||
The following reads an ASN.1 sequence with a boolean.
|
||||
|
||||
var Ber = require('asn1').Ber;
|
||||
|
||||
var reader = new Ber.Reader(new Buffer([0x30, 0x03, 0x01, 0x01, 0xff]));
|
||||
|
||||
reader.readSequence();
|
||||
console.log('Sequence len: ' + reader.length);
|
||||
if (reader.peek() === Ber.Boolean)
|
||||
console.log(reader.readBoolean());
|
||||
|
||||
### Encoding
|
||||
|
||||
The following generates the same payload as above.
|
||||
|
||||
var Ber = require('asn1').Ber;
|
||||
|
||||
var writer = new Ber.Writer();
|
||||
|
||||
writer.startSequence();
|
||||
writer.writeBoolean(true);
|
||||
writer.endSequence();
|
||||
|
||||
console.log(writer.buffer);
|
||||
|
||||
## Installation
|
||||
|
||||
npm install asn1
|
||||
|
||||
## License
|
||||
|
||||
MIT.
|
||||
|
||||
## Bugs
|
||||
|
||||
See <https://github.com/mcavage/node-asn1/issues>.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
|
||||
module.exports = {
|
||||
|
||||
newInvalidAsn1Error: function(msg) {
|
||||
var e = new Error();
|
||||
e.name = 'InvalidAsn1Error';
|
||||
e.message = msg || '';
|
||||
return e;
|
||||
}
|
||||
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var errors = require('./errors');
|
||||
var types = require('./types');
|
||||
|
||||
var Reader = require('./reader');
|
||||
var Writer = require('./writer');
|
||||
|
||||
|
||||
///--- Exports
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reader: Reader,
|
||||
|
||||
Writer: Writer
|
||||
|
||||
};
|
||||
|
||||
for (var t in types) {
|
||||
if (types.hasOwnProperty(t))
|
||||
module.exports[t] = types[t];
|
||||
}
|
||||
for (var e in errors) {
|
||||
if (errors.hasOwnProperty(e))
|
||||
module.exports[e] = errors[e];
|
||||
}
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
var ASN1 = require('./types');
|
||||
var errors = require('./errors');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
var newInvalidAsn1Error = errors.newInvalidAsn1Error;
|
||||
|
||||
|
||||
|
||||
///--- API
|
||||
|
||||
function Reader(data) {
|
||||
if (!data || !Buffer.isBuffer(data))
|
||||
throw new TypeError('data must be a node Buffer');
|
||||
|
||||
this._buf = data;
|
||||
this._size = data.length;
|
||||
|
||||
// These hold the "current" state
|
||||
this._len = 0;
|
||||
this._offset = 0;
|
||||
}
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'length', {
|
||||
enumerable: true,
|
||||
get: function () { return (this._len); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'offset', {
|
||||
enumerable: true,
|
||||
get: function () { return (this._offset); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'remain', {
|
||||
get: function () { return (this._size - this._offset); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'buffer', {
|
||||
get: function () { return (this._buf.slice(this._offset)); }
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Reads a single byte and advances offset; you can pass in `true` to make this
|
||||
* a "peek" operation (i.e., get the byte, but don't advance the offset).
|
||||
*
|
||||
* @param {Boolean} peek true means don't move offset.
|
||||
* @return {Number} the next byte, null if not enough data.
|
||||
*/
|
||||
Reader.prototype.readByte = function(peek) {
|
||||
if (this._size - this._offset < 1)
|
||||
return null;
|
||||
|
||||
var b = this._buf[this._offset] & 0xff;
|
||||
|
||||
if (!peek)
|
||||
this._offset += 1;
|
||||
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.peek = function() {
|
||||
return this.readByte(true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a (potentially) variable length off the BER buffer. This call is
|
||||
* not really meant to be called directly, as callers have to manipulate
|
||||
* the internal buffer afterwards.
|
||||
*
|
||||
* As a result of this call, you can call `Reader.length`, until the
|
||||
* next thing called that does a readLength.
|
||||
*
|
||||
* @return {Number} the amount of offset to advance the buffer.
|
||||
* @throws {InvalidAsn1Error} on bad ASN.1
|
||||
*/
|
||||
Reader.prototype.readLength = function(offset) {
|
||||
if (offset === undefined)
|
||||
offset = this._offset;
|
||||
|
||||
if (offset >= this._size)
|
||||
return null;
|
||||
|
||||
var lenB = this._buf[offset++] & 0xff;
|
||||
if (lenB === null)
|
||||
return null;
|
||||
|
||||
if ((lenB & 0x80) == 0x80) {
|
||||
lenB &= 0x7f;
|
||||
|
||||
if (lenB == 0)
|
||||
throw newInvalidAsn1Error('Indefinite length not supported');
|
||||
|
||||
if (lenB > 4)
|
||||
throw newInvalidAsn1Error('encoding too long');
|
||||
|
||||
if (this._size - offset < lenB)
|
||||
return null;
|
||||
|
||||
this._len = 0;
|
||||
for (var i = 0; i < lenB; i++)
|
||||
this._len = (this._len << 8) + (this._buf[offset++] & 0xff);
|
||||
|
||||
} else {
|
||||
// Wasn't a variable length
|
||||
this._len = lenB;
|
||||
}
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses the next sequence in this BER buffer.
|
||||
*
|
||||
* To get the length of the sequence, call `Reader.length`.
|
||||
*
|
||||
* @return {Number} the sequence's tag.
|
||||
*/
|
||||
Reader.prototype.readSequence = function(tag) {
|
||||
var seq = this.peek();
|
||||
if (seq === null)
|
||||
return null;
|
||||
if (tag !== undefined && tag !== seq)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + seq.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
this._offset = o;
|
||||
return seq;
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readInt = function() {
|
||||
return this._readTag(ASN1.Integer);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readBoolean = function() {
|
||||
return (this._readTag(ASN1.Boolean) === 0 ? false : true);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readEnumeration = function() {
|
||||
return this._readTag(ASN1.Enumeration);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readString = function(tag, retbuf) {
|
||||
if (!tag)
|
||||
tag = ASN1.OctetString;
|
||||
|
||||
var b = this.peek();
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
if (b !== tag)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + b.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
if (this.length > this._size - o)
|
||||
return null;
|
||||
|
||||
this._offset = o;
|
||||
|
||||
if (this.length === 0)
|
||||
return retbuf ? new Buffer(0) : '';
|
||||
|
||||
var str = this._buf.slice(this._offset, this._offset + this.length);
|
||||
this._offset += this.length;
|
||||
|
||||
return retbuf ? str : str.toString('utf8');
|
||||
};
|
||||
|
||||
Reader.prototype.readOID = function(tag) {
|
||||
if (!tag)
|
||||
tag = ASN1.OID;
|
||||
|
||||
var b = this.readString(tag, true);
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
var values = [];
|
||||
var value = 0;
|
||||
|
||||
for (var i = 0; i < b.length; i++) {
|
||||
var byte = b[i] & 0xff;
|
||||
|
||||
value <<= 7;
|
||||
value += byte & 0x7f;
|
||||
if ((byte & 0x80) == 0) {
|
||||
values.push(value);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
value = values.shift();
|
||||
values.unshift(value % 40);
|
||||
values.unshift((value / 40) >> 0);
|
||||
|
||||
return values.join('.');
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype._readTag = function(tag) {
|
||||
assert.ok(tag !== undefined);
|
||||
|
||||
var b = this.peek();
|
||||
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
if (b !== tag)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + b.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
if (this.length > 4)
|
||||
throw newInvalidAsn1Error('Integer too long: ' + this.length);
|
||||
|
||||
if (this.length > this._size - o)
|
||||
return null;
|
||||
this._offset = o;
|
||||
|
||||
var fb = this._buf[this._offset];
|
||||
var value = 0;
|
||||
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
value <<= 8;
|
||||
value |= (this._buf[this._offset++] & 0xff);
|
||||
}
|
||||
|
||||
if ((fb & 0x80) == 0x80 && i !== 4)
|
||||
value -= (1 << (i * 8));
|
||||
|
||||
return value >> 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///--- Exported API
|
||||
|
||||
module.exports = Reader;
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
|
||||
module.exports = {
|
||||
EOC: 0,
|
||||
Boolean: 1,
|
||||
Integer: 2,
|
||||
BitString: 3,
|
||||
OctetString: 4,
|
||||
Null: 5,
|
||||
OID: 6,
|
||||
ObjectDescriptor: 7,
|
||||
External: 8,
|
||||
Real: 9, // float
|
||||
Enumeration: 10,
|
||||
PDV: 11,
|
||||
Utf8String: 12,
|
||||
RelativeOID: 13,
|
||||
Sequence: 16,
|
||||
Set: 17,
|
||||
NumericString: 18,
|
||||
PrintableString: 19,
|
||||
T61String: 20,
|
||||
VideotexString: 21,
|
||||
IA5String: 22,
|
||||
UTCTime: 23,
|
||||
GeneralizedTime: 24,
|
||||
GraphicString: 25,
|
||||
VisibleString: 26,
|
||||
GeneralString: 28,
|
||||
UniversalString: 29,
|
||||
CharacterString: 30,
|
||||
BMPString: 31,
|
||||
Constructor: 32,
|
||||
Context: 128
|
||||
};
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var assert = require('assert');
|
||||
var ASN1 = require('./types');
|
||||
var errors = require('./errors');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
var newInvalidAsn1Error = errors.newInvalidAsn1Error;
|
||||
|
||||
var DEFAULT_OPTS = {
|
||||
size: 1024,
|
||||
growthFactor: 8
|
||||
};
|
||||
|
||||
|
||||
///--- Helpers
|
||||
|
||||
function merge(from, to) {
|
||||
assert.ok(from);
|
||||
assert.equal(typeof(from), 'object');
|
||||
assert.ok(to);
|
||||
assert.equal(typeof(to), 'object');
|
||||
|
||||
var keys = Object.getOwnPropertyNames(from);
|
||||
keys.forEach(function(key) {
|
||||
if (to[key])
|
||||
return;
|
||||
|
||||
var value = Object.getOwnPropertyDescriptor(from, key);
|
||||
Object.defineProperty(to, key, value);
|
||||
});
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///--- API
|
||||
|
||||
function Writer(options) {
|
||||
options = merge(DEFAULT_OPTS, options || {});
|
||||
|
||||
this._buf = new Buffer(options.size || 1024);
|
||||
this._size = this._buf.length;
|
||||
this._offset = 0;
|
||||
this._options = options;
|
||||
|
||||
// A list of offsets in the buffer where we need to insert
|
||||
// sequence tag/len pairs.
|
||||
this._seq = [];
|
||||
}
|
||||
|
||||
Object.defineProperty(Writer.prototype, 'buffer', {
|
||||
get: function () {
|
||||
if (this._seq.length)
|
||||
throw new InvalidAsn1Error(this._seq.length + ' unended sequence(s)');
|
||||
|
||||
return (this._buf.slice(0, this._offset));
|
||||
}
|
||||
});
|
||||
|
||||
Writer.prototype.writeByte = function(b) {
|
||||
if (typeof(b) !== 'number')
|
||||
throw new TypeError('argument must be a Number');
|
||||
|
||||
this._ensure(1);
|
||||
this._buf[this._offset++] = b;
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeInt = function(i, tag) {
|
||||
if (typeof(i) !== 'number')
|
||||
throw new TypeError('argument must be a Number');
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.Integer;
|
||||
|
||||
var sz = 4;
|
||||
|
||||
while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) &&
|
||||
(sz > 1)) {
|
||||
sz--;
|
||||
i <<= 8;
|
||||
}
|
||||
|
||||
if (sz > 4)
|
||||
throw new InvalidAsn1Error('BER ints cannot be > 0xffffffff');
|
||||
|
||||
this._ensure(2 + sz);
|
||||
this._buf[this._offset++] = tag;
|
||||
this._buf[this._offset++] = sz;
|
||||
|
||||
while (sz-- > 0) {
|
||||
this._buf[this._offset++] = ((i & 0xff000000) >>> 24);
|
||||
i <<= 8;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeNull = function() {
|
||||
this.writeByte(ASN1.Null);
|
||||
this.writeByte(0x00);
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeEnumeration = function(i, tag) {
|
||||
if (typeof(i) !== 'number')
|
||||
throw new TypeError('argument must be a Number');
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.Enumeration;
|
||||
|
||||
return this.writeInt(i, tag);
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeBoolean = function(b, tag) {
|
||||
if (typeof(b) !== 'boolean')
|
||||
throw new TypeError('argument must be a Boolean');
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.Boolean;
|
||||
|
||||
this._ensure(3);
|
||||
this._buf[this._offset++] = tag;
|
||||
this._buf[this._offset++] = 0x01;
|
||||
this._buf[this._offset++] = b ? 0xff : 0x00;
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeString = function(s, tag) {
|
||||
if (typeof(s) !== 'string')
|
||||
throw new TypeError('argument must be a string (was: ' + typeof(s) + ')');
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.OctetString;
|
||||
|
||||
var len = Buffer.byteLength(s);
|
||||
this.writeByte(tag);
|
||||
this.writeLength(len);
|
||||
if (len) {
|
||||
this._ensure(len);
|
||||
this._buf.write(s, this._offset);
|
||||
this._offset += len;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeBuffer = function(buf, tag) {
|
||||
if (typeof(tag) !== 'number')
|
||||
throw new TypeError('tag must be a number');
|
||||
if (!Buffer.isBuffer(buf))
|
||||
throw new TypeError('argument must be a buffer');
|
||||
|
||||
this.writeByte(tag);
|
||||
this.writeLength(buf.length);
|
||||
this._ensure(buf.length);
|
||||
buf.copy(this._buf, this._offset, 0, buf.length);
|
||||
this._offset += buf.length;
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeStringArray = function(strings) {
|
||||
if ((!strings instanceof Array))
|
||||
throw new TypeError('argument must be an Array[String]');
|
||||
|
||||
var self = this;
|
||||
strings.forEach(function(s) {
|
||||
self.writeString(s);
|
||||
});
|
||||
};
|
||||
|
||||
// This is really to solve DER cases, but whatever for now
|
||||
Writer.prototype.writeOID = function(s, tag) {
|
||||
if (typeof(s) !== 'string')
|
||||
throw new TypeError('argument must be a string');
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.OID;
|
||||
|
||||
if (!/^([0-9]+\.){3,}[0-9]+$/.test(s))
|
||||
throw new Error('argument is not a valid OID string');
|
||||
|
||||
function encodeOctet(bytes, octet) {
|
||||
if (octet < 128) {
|
||||
bytes.push(octet);
|
||||
} else if (octet < 16384) {
|
||||
bytes.push((octet >>> 7) | 0x80);
|
||||
bytes.push(octet & 0x7F);
|
||||
} else if (octet < 2097152) {
|
||||
bytes.push((octet >>> 14) | 0x80);
|
||||
bytes.push(((octet >>> 7) | 0x80) & 0xFF);
|
||||
bytes.push(octet & 0x7F);
|
||||
} else if (octet < 268435456) {
|
||||
bytes.push((octet >>> 21) | 0x80);
|
||||
bytes.push(((octet >>> 14) | 0x80) & 0xFF);
|
||||
bytes.push(((octet >>> 7) | 0x80) & 0xFF);
|
||||
bytes.push(octet & 0x7F);
|
||||
} else {
|
||||
bytes.push(((octet >>> 28) | 0x80) & 0xFF);
|
||||
bytes.push(((octet >>> 21) | 0x80) & 0xFF);
|
||||
bytes.push(((octet >>> 14) | 0x80) & 0xFF);
|
||||
bytes.push(((octet >>> 7) | 0x80) & 0xFF);
|
||||
bytes.push(octet & 0x7F);
|
||||
}
|
||||
}
|
||||
|
||||
var tmp = s.split('.');
|
||||
var bytes = [];
|
||||
bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10));
|
||||
tmp.slice(2).forEach(function(b) {
|
||||
encodeOctet(bytes, parseInt(b, 10));
|
||||
});
|
||||
|
||||
var self = this;
|
||||
this._ensure(2 + bytes.length);
|
||||
this.writeByte(tag);
|
||||
this.writeLength(bytes.length);
|
||||
bytes.forEach(function(b) {
|
||||
self.writeByte(b);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.writeLength = function(len) {
|
||||
if (typeof(len) !== 'number')
|
||||
throw new TypeError('argument must be a Number');
|
||||
|
||||
this._ensure(4);
|
||||
|
||||
if (len <= 0x7f) {
|
||||
this._buf[this._offset++] = len;
|
||||
} else if (len <= 0xff) {
|
||||
this._buf[this._offset++] = 0x81;
|
||||
this._buf[this._offset++] = len;
|
||||
} else if (len <= 0xffff) {
|
||||
this._buf[this._offset++] = 0x82;
|
||||
this._buf[this._offset++] = len >> 8;
|
||||
this._buf[this._offset++] = len;
|
||||
} else if (len <= 0xffffff) {
|
||||
this._buf[this._offset++] = 0x83;
|
||||
this._buf[this._offset++] = len >> 16;
|
||||
this._buf[this._offset++] = len >> 8;
|
||||
this._buf[this._offset++] = len;
|
||||
} else {
|
||||
throw new InvalidAsn1ERror('Length too long (> 4 bytes)');
|
||||
}
|
||||
};
|
||||
|
||||
Writer.prototype.startSequence = function(tag) {
|
||||
if (typeof(tag) !== 'number')
|
||||
tag = ASN1.Sequence | ASN1.Constructor;
|
||||
|
||||
this.writeByte(tag);
|
||||
this._seq.push(this._offset);
|
||||
this._ensure(3);
|
||||
this._offset += 3;
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype.endSequence = function() {
|
||||
var seq = this._seq.pop();
|
||||
var start = seq + 3;
|
||||
var len = this._offset - start;
|
||||
|
||||
if (len <= 0x7f) {
|
||||
this._shift(start, len, -2);
|
||||
this._buf[seq] = len;
|
||||
} else if (len <= 0xff) {
|
||||
this._shift(start, len, -1);
|
||||
this._buf[seq] = 0x81;
|
||||
this._buf[seq + 1] = len;
|
||||
} else if (len <= 0xffff) {
|
||||
this._buf[seq] = 0x82;
|
||||
this._buf[seq + 1] = len >> 8;
|
||||
this._buf[seq + 2] = len;
|
||||
} else if (len <= 0xffffff) {
|
||||
this._shift(start, len, 1);
|
||||
this._buf[seq] = 0x83;
|
||||
this._buf[seq + 1] = len >> 16;
|
||||
this._buf[seq + 2] = len >> 8;
|
||||
this._buf[seq + 3] = len;
|
||||
} else {
|
||||
throw new InvalidAsn1Error('Sequence too long');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Writer.prototype._shift = function(start, len, shift) {
|
||||
assert.ok(start !== undefined);
|
||||
assert.ok(len !== undefined);
|
||||
assert.ok(shift);
|
||||
|
||||
this._buf.copy(this._buf, start + shift, start, start + len);
|
||||
this._offset += shift;
|
||||
};
|
||||
|
||||
Writer.prototype._ensure = function(len) {
|
||||
assert.ok(len);
|
||||
|
||||
if (this._size - this._offset < len) {
|
||||
var sz = this._size * this._options.growthFactor;
|
||||
if (sz - this._offset < len)
|
||||
sz += len;
|
||||
|
||||
var buf = new Buffer(sz);
|
||||
|
||||
this._buf.copy(buf, 0, 0, this._offset);
|
||||
this._buf = buf;
|
||||
this._size = sz;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
///--- Exported API
|
||||
|
||||
module.exports = Writer;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
// If you have no idea what ASN.1 or BER is, see this:
|
||||
// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc
|
||||
|
||||
var Ber = require('./ber/index');
|
||||
|
||||
|
||||
|
||||
///--- Exported API
|
||||
|
||||
module.exports = {
|
||||
|
||||
Ber: Ber,
|
||||
|
||||
BerReader: Ber.Reader,
|
||||
|
||||
BerWriter: Ber.Writer
|
||||
|
||||
};
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"asn1@~0.2.3",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/sshpk"
|
||||
]
|
||||
],
|
||||
"_from": "asn1@>=0.2.3 <0.3.0",
|
||||
"_id": "asn1@0.2.3",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/asn1",
|
||||
"_npmUser": {
|
||||
"email": "patrick.f.mooney@gmail.com",
|
||||
"name": "pfmooney"
|
||||
},
|
||||
"_npmVersion": "1.4.28",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "asn1",
|
||||
"raw": "asn1@~0.2.3",
|
||||
"rawSpec": "~0.2.3",
|
||||
"scope": null,
|
||||
"spec": ">=0.2.3 <0.3.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/sshpk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
|
||||
"_shasum": "dac8787713c9966849fc8180777ebe9c1ddf3b86",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "asn1@~0.2.3",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/sshpk",
|
||||
"author": {
|
||||
"email": "mcavage@gmail.com",
|
||||
"name": "Mark Cavage"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mcavage/node-asn1/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "David Gwynne",
|
||||
"email": "loki@animata.net"
|
||||
},
|
||||
{
|
||||
"name": "Yunong Xiao",
|
||||
"email": "yunong@joyent.com"
|
||||
},
|
||||
{
|
||||
"name": "Alex Wilson",
|
||||
"email": "alex.wilson@joyent.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "Contains parsers and serializers for ASN.1 (currently BER only)",
|
||||
"devDependencies": {
|
||||
"tap": "0.4.8"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "dac8787713c9966849fc8180777ebe9c1ddf3b86",
|
||||
"tarball": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz"
|
||||
},
|
||||
"homepage": "https://github.com/mcavage/node-asn1",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "mcavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "pfmooney",
|
||||
"email": "patrick.f.mooney@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "asn1",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mcavage/node-asn1.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap ./tst"
|
||||
},
|
||||
"version": "0.2.3"
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var test = require('tap').test;
|
||||
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
var BerReader;
|
||||
|
||||
|
||||
|
||||
///--- Tests
|
||||
|
||||
test('load library', function(t) {
|
||||
BerReader = require('../../lib/index').BerReader;
|
||||
t.ok(BerReader);
|
||||
try {
|
||||
new BerReader();
|
||||
t.fail('Should have thrown');
|
||||
} catch (e) {
|
||||
t.ok(e instanceof TypeError, 'Should have been a type error');
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read byte', function(t) {
|
||||
var reader = new BerReader(new Buffer([0xde]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readByte(), 0xde, 'wrong value');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 1 byte int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x01, 0x03]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), 0x03, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 2 byte int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x02, 0x7e, 0xde]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), 0x7ede, 'wrong value');
|
||||
t.equal(reader.length, 0x02, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 3 byte int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x03, 0x7e, 0xde, 0x03]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), 0x7ede03, 'wrong value');
|
||||
t.equal(reader.length, 0x03, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 4 byte int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x04, 0x7e, 0xde, 0x03, 0x01]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), 0x7ede0301, 'wrong value');
|
||||
t.equal(reader.length, 0x04, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 1 byte negative int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x01, 0xdc]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), -36, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 2 byte negative int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x02, 0xc0, 0x4e]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), -16306, 'wrong value');
|
||||
t.equal(reader.length, 0x02, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 3 byte negative int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x03, 0xff, 0x00, 0x19]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), -65511, 'wrong value');
|
||||
t.equal(reader.length, 0x03, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read 4 byte negative int', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readInt(), -1854135777, 'wrong value');
|
||||
t.equal(reader.length, 0x04, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read boolean true', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x01, 0x01, 0xff]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readBoolean(), true, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read boolean false', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x01, 0x01, 0x00]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readBoolean(), false, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read enumeration', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x0a, 0x01, 0x20]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readEnumeration(), 0x20, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read string', function(t) {
|
||||
var dn = 'cn=foo,ou=unit,o=test';
|
||||
var buf = new Buffer(dn.length + 2);
|
||||
buf[0] = 0x04;
|
||||
buf[1] = Buffer.byteLength(dn);
|
||||
buf.write(dn, 2);
|
||||
var reader = new BerReader(buf);
|
||||
t.ok(reader);
|
||||
t.equal(reader.readString(), dn, 'wrong value');
|
||||
t.equal(reader.length, dn.length, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('read sequence', function(t) {
|
||||
var reader = new BerReader(new Buffer([0x30, 0x03, 0x01, 0x01, 0xff]));
|
||||
t.ok(reader);
|
||||
t.equal(reader.readSequence(), 0x30, 'wrong value');
|
||||
t.equal(reader.length, 0x03, 'wrong length');
|
||||
t.equal(reader.readBoolean(), true, 'wrong value');
|
||||
t.equal(reader.length, 0x01, 'wrong length');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('anonymous LDAPv3 bind', function(t) {
|
||||
var BIND = new Buffer(14);
|
||||
BIND[0] = 0x30; // Sequence
|
||||
BIND[1] = 12; // len
|
||||
BIND[2] = 0x02; // ASN.1 Integer
|
||||
BIND[3] = 1; // len
|
||||
BIND[4] = 0x04; // msgid (make up 4)
|
||||
BIND[5] = 0x60; // Bind Request
|
||||
BIND[6] = 7; // len
|
||||
BIND[7] = 0x02; // ASN.1 Integer
|
||||
BIND[8] = 1; // len
|
||||
BIND[9] = 0x03; // v3
|
||||
BIND[10] = 0x04; // String (bind dn)
|
||||
BIND[11] = 0; // len
|
||||
BIND[12] = 0x80; // ContextSpecific (choice)
|
||||
BIND[13] = 0; // simple bind
|
||||
|
||||
// Start testing ^^
|
||||
var ber = new BerReader(BIND);
|
||||
t.equal(ber.readSequence(), 48, 'Not an ASN.1 Sequence');
|
||||
t.equal(ber.length, 12, 'Message length should be 12');
|
||||
t.equal(ber.readInt(), 4, 'Message id should have been 4');
|
||||
t.equal(ber.readSequence(), 96, 'Bind Request should have been 96');
|
||||
t.equal(ber.length, 7, 'Bind length should have been 7');
|
||||
t.equal(ber.readInt(), 3, 'LDAP version should have been 3');
|
||||
t.equal(ber.readString(), '', 'Bind DN should have been empty');
|
||||
t.equal(ber.length, 0, 'string length should have been 0');
|
||||
t.equal(ber.readByte(), 0x80, 'Should have been ContextSpecific (choice)');
|
||||
t.equal(ber.readByte(), 0, 'Should have been simple bind');
|
||||
t.equal(null, ber.readByte(), 'Should be out of data');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('long string', function(t) {
|
||||
var buf = new Buffer(256);
|
||||
var o;
|
||||
var s =
|
||||
'2;649;CN=Red Hat CS 71GA Demo,O=Red Hat CS 71GA Demo,C=US;' +
|
||||
'CN=RHCS Agent - admin01,UID=admin01,O=redhat,C=US [1] This is ' +
|
||||
'Teena Vradmin\'s description.';
|
||||
buf[0] = 0x04;
|
||||
buf[1] = 0x81;
|
||||
buf[2] = 0x94;
|
||||
buf.write(s, 3);
|
||||
var ber = new BerReader(buf.slice(0, 3 + s.length));
|
||||
t.equal(ber.readString(), s);
|
||||
t.end();
|
||||
});
|
||||
+370
@@ -0,0 +1,370 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var test = require('tap').test;
|
||||
var sys = require('sys');
|
||||
|
||||
///--- Globals
|
||||
|
||||
var BerWriter;
|
||||
|
||||
var BerReader;
|
||||
|
||||
|
||||
///--- Tests
|
||||
|
||||
test('load library', function(t) {
|
||||
BerWriter = require('../../lib/index').BerWriter;
|
||||
t.ok(BerWriter);
|
||||
t.ok(new BerWriter());
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write byte', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeByte(0xC2);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 1, 'Wrong length');
|
||||
t.equal(ber[0], 0xC2, 'value wrong');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 1 byte int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(0x7f);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 3, 'Wrong length for an int: ' + ber.length);
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong (2) -> ' + ber[0]);
|
||||
t.equal(ber[1], 0x01, 'length wrong(1) -> ' + ber[1]);
|
||||
t.equal(ber[2], 0x7f, 'value wrong(3) -> ' + ber[2]);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 2 byte int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(0x7ffe);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 4, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x02, 'length wrong');
|
||||
t.equal(ber[2], 0x7f, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0xfe, 'value wrong (byte 2)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 3 byte int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(0x7ffffe);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 5, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x03, 'length wrong');
|
||||
t.equal(ber[2], 0x7f, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0xff, 'value wrong (byte 2)');
|
||||
t.equal(ber[4], 0xfe, 'value wrong (byte 3)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 4 byte int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(0x7ffffffe);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 6, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x04, 'length wrong');
|
||||
t.equal(ber[2], 0x7f, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0xff, 'value wrong (byte 2)');
|
||||
t.equal(ber[4], 0xff, 'value wrong (byte 3)');
|
||||
t.equal(ber[5], 0xfe, 'value wrong (byte 4)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 1 byte negative int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(-128);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 3, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x01, 'length wrong');
|
||||
t.equal(ber[2], 0x80, 'value wrong (byte 1)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 2 byte negative int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(-22400);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 4, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x02, 'length wrong');
|
||||
t.equal(ber[2], 0xa8, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0x80, 'value wrong (byte 2)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 3 byte negative int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(-481653);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 5, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x03, 'length wrong');
|
||||
t.equal(ber[2], 0xf8, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0xa6, 'value wrong (byte 2)');
|
||||
t.equal(ber[4], 0x8b, 'value wrong (byte 3)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write 4 byte negative int', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeInt(-1522904131);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 6, 'Wrong length for an int');
|
||||
t.equal(ber[0], 0x02, 'ASN.1 tag wrong');
|
||||
t.equal(ber[1], 0x04, 'length wrong');
|
||||
t.equal(ber[2], 0xa5, 'value wrong (byte 1)');
|
||||
t.equal(ber[3], 0x3a, 'value wrong (byte 2)');
|
||||
t.equal(ber[4], 0x53, 'value wrong (byte 3)');
|
||||
t.equal(ber[5], 0xbd, 'value wrong (byte 4)');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write boolean', function(t) {
|
||||
var writer = new BerWriter();
|
||||
|
||||
writer.writeBoolean(true);
|
||||
writer.writeBoolean(false);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 6, 'Wrong length');
|
||||
t.equal(ber[0], 0x01, 'tag wrong');
|
||||
t.equal(ber[1], 0x01, 'length wrong');
|
||||
t.equal(ber[2], 0xff, 'value wrong');
|
||||
t.equal(ber[3], 0x01, 'tag wrong');
|
||||
t.equal(ber[4], 0x01, 'length wrong');
|
||||
t.equal(ber[5], 0x00, 'value wrong');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('write string', function(t) {
|
||||
var writer = new BerWriter();
|
||||
writer.writeString('hello world');
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 13, 'wrong length');
|
||||
t.equal(ber[0], 0x04, 'wrong tag');
|
||||
t.equal(ber[1], 11, 'wrong length');
|
||||
t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('write buffer', function(t) {
|
||||
var writer = new BerWriter();
|
||||
// write some stuff to start with
|
||||
writer.writeString('hello world');
|
||||
var ber = writer.buffer;
|
||||
var buf = new Buffer([0x04, 0x0b, 0x30, 0x09, 0x02, 0x01, 0x0f, 0x01, 0x01,
|
||||
0xff, 0x01, 0x01, 0xff]);
|
||||
writer.writeBuffer(buf.slice(2, buf.length), 0x04);
|
||||
ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 26, 'wrong length');
|
||||
t.equal(ber[0], 0x04, 'wrong tag');
|
||||
t.equal(ber[1], 11, 'wrong length');
|
||||
t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value');
|
||||
t.equal(ber[13], buf[0], 'wrong tag');
|
||||
t.equal(ber[14], buf[1], 'wrong length');
|
||||
for (var i = 13, j = 0; i < ber.length && j < buf.length; i++, j++) {
|
||||
t.equal(ber[i], buf[j], 'buffer contents not identical');
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('write string array', function(t) {
|
||||
var writer = new BerWriter();
|
||||
writer.writeStringArray(['hello world', 'fubar!']);
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
|
||||
t.equal(ber.length, 21, 'wrong length');
|
||||
t.equal(ber[0], 0x04, 'wrong tag');
|
||||
t.equal(ber[1], 11, 'wrong length');
|
||||
t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value');
|
||||
|
||||
t.equal(ber[13], 0x04, 'wrong tag');
|
||||
t.equal(ber[14], 6, 'wrong length');
|
||||
t.equal(ber.slice(15).toString('utf8'), 'fubar!', 'wrong value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('resize internal buffer', function(t) {
|
||||
var writer = new BerWriter({size: 2});
|
||||
writer.writeString('hello world');
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 13, 'wrong length');
|
||||
t.equal(ber[0], 0x04, 'wrong tag');
|
||||
t.equal(ber[1], 11, 'wrong length');
|
||||
t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('sequence', function(t) {
|
||||
var writer = new BerWriter({size: 25});
|
||||
writer.startSequence();
|
||||
writer.writeString('hello world');
|
||||
writer.endSequence();
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
console.log(ber);
|
||||
t.equal(ber.length, 15, 'wrong length');
|
||||
t.equal(ber[0], 0x30, 'wrong tag');
|
||||
t.equal(ber[1], 13, 'wrong length');
|
||||
t.equal(ber[2], 0x04, 'wrong tag');
|
||||
t.equal(ber[3], 11, 'wrong length');
|
||||
t.equal(ber.slice(4).toString('utf8'), 'hello world', 'wrong value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('nested sequence', function(t) {
|
||||
var writer = new BerWriter({size: 25});
|
||||
writer.startSequence();
|
||||
writer.writeString('hello world');
|
||||
writer.startSequence();
|
||||
writer.writeString('hello world');
|
||||
writer.endSequence();
|
||||
writer.endSequence();
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 30, 'wrong length');
|
||||
t.equal(ber[0], 0x30, 'wrong tag');
|
||||
t.equal(ber[1], 28, 'wrong length');
|
||||
t.equal(ber[2], 0x04, 'wrong tag');
|
||||
t.equal(ber[3], 11, 'wrong length');
|
||||
t.equal(ber.slice(4, 15).toString('utf8'), 'hello world', 'wrong value');
|
||||
t.equal(ber[15], 0x30, 'wrong tag');
|
||||
t.equal(ber[16], 13, 'wrong length');
|
||||
t.equal(ber[17], 0x04, 'wrong tag');
|
||||
t.equal(ber[18], 11, 'wrong length');
|
||||
t.equal(ber.slice(19, 30).toString('utf8'), 'hello world', 'wrong value');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('LDAP bind message', function(t) {
|
||||
var dn = 'cn=foo,ou=unit,o=test';
|
||||
var writer = new BerWriter();
|
||||
writer.startSequence();
|
||||
writer.writeInt(3); // msgid = 3
|
||||
writer.startSequence(0x60); // ldap bind
|
||||
writer.writeInt(3); // ldap v3
|
||||
writer.writeString(dn);
|
||||
writer.writeByte(0x80);
|
||||
writer.writeByte(0x00);
|
||||
writer.endSequence();
|
||||
writer.endSequence();
|
||||
var ber = writer.buffer;
|
||||
|
||||
t.ok(ber);
|
||||
t.equal(ber.length, 35, 'wrong length (buffer)');
|
||||
t.equal(ber[0], 0x30, 'wrong tag');
|
||||
t.equal(ber[1], 33, 'wrong length');
|
||||
t.equal(ber[2], 0x02, 'wrong tag');
|
||||
t.equal(ber[3], 1, 'wrong length');
|
||||
t.equal(ber[4], 0x03, 'wrong value');
|
||||
t.equal(ber[5], 0x60, 'wrong tag');
|
||||
t.equal(ber[6], 28, 'wrong length');
|
||||
t.equal(ber[7], 0x02, 'wrong tag');
|
||||
t.equal(ber[8], 1, 'wrong length');
|
||||
t.equal(ber[9], 0x03, 'wrong value');
|
||||
t.equal(ber[10], 0x04, 'wrong tag');
|
||||
t.equal(ber[11], dn.length, 'wrong length');
|
||||
t.equal(ber.slice(12, 33).toString('utf8'), dn, 'wrong value');
|
||||
t.equal(ber[33], 0x80, 'wrong tag');
|
||||
t.equal(ber[34], 0x00, 'wrong len');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('Write OID', function(t) {
|
||||
var oid = '1.2.840.113549.1.1.1';
|
||||
var writer = new BerWriter();
|
||||
writer.writeOID(oid);
|
||||
|
||||
var ber = writer.buffer;
|
||||
t.ok(ber);
|
||||
console.log(require('util').inspect(ber));
|
||||
console.log(require('util').inspect(new Buffer([0x06, 0x09, 0x2a, 0x86,
|
||||
0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x01, 0x01])));
|
||||
|
||||
t.end();
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
Dave Eddy <dave@daveeddy.com>
|
||||
Fred Kuo <fred.kuo@joyent.com>
|
||||
Lars-Magnus Skog <ralphtheninja@riseup.net>
|
||||
Mark Cavage <mcavage@gmail.com>
|
||||
Patrick Mooney <pmooney@pfmooney.com>
|
||||
Rob Gulewich <robert.gulewich@joyent.com>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
# assert-plus Changelog
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Fix `assert.object(null)` so it throws
|
||||
- Fix optional/arrayOf exports for non-type-of asserts
|
||||
- Add optiona/arrayOf exports for Stream/Date/Regex/uuid
|
||||
- Add basic unit test coverage
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
# assert-plus
|
||||
|
||||
This library is a super small wrapper over node's assert module that has two
|
||||
things: (1) the ability to disable assertions with the environment variable
|
||||
NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like
|
||||
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
|
||||
like this:
|
||||
|
||||
```javascript
|
||||
var assert = require('assert-plus');
|
||||
|
||||
function fooAccount(options, callback) {
|
||||
assert.object(options, 'options');
|
||||
assert.number(options.id, 'options.id');
|
||||
assert.bool(options.isManager, 'options.isManager');
|
||||
assert.string(options.name, 'options.name');
|
||||
assert.arrayOfString(options.email, 'options.email');
|
||||
assert.func(callback, 'callback');
|
||||
|
||||
// Do stuff
|
||||
callback(null, {});
|
||||
}
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
All methods that *aren't* part of node's core assert API are simply assumed to
|
||||
take an argument, and then a string 'name' that's not a message; `AssertionError`
|
||||
will be thrown if the assertion fails with a message like:
|
||||
|
||||
AssertionError: foo (string) is required
|
||||
at test (/home/mark/work/foo/foo.js:3:9)
|
||||
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
|
||||
at Module._compile (module.js:446:26)
|
||||
at Object..js (module.js:464:10)
|
||||
at Module.load (module.js:353:31)
|
||||
at Function._load (module.js:311:12)
|
||||
at Array.0 (module.js:484:10)
|
||||
at EventEmitter._tickCallback (node.js:190:38)
|
||||
|
||||
from:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.string(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`:
|
||||
|
||||
```javascript
|
||||
function test(foo) {
|
||||
assert.arrayOfString(foo, 'foo');
|
||||
}
|
||||
```
|
||||
|
||||
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
|
||||
|
||||
```javascript
|
||||
assert.optionalString(foo, 'foo');
|
||||
```
|
||||
|
||||
Lastly, you can opt-out of assertion checking altogether by setting the
|
||||
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
|
||||
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
|
||||
production. Be advised: The standard functions re-exported from `assert` are
|
||||
also disabled in assert-plus if NDEBUG is specified. Using them directly from
|
||||
the `assert` module avoids this behavior.
|
||||
|
||||
The complete list of APIs is:
|
||||
|
||||
* assert.array
|
||||
* assert.bool
|
||||
* assert.buffer
|
||||
* assert.func
|
||||
* assert.number
|
||||
* assert.object
|
||||
* assert.string
|
||||
* assert.stream
|
||||
* assert.date
|
||||
* assert.regex
|
||||
* assert.uuid
|
||||
* assert.arrayOfArray
|
||||
* assert.arrayOfBool
|
||||
* assert.arrayOfBuffer
|
||||
* assert.arrayOfFunc
|
||||
* assert.arrayOfNumber
|
||||
* assert.arrayOfObject
|
||||
* assert.arrayOfString
|
||||
* assert.arrayOfStream
|
||||
* assert.arrayOfDate
|
||||
* assert.arrayOfUuid
|
||||
* assert.optionalArray
|
||||
* assert.optionalBool
|
||||
* assert.optionalBuffer
|
||||
* assert.optionalFunc
|
||||
* assert.optionalNumber
|
||||
* assert.optionalObject
|
||||
* assert.optionalString
|
||||
* assert.optionalStream
|
||||
* assert.optionalDate
|
||||
* assert.optionalUuid
|
||||
* assert.optionalArrayOfArray
|
||||
* assert.optionalArrayOfBool
|
||||
* assert.optionalArrayOfBuffer
|
||||
* assert.optionalArrayOfFunc
|
||||
* assert.optionalArrayOfNumber
|
||||
* assert.optionalArrayOfObject
|
||||
* assert.optionalArrayOfString
|
||||
* assert.optionalArrayOfStream
|
||||
* assert.optionalArrayOfDate
|
||||
* assert.optionalArrayOfUuid
|
||||
* assert.AssertionError
|
||||
* assert.fail
|
||||
* assert.ok
|
||||
* assert.equal
|
||||
* assert.notEqual
|
||||
* assert.deepEqual
|
||||
* assert.notDeepEqual
|
||||
* assert.strictEqual
|
||||
* assert.notStrictEqual
|
||||
* assert.throws
|
||||
* assert.doesNotThrow
|
||||
* assert.ifError
|
||||
|
||||
# Installation
|
||||
|
||||
npm install assert-plus
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2012 Mark Cavage
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
## Bugs
|
||||
|
||||
See <https://github.com/mcavage/node-assert-plus/issues>.
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) 2012, Mark Cavage. All rights reserved.
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
var assert = require('assert');
|
||||
var Stream = require('stream').Stream;
|
||||
var util = require('util');
|
||||
|
||||
|
||||
///--- Globals
|
||||
|
||||
/* JSSTYLED */
|
||||
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
|
||||
|
||||
|
||||
///--- Internal
|
||||
|
||||
function _capitalize(str) {
|
||||
return (str.charAt(0).toUpperCase() + str.slice(1));
|
||||
}
|
||||
|
||||
function _toss(name, expected, oper, arg, actual) {
|
||||
throw new assert.AssertionError({
|
||||
message: util.format('%s (%s) is required', name, expected),
|
||||
actual: (actual === undefined) ? typeof (arg) : actual(arg),
|
||||
expected: expected,
|
||||
operator: oper || '===',
|
||||
stackStartFunction: _toss.caller
|
||||
});
|
||||
}
|
||||
|
||||
function _getClass(arg) {
|
||||
return (Object.prototype.toString.call(arg).slice(8, -1));
|
||||
}
|
||||
|
||||
function noop() {
|
||||
// Why even bother with asserts?
|
||||
}
|
||||
|
||||
|
||||
///--- Exports
|
||||
|
||||
var types = {
|
||||
bool: {
|
||||
check: function (arg) { return typeof (arg) === 'boolean'; }
|
||||
},
|
||||
func: {
|
||||
check: function (arg) { return typeof (arg) === 'function'; }
|
||||
},
|
||||
string: {
|
||||
check: function (arg) { return typeof (arg) === 'string'; }
|
||||
},
|
||||
object: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'object' && arg !== null;
|
||||
}
|
||||
},
|
||||
number: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg);
|
||||
}
|
||||
},
|
||||
buffer: {
|
||||
check: function (arg) { return Buffer.isBuffer(arg); },
|
||||
operator: 'Buffer.isBuffer'
|
||||
},
|
||||
array: {
|
||||
check: function (arg) { return Array.isArray(arg); },
|
||||
operator: 'Array.isArray'
|
||||
},
|
||||
stream: {
|
||||
check: function (arg) { return arg instanceof Stream; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
date: {
|
||||
check: function (arg) { return arg instanceof Date; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
regexp: {
|
||||
check: function (arg) { return arg instanceof RegExp; },
|
||||
operator: 'instanceof',
|
||||
actual: _getClass
|
||||
},
|
||||
uuid: {
|
||||
check: function (arg) {
|
||||
return typeof (arg) === 'string' && UUID_REGEXP.test(arg);
|
||||
},
|
||||
operator: 'isUUID'
|
||||
}
|
||||
};
|
||||
|
||||
function _setExports(ndebug) {
|
||||
var keys = Object.keys(types);
|
||||
var out;
|
||||
|
||||
/* re-export standard assert */
|
||||
if (process.env.NODE_NDEBUG) {
|
||||
out = noop;
|
||||
} else {
|
||||
out = function (arg, msg) {
|
||||
if (!arg) {
|
||||
_toss(msg, 'true', arg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* standard checks */
|
||||
keys.forEach(function (k) {
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[k] = function (arg, msg) {
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optional checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optional' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!type.check(arg)) {
|
||||
_toss(msg, k, type.operator, arg, type.actual);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* arrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'arrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* optionalArrayOf checks */
|
||||
keys.forEach(function (k) {
|
||||
var name = 'optionalArrayOf' + _capitalize(k);
|
||||
if (ndebug) {
|
||||
out[name] = noop;
|
||||
return;
|
||||
}
|
||||
var type = types[k];
|
||||
var expected = '[' + k + ']';
|
||||
out[name] = function (arg, msg) {
|
||||
if (arg === undefined || arg === null) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(arg)) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
var i;
|
||||
for (i = 0; i < arg.length; i++) {
|
||||
if (!type.check(arg[i])) {
|
||||
_toss(msg, expected, type.operator, arg, type.actual);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
/* re-export built-in assertions */
|
||||
Object.keys(assert).forEach(function (k) {
|
||||
if (k === 'AssertionError') {
|
||||
out[k] = assert[k];
|
||||
return;
|
||||
}
|
||||
if (ndebug) {
|
||||
out[k] = noop;
|
||||
return;
|
||||
}
|
||||
out[k] = assert[k];
|
||||
});
|
||||
|
||||
/* export ourselves (for unit tests _only_) */
|
||||
out._setExports = _setExports;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
module.exports = _setExports(process.env.NODE_NDEBUG);
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"assert-plus@^0.2.0",
|
||||
"/home/xor/shared_vm/git/node-sunwell/node_modules/http-signature"
|
||||
]
|
||||
],
|
||||
"_from": "assert-plus@>=0.2.0 <0.3.0",
|
||||
"_id": "assert-plus@0.2.0",
|
||||
"_inCache": true,
|
||||
"_installable": true,
|
||||
"_location": "/assert-plus",
|
||||
"_nodeVersion": "0.10.36",
|
||||
"_npmUser": {
|
||||
"email": "patrick.f.mooney@gmail.com",
|
||||
"name": "pfmooney"
|
||||
},
|
||||
"_npmVersion": "3.3.8",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "assert-plus",
|
||||
"raw": "assert-plus@^0.2.0",
|
||||
"rawSpec": "^0.2.0",
|
||||
"scope": null,
|
||||
"spec": ">=0.2.0 <0.3.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/http-signature"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
|
||||
"_shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "assert-plus@^0.2.0",
|
||||
"_where": "/home/xor/shared_vm/git/node-sunwell/node_modules/http-signature",
|
||||
"author": {
|
||||
"email": "mcavage@gmail.com",
|
||||
"name": "Mark Cavage"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mcavage/node-assert-plus/issues"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Dave Eddy",
|
||||
"email": "dave@daveeddy.com"
|
||||
},
|
||||
{
|
||||
"name": "Fred Kuo",
|
||||
"email": "fred.kuo@joyent.com"
|
||||
},
|
||||
{
|
||||
"name": "Lars-Magnus Skog",
|
||||
"email": "ralphtheninja@riseup.net"
|
||||
},
|
||||
{
|
||||
"name": "Mark Cavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Patrick Mooney",
|
||||
"email": "pmooney@pfmooney.com"
|
||||
},
|
||||
{
|
||||
"name": "Rob Gulewich",
|
||||
"email": "robert.gulewich@joyent.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"description": "Extra assertions on top of node's assert module",
|
||||
"devDependencies": {
|
||||
"faucet": "0.0.1",
|
||||
"tape": "4.2.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
|
||||
"tarball": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
},
|
||||
"homepage": "https://github.com/mcavage/node-assert-plus#readme",
|
||||
"license": "MIT",
|
||||
"main": "./assert.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "mcavage",
|
||||
"email": "mcavage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "pfmooney",
|
||||
"email": "patrick.f.mooney@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "assert-plus",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mcavage/node-assert-plus.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape tests/*.js | ./node_modules/.bin/faucet"
|
||||
},
|
||||
"version": "0.2.0"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
docs/
|
||||
test/
|
||||
build/
|
||||
components/
|
||||
support/
|
||||
coverage.html
|
||||
component.json
|
||||
lib-cov
|
||||
.travis.yml
|
||||
Makefile
|
||||
*.swp
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
1.0.1 / 2015-03-04
|
||||
==================
|
||||
|
||||
* Merge pull request #2 from simonzack/master
|
||||
* fixes `.stack` on firefox
|
||||
|
||||
1.0.0 / 2013-06-08
|
||||
==================
|
||||
|
||||
* readme: change travis and component urls
|
||||
* refactor: [*] prepare for move to chaijs gh org
|
||||
|
||||
0.1.0 / 2013-04-07
|
||||
==================
|
||||
|
||||
* test: use vanilla test runner/assert
|
||||
* pgk: remove unused deps
|
||||
* lib: implement
|
||||
* "Initial commit"
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# AssertionError [](https://travis-ci.org/chaijs/assertion-error)
|
||||
|
||||
> Error constructor for test and validation frameworks that implements standardized AssertionError specification.
|
||||
|
||||
## Installation
|
||||
|
||||
### Node.js
|
||||
|
||||
`assertion-error` is available on [npm](http://npmjs.org).
|
||||
|
||||
$ npm install assertion-error
|
||||
|
||||
### Component
|
||||
|
||||
`assertion-error` is available as a [component](https://github.com/component/component).
|
||||
|
||||
$ component install chaijs/assertion-error
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013 Jake Luer <jake@qualiancy.com> (http://qualiancy.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*!
|
||||
* assertion-error
|
||||
* Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Return a function that will copy properties from
|
||||
* one object to another excluding any originally
|
||||
* listed. Returned function will create a new `{}`.
|
||||
*
|
||||
* @param {String} excluded properties ...
|
||||
* @return {Function}
|
||||
*/
|
||||
|
||||
function exclude () {
|
||||
var excludes = [].slice.call(arguments);
|
||||
|
||||
function excludeProps (res, obj) {
|
||||
Object.keys(obj).forEach(function (key) {
|
||||
if (!~excludes.indexOf(key)) res[key] = obj[key];
|
||||
});
|
||||
}
|
||||
|
||||
return function extendExclude () {
|
||||
var args = [].slice.call(arguments)
|
||||
, i = 0
|
||||
, res = {};
|
||||
|
||||
for (; i < args.length; i++) {
|
||||
excludeProps(res, args[i]);
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
* Primary Exports
|
||||
*/
|
||||
|
||||
module.exports = AssertionError;
|
||||
|
||||
/**
|
||||
* ### AssertionError
|
||||
*
|
||||
* An extension of the JavaScript `Error` constructor for
|
||||
* assertion and validation scenarios.
|
||||
*
|
||||
* @param {String} message
|
||||
* @param {Object} properties to include (optional)
|
||||
* @param {callee} start stack function (optional)
|
||||
*/
|
||||
|
||||
function AssertionError (message, _props, ssf) {
|
||||
var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
|
||||
, props = extend(_props || {});
|
||||
|
||||
// default values
|
||||
this.message = message || 'Unspecified AssertionError';
|
||||
this.showDiff = false;
|
||||
|
||||
// copy from properties
|
||||
for (var key in props) {
|
||||
this[key] = props[key];
|
||||
}
|
||||
|
||||
// capture stack trace
|
||||
ssf = ssf || arguments.callee;
|
||||
if (ssf && Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, ssf);
|
||||
} else {
|
||||
try {
|
||||
throw new Error();
|
||||
} catch(e) {
|
||||
this.stack = e.stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from Error.prototype
|
||||
*/
|
||||
|
||||
AssertionError.prototype = Object.create(Error.prototype);
|
||||
|
||||
/*!
|
||||
* Statically set name
|
||||
*/
|
||||
|
||||
AssertionError.prototype.name = 'AssertionError';
|
||||
|
||||
/*!
|
||||
* Ensure correct constructor
|
||||
*/
|
||||
|
||||
AssertionError.prototype.constructor = AssertionError;
|
||||
|
||||
/**
|
||||
* Allow errors to be converted to JSON for static transfer.
|
||||
*
|
||||
* @param {Boolean} include stack (default: `true`)
|
||||
* @return {Object} object that can be `JSON.stringify`
|
||||
*/
|
||||
|
||||
AssertionError.prototype.toJSON = function (stack) {
|
||||
var extend = exclude('constructor', 'toJSON', 'stack')
|
||||
, props = extend({ name: this.name }, this);
|
||||
|
||||
// include stack if exists and not turned off
|
||||
if (false !== stack && this.stack) {
|
||||
props.stack = this.stack;
|
||||
}
|
||||
|
||||
return props;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user