Initial commit — jibo-cli v3.0.7 with bundled node_modules

This commit is contained in:
pasketti
2026-04-05 18:40:18 -04:00
commit b2569b4ce4
10488 changed files with 1631271 additions and 0 deletions

6
node_modules/skills-service-manager/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,6 @@
skills-service-manager - Skills Services Manager
@version v4.0.6
Copyright (c) 2017, Jibo, Inc. All rights reserved.
All use of the Jibo SDK is subject to the Jibo SDK End User License Agreement (EULA)
distributed herewith. If you did not receive a copy of the EULA, you may view a
copy at https://developers.jibo.com/license.

2
node_modules/skills-service-manager/README.md generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# skills-service-manager
Skills Services Manager

View File

@@ -0,0 +1,61 @@
{
"platformVersion" : ">=3.1.0",
"services": {
"KBService": {
"port": 8778
},
"SkillsService": {
"singleSkill": true,
"port": 8779
},
"MediaProxyService": {
"port": 8487
},
"ServiceManager": {
"port": 8999
},
"NotificationsService": {
"port": 8001
},
"PerformanceService": {
"port": 10003
},
"ErrorService": {
"port": 10004
},
"SchedulerService": {
"port": 10005
},
"ListenService": {
"port": 10002,
"nativeSkillMap": {
"@be/clock": "@be/be",
"@be/settings": "@be/be",
"@be/greetings": "@be/be",
"@be/chitchat": "@be/be",
"@be/main-menu": "@be/be",
"@be/friendly-tips": "@be/be",
"@be/idle": "@be/be",
"@be/who-am-i": "@be/be",
"@be/create": "@be/be",
"@be/gallery": "@be/be",
"@be/demo": "@be/be"
}
},
"WifiService": {
"port": 8668,
"region": "api"
},
"DevShell": {
"port" : 8686,
"syncPort" : 8989,
"debugPort": 9191,
"skillDest" : "/opt/jibo/Jibo/Skills",
"sdkDest" : "bin/on-robot/"
}
},
"RegistryClient": {
"port": 8181,
"host": "127.0.0.1"
}
}

View File

@@ -0,0 +1,61 @@
{
"platformVersion": ">=3.1.0",
"services": {
"KBService": {
"port": 8778
},
"SkillsService": {
"singleSkill": true,
"port": 8779
},
"MediaProxyService": {
"port": 8487
},
"ServiceManager": {
"port": 8999
},
"NotificationsService": {
"port": 8001
},
"PerformanceService": {
"port": 10003
},
"ErrorService": {
"port": 10004
},
"SchedulerService": {
"port": 10005
},
"ListenService": {
"port": 10002,
"nativeSkillMap": {
"@be/clock": "@be/be",
"@be/settings": "@be/be",
"@be/greetings": "@be/be",
"@be/chitchat": "@be/be",
"@be/main-menu": "@be/be",
"@be/friendly-tips": "@be/be",
"@be/idle": "@be/be",
"@be/who-am-i": "@be/be",
"@be/create": "@be/be",
"@be/gallery": "@be/be",
"@be/demo": "@be/be"
}
},
"WifiService": {
"port": 8668,
"region": "api"
},
"DevShell": {
"port": 8686,
"syncPort": 8989,
"debugPort": 9191,
"skillDest": "/opt/jibo/Jibo/Skills",
"sdkDest": "bin/on-robot/"
}
},
"RegistryClient": {
"port": 8181,
"host": "127.0.0.1"
}
}

View File

@@ -0,0 +1,39 @@
{
"platformVersion": ">=3.1.0",
"services": {
"KBService": {
"port": 8778
},
"SkillsService": {
"startSkill": "@be/be",
"singleSkill": true,
"port": 8779
},
"MediaProxyService": {
"port": 8487
},
"ServiceManager": {
"port": 8999
},
"NotificationsService": {
"port": 8001
},
"ErrorService": {
"port": 10004
},
"SchedulerService": {
"port": 10005
},
"ListenService": {
"port": 10002
},
"WifiService": {
"port": 8668,
"region": "api"
}
},
"RegistryClient": {
"port": 8181,
"host": "127.0.0.1"
}
}

View File

@@ -0,0 +1,39 @@
{
"platformVersion": ">=3.1.0",
"services": {
"KBService": {
"port": 8778
},
"SkillsService": {
"singleSkill": true,
"startSkill": "oobe-config",
"port": 8779
},
"MediaProxyService": {
"port": 8487
},
"ServiceManager": {
"port": 8999
},
"NotificationsService": {
"port": 8001
},
"ErrorService": {
"port": 10004
},
"SchedulerService": {
"port": 10005
},
"ListenService": {
"port": 10002
},
"WifiService": {
"port": 8668,
"region": "api"
}
},
"RegistryClient": {
"port": 8181,
"host": "127.0.0.1"
}
}

44
node_modules/skills-service-manager/index.html generated vendored Normal file
View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Skills Service Manager</title>
<link rel="stylesheet" type="text/css" href="./startup/startup.css" />
<link rel="stylesheet" type="text/css" href="node_modules/jibo/resources/fonts.css" />
</head>
<body>
<div id="view-screen" class="center mode-empty">
<div id="view-content" class="center status-loading">
<svg class="icon-loading" x="0px" y="0px" viewBox="0 0 80 80" style="enable-background:new 0 0 80 80;" xml:space="preserve">
<circle class="st0" cx="39.9" cy="9.2" r="9"/>
<circle class="st0" cx="70.7" cy="40" r="7"/>
<circle class="st0" cx="39.9" cy="70.8" r="7"/>
<circle class="st0" cx="9.1" cy="40" r="7"/>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 5.2044 48.9596)" class="st0" cx="61.7" cy="18.2" rx="7" ry="7"/>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 -25.6289 61.7312)" class="st0" cx="61.7" cy="61.8" rx="7" ry="7"/>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 -38.4005 30.8978)" class="st0" cx="18.1" cy="61.8" rx="7" ry="7"/>
<ellipse transform="matrix(0.7071 -0.7071 0.7071 0.7071 -7.5672 18.1263)" class="st0" cx="18.1" cy="18.2" rx="7" ry="7"/>
</svg>
<h1>
<svg class="icon icon-success success" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve"><g><path class="st0" d="M500,10C229.4,10,10,229.4,10,500c0,270.6,219.4,490,490,490c270.6,0,490-219.4,490-490C990,229.4,770.6,10,500,10z M394.5,740.7l-57.4-57.4l-0.4,0.4l-154-154l57.8-57.7l153.6,153.6L759.7,260l57.7,57.8L394.5,740.7z"/></g></svg>
<svg class="icon icon-error error" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve"><path class="st0" d="M500,10.3c-270.6,0-490,219.4-490,490s219.4,490,490,490s490-219.4,490-490S770.6,10.3,500,10.3z M740.3,683l-57.8,57.7L500,558.2L317.5,740.7l-57.4-57.4l-0.4,0.4l182.8-183.1L259.7,317.8l57.4-57.4l-0.4-0.4L500,443l182.7-183l57.7,57.8L557.6,500.6L740.3,683z"/></svg>
<span class="developer">Jibo</span>
<span class="int-developer">Skills Service Manager</span>
<span class="success">is Ready</span>
<span class="error">has Failed</span>
</h1>
<h2 id="view-message"></h2>
</div>
</div>
<script>
'use strict';
const createProxyServer = require('./lib/skills-service-manager').default.createProxyServer;
createProxyServer(10223, 12345);
createProxyServer(9222, 9191);
require('./startup');
</script>
</body>
</html>

2
node_modules/skills-service-manager/index.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// Include the library main file
module.exports = require('./lib/skills-service-manager').default;

1
node_modules/skills-service-manager/jibo-ssm.js generated vendored Normal file
View File

@@ -0,0 +1 @@
require('./lib/main-process');

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
/**
* skills-service-manager - Skills Services Manager
* @version v4.0.6
* @license Copyright (c) 2017, Jibo, Inc. All rights reserved.
* All use of the Jibo SDK is subject to the Jibo SDK End User License Agreement (EULA)
* distributed herewith. If you did not receive a copy of the EULA, you may view a
* copy at https://developers.jibo.com/license.
*/
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.skillsMainProcess=e()}}(function(){return function e(t,n,o){function i(r,c){if(!n[r]){if(!t[r]){var d="function"==typeof require&&require;if(!c&&d)return d(r,!0);if(s)return s(r,!0);var f=new Error("Cannot find module '"+r+"'");throw f.code="MODULE_NOT_FOUND",f}var h=n[r]={exports:{}};t[r][0].call(h.exports,function(e){var n=t[r][1][e];return i(n?n:e)},h,h.exports,e,t,n,o)}return n[r].exports}for(var s="function"==typeof require&&require,r=0;r<o.length;r++)i(o[r]);return i}({1:[function(e,t,n){"use strict";function o(e,t,n){return new c(e,t,n)}console.log("skills-main-process.ts");const i=e("electron"),s=e("../utils/Log");let r=s.createLog("ssm-skill-main-process");class c{constructor(e,t,n){this.registryHost=e,this.indexPath=t,this.context=n,this.onReady=this.onReady.bind(this),this.onInit=this.onInit.bind(this),this.onFinished=this.onFinished.bind(this),this.onGetContext=this.onGetContext.bind(this),this.onCrashed=this.onCrashed.bind(this),i.ipcMain.on("get-context",this.onGetContext),i.ipcMain.on("init-done",this.onInit),i.app.once("ready",this.onReady)}onCrashed(){r.error("Skill renderer process crashed. Restarting."),this.window.reload()}onReady(){r.info("App Ready",this.indexPath),this.window=new i.BrowserWindow({show:!1,x:0,y:0,width:c.WIDTH,height:c.HEIGHT,frame:!1}),this.window.webContents.on("crashed",this.onCrashed),this.window.loadURL("file://"+this.indexPath)}onFinished(){i.app.quit()}onInit(){this.window.show(),this.window.focus(),this.window.setPosition(0,0)}onGetContext(e){r.info("Get context called"),e.sender.send("set-context",{registryHost:this.registryHost,runMode:process.env.RUNMODE,token:"",context:this.context})}}c.WIDTH=1280,c.HEIGHT=721,Object.defineProperty(n,"__esModule",{value:!0}),n.default=o},{"../utils/Log":3,electron:void 0}],2:[function(e,t,n){"use strict";const o=e("./MainProcess");let i,s=process.argv[3],r=process.argv[4];if(6===process.argv.length)try{i=JSON.parse(process.argv[5])}catch(e){console.error("could not parse context",process.argv[5])}o.default(s,r,i)},{"./MainProcess":1}],3:[function(e,t,n){"use strict";function o(e,t){let n=new i(e);return n.toSyslog(),n}const i=e("jibo-log");n.createLog=o},{"jibo-log":void 0}]},{},[2])(2)});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
../mime/cli.js

View File

@@ -0,0 +1 @@
../mkdirp/bin/cmd.js

View File

@@ -0,0 +1 @@
../parser-download/bin/parser-download.js

View File

@@ -0,0 +1 @@
../rimraf/bin.js

View File

@@ -0,0 +1 @@
../semver/bin/semver

View File

@@ -0,0 +1,125 @@
# v1.5.2
- Allow using `"consructor"` as an argument in `memoize` (#998)
- Give a better error messsage when `auto` dependency checking fails (#994)
- Various doc updates (#936, #956, #979, #1002)
# v1.5.1
- Fix issue with `pause` in `queue` with concurrency enabled (#946)
- `while` and `until` now pass the final result to callback (#963)
- `auto` will properly handle concurrency when there is no callback (#966)
- `auto` will now properly stop execution when an error occurs (#988, #993)
- Various doc fixes (#971, #980)
# v1.5.0
- Added `transform`, analogous to [`_.transform`](http://lodash.com/docs#transform) (#892)
- `map` now returns an object when an object is passed in, rather than array with non-numeric keys. `map` will begin always returning an array with numeric indexes in the next major release. (#873)
- `auto` now accepts an optional `concurrency` argument to limit the number of running tasks (#637)
- Added `queue#workersList()`, to retrieve the list of currently running tasks. (#891)
- Various code simplifications (#896, #904)
- Various doc fixes :scroll: (#890, #894, #903, #905, #912)
# v1.4.2
- Ensure coverage files don't get published on npm (#879)
# v1.4.1
- Add in overlooked `detectLimit` method (#866)
- Removed unnecessary files from npm releases (#861)
- Removed usage of a reserved word to prevent :boom: in older environments (#870)
# v1.4.0
- `asyncify` now supports promises (#840)
- Added `Limit` versions of `filter` and `reject` (#836)
- Add `Limit` versions of `detect`, `some` and `every` (#828, #829)
- `some`, `every` and `detect` now short circuit early (#828, #829)
- Improve detection of the global object (#804), enabling use in WebWorkers
- `whilst` now called with arguments from iterator (#823)
- `during` now gets called with arguments from iterator (#824)
- Code simplifications and optimizations aplenty ([diff](https://github.com/caolan/async/compare/v1.3.0...v1.4.0))
# v1.3.0
New Features:
- Added `constant`
- Added `asyncify`/`wrapSync` for making sync functions work with callbacks. (#671, #806)
- Added `during` and `doDuring`, which are like `whilst` with an async truth test. (#800)
- `retry` now accepts an `interval` parameter to specify a delay between retries. (#793)
- `async` should work better in Web Workers due to better `root` detection (#804)
- Callbacks are now optional in `whilst`, `doWhilst`, `until`, and `doUntil` (#642)
- Various internal updates (#786, #801, #802, #803)
- Various doc fixes (#790, #794)
Bug Fixes:
- `cargo` now exposes the `payload` size, and `cargo.payload` can be changed on the fly after the `cargo` is created. (#740, #744, #783)
# v1.2.1
Bug Fix:
- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
# v1.2.0
New Features:
- Added `timesLimit` (#743)
- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. (#747, #772)
Bug Fixes:
- Fixed a regression in `each` and family with empty arrays that have additional properties. (#775, #777)
# v1.1.1
Bug Fix:
- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782)
# v1.1.0
New Features:
- `cargo` now supports all of the same methods and event callbacks as `queue`.
- Added `ensureAsync` - A wrapper that ensures an async function calls its callback on a later tick. (#769)
- Optimized `map`, `eachOf`, and `waterfall` families of functions
- Passing a `null` or `undefined` array to `map`, `each`, `parallel` and families will be treated as an empty array (#667).
- The callback is now optional for the composed results of `compose` and `seq`. (#618)
- Reduced file size by 4kb, (minified version by 1kb)
- Added code coverage through `nyc` and `coveralls` (#768)
Bug Fixes:
- `forever` will no longer stack overflow with a synchronous iterator (#622)
- `eachLimit` and other limit functions will stop iterating once an error occurs (#754)
- Always pass `null` in callbacks when there is no error (#439)
- Ensure proper conditions when calling `drain()` after pushing an empty data set to a queue (#668)
- `each` and family will properly handle an empty array (#578)
- `eachSeries` and family will finish if the underlying array is modified during execution (#557)
- `queue` will throw if a non-function is passed to `q.push()` (#593)
- Doc fixes (#629, #766)
# v1.0.0
No known breaking changes, we are simply complying with semver from here on out.
Changes:
- Start using a changelog!
- Add `forEachOf` for iterating over Objects (or to iterate Arrays with indexes available) (#168 #704 #321)
- Detect deadlocks in `auto` (#663)
- Better support for require.js (#527)
- Throw if queue created with concurrency `0` (#714)
- Fix unneeded iteration in `queue.resume()` (#758)
- Guard against timer mocking overriding `setImmediate` (#609 #611)
- Miscellaneous doc fixes (#542 #596 #615 #628 #631 #690 #729)
- Use single noop function internally (#546)
- Optimize internal `_each`, `_map` and `_keys` functions.

View File

@@ -0,0 +1,19 @@
Copyright (c) 2010-2014 Caolan McMahon
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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
{
"_from": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"_id": "async@1.5.2",
"_inBundle": false,
"_integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==",
"_location": "/skills-service-manager/async",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "async@https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"name": "async",
"escapedName": "async",
"rawSpec": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"saveSpec": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"fetchSpec": "https://registry.npmjs.org/async/-/async-1.5.2.tgz"
},
"_requiredBy": [
"/skills-service-manager",
"/skills-service-manager/jibo"
],
"_resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"_spec": "async@https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "Caolan McMahon"
},
"bugs": {
"url": "https://github.com/caolan/async/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Higher-order functions and common patterns for asynchronous code",
"devDependencies": {
"benchmark": "github:bestiejs/benchmark.js",
"bluebird": "^2.9.32",
"chai": "^3.1.0",
"coveralls": "^2.11.2",
"es6-promise": "^2.3.0",
"jscs": "^1.13.1",
"jshint": "~2.8.0",
"karma": "^0.13.2",
"karma-browserify": "^4.2.1",
"karma-firefox-launcher": "^0.1.6",
"karma-mocha": "^0.2.0",
"karma-mocha-reporter": "^1.0.2",
"lodash": "^3.9.0",
"mkdirp": "~0.5.1",
"mocha": "^2.2.5",
"native-promise-only": "^0.8.0-a",
"nodeunit": ">0.0.0",
"nyc": "^2.1.0",
"rsvp": "^3.0.18",
"semver": "^4.3.6",
"uglify-js": "~2.4.0",
"xyz": "^0.5.0",
"yargs": "~3.9.1"
},
"files": [
"lib",
"dist/async.js",
"dist/async.min.js"
],
"homepage": "https://github.com/caolan/async#readme",
"jam": {
"main": "lib/async.js",
"include": [
"lib/async.js",
"README.md",
"LICENSE"
],
"categories": [
"Utilities"
]
},
"keywords": [
"async",
"callback",
"utility",
"module"
],
"license": "MIT",
"main": "lib/async.js",
"name": "async",
"repository": {
"type": "git",
"url": "git+https://github.com/caolan/async.git"
},
"scripts": {
"coverage": "nyc npm test && nyc report",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"lint": "jshint lib/*.js test/*.js perf/*.js && jscs lib/*.js test/*.js perf/*.js",
"mocha-browser-test": "karma start",
"mocha-node-test": "mocha mocha_test/",
"mocha-test": "npm run mocha-node-test && npm run mocha-browser-test",
"nodeunit-test": "nodeunit test/test-async.js",
"test": "npm run-script lint && npm run nodeunit-test && npm run mocha-test"
},
"spm": {
"main": "lib/async.js"
},
"version": "1.5.2",
"volo": {
"main": "lib/async.js",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
}

View File

@@ -0,0 +1,492 @@
1.16.0 / 2017-01-17
===================
* deps: debug@2.6.0
- Allow colors in workers
- Deprecated `DEBUG_FD` environment variable
- Fix error when running under React Native
- Use same color for same namespace
- deps: ms@0.7.2
* deps: http-errors@~1.5.1
- deps: inherits@2.0.3
- deps: setprototypeof@1.0.2
- deps: statuses@'>= 1.3.1 < 2'
* deps: iconv-lite@0.4.15
- Added encoding MS-31J
- Added encoding MS-932
- Added encoding MS-936
- Added encoding MS-949
- Added encoding MS-950
- Fix GBK/GB18030 handling of Euro character
* deps: qs@6.3.0
- Fix array parsing from skipping empty values
- Fix compacting nested arrays
* deps: raw-body@~2.2.0
- deps: iconv-lite@0.4.15
* deps: type-is@~1.6.14
- deps: mime-types@~2.1.13
1.15.2 / 2016-06-19
===================
* deps: bytes@2.4.0
* deps: content-type@~1.0.2
- perf: enable strict mode
* deps: http-errors@~1.5.0
- Use `setprototypeof` module to replace `__proto__` setting
- deps: statuses@'>= 1.3.0 < 2'
- perf: enable strict mode
* deps: qs@6.2.0
* deps: raw-body@~2.1.7
- deps: bytes@2.4.0
- perf: remove double-cleanup on happy path
* deps: type-is@~1.6.13
- deps: mime-types@~2.1.11
1.15.1 / 2016-05-05
===================
* deps: bytes@2.3.0
- Drop partial bytes on all parsed units
- Fix parsing byte string that looks like hex
* deps: raw-body@~2.1.6
- deps: bytes@2.3.0
* deps: type-is@~1.6.12
- deps: mime-types@~2.1.10
1.15.0 / 2016-02-10
===================
* deps: http-errors@~1.4.0
- Add `HttpError` export, for `err instanceof createError.HttpError`
- deps: inherits@2.0.1
- deps: statuses@'>= 1.2.1 < 2'
* deps: qs@6.1.0
* deps: type-is@~1.6.11
- deps: mime-types@~2.1.9
1.14.2 / 2015-12-16
===================
* deps: bytes@2.2.0
* deps: iconv-lite@0.4.13
* deps: qs@5.2.0
* deps: raw-body@~2.1.5
- deps: bytes@2.2.0
- deps: iconv-lite@0.4.13
* deps: type-is@~1.6.10
- deps: mime-types@~2.1.8
1.14.1 / 2015-09-27
===================
* Fix issue where invalid charset results in 400 when `verify` used
* deps: iconv-lite@0.4.12
- Fix CESU-8 decoding in Node.js 4.x
* deps: raw-body@~2.1.4
- Fix masking critical errors from `iconv-lite`
- deps: iconv-lite@0.4.12
* deps: type-is@~1.6.9
- deps: mime-types@~2.1.7
1.14.0 / 2015-09-16
===================
* Fix JSON strict parse error to match syntax errors
* Provide static `require` analysis in `urlencoded` parser
* deps: depd@~1.1.0
- Support web browser loading
* deps: qs@5.1.0
* deps: raw-body@~2.1.3
- Fix sync callback when attaching data listener causes sync read
* deps: type-is@~1.6.8
- Fix type error when given invalid type to match against
- deps: mime-types@~2.1.6
1.13.3 / 2015-07-31
===================
* deps: type-is@~1.6.6
- deps: mime-types@~2.1.4
1.13.2 / 2015-07-05
===================
* deps: iconv-lite@0.4.11
* deps: qs@4.0.0
- Fix dropping parameters like `hasOwnProperty`
- Fix user-visible incompatibilities from 3.1.0
- Fix various parsing edge cases
* deps: raw-body@~2.1.2
- Fix error stack traces to skip `makeError`
- deps: iconv-lite@0.4.11
* deps: type-is@~1.6.4
- deps: mime-types@~2.1.2
- perf: enable strict mode
- perf: remove argument reassignment
1.13.1 / 2015-06-16
===================
* deps: qs@2.4.2
- Downgraded from 3.1.0 because of user-visible incompatibilities
1.13.0 / 2015-06-14
===================
* Add `statusCode` property on `Error`s, in addition to `status`
* Change `type` default to `application/json` for JSON parser
* Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
* Provide static `require` analysis
* Use the `http-errors` module to generate errors
* deps: bytes@2.1.0
- Slight optimizations
* deps: iconv-lite@0.4.10
- The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails
- Leading BOM is now removed when decoding
* deps: on-finished@~2.3.0
- Add defined behavior for HTTP `CONNECT` requests
- Add defined behavior for HTTP `Upgrade` requests
- deps: ee-first@1.1.1
* deps: qs@3.1.0
- Fix dropping parameters like `hasOwnProperty`
- Fix various parsing edge cases
- Parsed object now has `null` prototype
* deps: raw-body@~2.1.1
- Use `unpipe` module for unpiping requests
- deps: iconv-lite@0.4.10
* deps: type-is@~1.6.3
- deps: mime-types@~2.1.1
- perf: reduce try block size
- perf: remove bitwise operations
* perf: enable strict mode
* perf: remove argument reassignment
* perf: remove delete call
1.12.4 / 2015-05-10
===================
* deps: debug@~2.2.0
* deps: qs@2.4.2
- Fix allowing parameters like `constructor`
* deps: on-finished@~2.2.1
* deps: raw-body@~2.0.1
- Fix a false-positive when unpiping in Node.js 0.8
- deps: bytes@2.0.1
* deps: type-is@~1.6.2
- deps: mime-types@~2.0.11
1.12.3 / 2015-04-15
===================
* Slight efficiency improvement when not debugging
* deps: depd@~1.0.1
* deps: iconv-lite@0.4.8
- Add encoding alias UNICODE-1-1-UTF-7
* deps: raw-body@1.3.4
- Fix hanging callback if request aborts during read
- deps: iconv-lite@0.4.8
1.12.2 / 2015-03-16
===================
* deps: qs@2.4.1
- Fix error when parameter `hasOwnProperty` is present
1.12.1 / 2015-03-15
===================
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
* deps: type-is@~1.6.1
- deps: mime-types@~2.0.10
1.12.0 / 2015-02-13
===================
* add `debug` messages
* accept a function for the `type` option
* use `content-type` to parse `Content-Type` headers
* deps: iconv-lite@0.4.7
- Gracefully support enumerables on `Object.prototype`
* deps: raw-body@1.3.3
- deps: iconv-lite@0.4.7
* deps: type-is@~1.6.0
- fix argument reassignment
- fix false-positives in `hasBody` `Transfer-Encoding` check
- support wildcard for both type and subtype (`*/*`)
- deps: mime-types@~2.0.9
1.11.0 / 2015-01-30
===================
* make internal `extended: true` depth limit infinity
* deps: type-is@~1.5.6
- deps: mime-types@~2.0.8
1.10.2 / 2015-01-20
===================
* deps: iconv-lite@0.4.6
- Fix rare aliases of single-byte encodings
* deps: raw-body@1.3.2
- deps: iconv-lite@0.4.6
1.10.1 / 2015-01-01
===================
* deps: on-finished@~2.2.0
* deps: type-is@~1.5.5
- deps: mime-types@~2.0.7
1.10.0 / 2014-12-02
===================
* make internal `extended: true` array limit dynamic
1.9.3 / 2014-11-21
==================
* deps: iconv-lite@0.4.5
- Fix Windows-31J and X-SJIS encoding support
* deps: qs@2.3.3
- Fix `arrayLimit` behavior
* deps: raw-body@1.3.1
- deps: iconv-lite@0.4.5
* deps: type-is@~1.5.3
- deps: mime-types@~2.0.3
1.9.2 / 2014-10-27
==================
* deps: qs@2.3.2
- Fix parsing of mixed objects and values
1.9.1 / 2014-10-22
==================
* deps: on-finished@~2.1.1
- Fix handling of pipelined requests
* deps: qs@2.3.0
- Fix parsing of mixed implicit and explicit arrays
* deps: type-is@~1.5.2
- deps: mime-types@~2.0.2
1.9.0 / 2014-09-24
==================
* include the charset in "unsupported charset" error message
* include the encoding in "unsupported content encoding" error message
* deps: depd@~1.0.0
1.8.4 / 2014-09-23
==================
* fix content encoding to be case-insensitive
1.8.3 / 2014-09-19
==================
* deps: qs@2.2.4
- Fix issue with object keys starting with numbers truncated
1.8.2 / 2014-09-15
==================
* deps: depd@0.4.5
1.8.1 / 2014-09-07
==================
* deps: media-typer@0.3.0
* deps: type-is@~1.5.1
1.8.0 / 2014-09-05
==================
* make empty-body-handling consistent between chunked requests
- empty `json` produces `{}`
- empty `raw` produces `new Buffer(0)`
- empty `text` produces `''`
- empty `urlencoded` produces `{}`
* deps: qs@2.2.3
- Fix issue where first empty value in array is discarded
* deps: type-is@~1.5.0
- fix `hasbody` to be true for `content-length: 0`
1.7.0 / 2014-09-01
==================
* add `parameterLimit` option to `urlencoded` parser
* change `urlencoded` extended array limit to 100
* respond with 413 when over `parameterLimit` in `urlencoded`
1.6.7 / 2014-08-29
==================
* deps: qs@2.2.2
- Remove unnecessary cloning
1.6.6 / 2014-08-27
==================
* deps: qs@2.2.0
- Array parsing fix
- Performance improvements
1.6.5 / 2014-08-16
==================
* deps: on-finished@2.1.0
1.6.4 / 2014-08-14
==================
* deps: qs@1.2.2
1.6.3 / 2014-08-10
==================
* deps: qs@1.2.1
1.6.2 / 2014-08-07
==================
* deps: qs@1.2.0
- Fix parsing array of objects
1.6.1 / 2014-08-06
==================
* deps: qs@1.1.0
- Accept urlencoded square brackets
- Accept empty values in implicit array notation
1.6.0 / 2014-08-05
==================
* deps: qs@1.0.2
- Complete rewrite
- Limits array length to 20
- Limits object depth to 5
- Limits parameters to 1,000
1.5.2 / 2014-07-27
==================
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
1.5.1 / 2014-07-26
==================
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
1.5.0 / 2014-07-20
==================
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
* deps: iconv-lite@0.4.4
- Added encoding UTF-7
* deps: raw-body@1.3.0
- deps: iconv-lite@0.4.4
- Added encoding UTF-7
- Fix `Cannot switch to old mode now` error on Node.js 0.10+
* deps: type-is@~1.3.2
1.4.3 / 2014-06-19
==================
* deps: type-is@1.3.1
- fix global variable leak
1.4.2 / 2014-06-19
==================
* deps: type-is@1.3.0
- improve type parsing
1.4.1 / 2014-06-19
==================
* fix urlencoded extended deprecation message
1.4.0 / 2014-06-19
==================
* add `text` parser
* add `raw` parser
* check accepted charset in content-type (accepts utf-8)
* check accepted encoding in content-encoding (accepts identity)
* deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed
* deprecate `urlencoded()` without provided `extended` option
* lazy-load urlencoded parsers
* parsers split into files for reduced mem usage
* support gzip and deflate bodies
- set `inflate: false` to turn off
* deps: raw-body@1.2.2
- Support all encodings from `iconv-lite`
1.3.1 / 2014-06-11
==================
* deps: type-is@1.2.1
- Switch dependency from mime to mime-types@1.0.0
1.3.0 / 2014-05-31
==================
* add `extended` option to urlencoded parser
1.2.2 / 2014-05-27
==================
* deps: raw-body@1.1.6
- assert stream encoding on node.js 0.8
- assert stream encoding on node.js < 0.10.6
- deps: bytes@1
1.2.1 / 2014-05-26
==================
* invoke `next(err)` after request fully read
- prevents hung responses and socket hang ups
1.2.0 / 2014-05-11
==================
* add `verify` option
* deps: type-is@1.2.0
- support suffix matching
1.1.2 / 2014-05-11
==================
* improve json parser speed
1.1.1 / 2014-05-11
==================
* fix repeated limit parsing with every request
1.1.0 / 2014-05-10
==================
* add `type` option
* deps: pin for safety and consistency
1.0.2 / 2014-04-14
==================
* use `type-is` module
1.0.1 / 2014-03-20
==================
* lower default limits to 100kb

View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2014-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.

View File

@@ -0,0 +1,416 @@
# body-parser
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Node.js body parsing middleware.
Parse incoming request bodies in a middleware before your handlers, available
under the `req.body` property.
[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/).
_This does not handle multipart bodies_, due to their complex and typically
large nature. For multipart bodies, you may be interested in the following
modules:
* [busboy](https://www.npmjs.org/package/busboy#readme) and
[connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)
* [multiparty](https://www.npmjs.org/package/multiparty#readme) and
[connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)
* [formidable](https://www.npmjs.org/package/formidable#readme)
* [multer](https://www.npmjs.org/package/multer#readme)
This module provides the following parsers:
* [JSON body parser](#bodyparserjsonoptions)
* [Raw body parser](#bodyparserrawoptions)
* [Text body parser](#bodyparsertextoptions)
* [URL-encoded form body parser](#bodyparserurlencodedoptions)
Other body parsers you might be interested in:
- [body](https://www.npmjs.org/package/body#readme)
- [co-body](https://www.npmjs.org/package/co-body#readme)
## Installation
```sh
$ npm install body-parser
```
## API
<!-- eslint-disable no-unused-vars -->
```js
var bodyParser = require('body-parser')
```
The `bodyParser` object exposes various factories to create middlewares. All
middlewares will populate the `req.body` property with the parsed body, or an
empty object (`{}`) if there was no body to parse (or an error was returned).
The various errors returned by this module are described in the
[errors section](#errors).
### bodyParser.json(options)
Returns middleware that only parses `json`. This parser accepts any Unicode
encoding of the body and supports automatic inflation of `gzip` and `deflate`
encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`).
#### Options
The `json` function takes an option `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### reviver
The `reviver` option is passed directly to `JSON.parse` as the second
argument. You can find more information on this argument
[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
##### strict
When set to `true`, will only accept arrays and objects; when `false` will
accept anything `JSON.parse` accepts. Defaults to `true`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `json`), a mime type (like
`application/json`), or a mime type with a wildcard (like `*/*` or `*/json`).
If a function, the `type` option is called as `fn(req)` and the request is
parsed if it returns a truthy value. Defaults to `application/json`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.raw(options)
Returns middleware that parses all bodies as a `Buffer`. This parser
supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a `Buffer` object
of the body.
#### Options
The `raw` function takes an option `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `bin`), a mime type (like
`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
`application/*`). If a function, the `type` option is called as `fn(req)`
and the request is parsed if it returns a truthy value. Defaults to
`application/octet-stream`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.text(options)
Returns middleware that parses all bodies as a string. This parser supports
automatic inflation of `gzip` and `deflate` encodings.
A new `body` string containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a string of the
body.
#### Options
The `text` function takes an option `options` object that may contain any of
the following keys:
##### defaultCharset
Specify the default character set for the text content if the charset is not
specified in the `Content-Type` header of the request. Defaults to `utf-8`.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `txt`), a mime type (like
`text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`).
If a function, the `type` option is called as `fn(req)` and the request is
parsed if it returns a truthy value. Defaults to `text/plain`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.urlencoded(options)
Returns middleware that only parses `urlencoded` bodies. This parser accepts
only UTF-8 encoding of the body and supports automatic inflation of `gzip`
and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This object will contain
key-value pairs, where the value can be a string or array (when `extended` is
`false`), or any type (when `extended` is `true`).
#### Options
The `urlencoded` function takes an option `options` object that may contain
any of the following keys:
##### extended
The `extended` option allows to choose between parsing the URL-encoded data
with the `querystring` library (when `false`) or the `qs` library (when
`true`). The "extended" syntax allows for rich objects and arrays to be
encoded into the URL-encoded format, allowing for a JSON-like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
Defaults to `true`, but using the default has been deprecated. Please
research into the difference between `qs` and `querystring` and choose the
appropriate setting.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### parameterLimit
The `parameterLimit` option controls the maximum number of parameters that
are allowed in the URL-encoded data. If a request contains more parameters
than this value, a 413 will be returned to the client. Defaults to `1000`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a function or a string. If a string, `type` option
is passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `urlencoded`), a mime type (like
`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
`*/x-www-form-urlencoded`). If a function, the `type` option is called as
`fn(req)` and the request is parsed if it returns a truthy value. Defaults
to `application/x-www-form-urlencoded`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
## Errors
The middlewares provided by this module create errors depending on the error
condition during parsing. The errors will typically have a `status` property
that contains the suggested HTTP response code and a `body` property containing
the read body, if available.
The following are the common errors emitted, though any error can come through
for various reasons.
### content encoding unsupported
This error will occur when the request had a `Content-Encoding` header that
contained an encoding but the "inflation" option was set to `false`. The
`status` property is set to `415`.
### request aborted
This error will occur when the request is aborted by the client before reading
the body has finished. The `received` property will be set to the number of
bytes received before the request was aborted and the `expected` property is
set to the number of expected bytes. The `status` property is set to `400`.
### request entity too large
This error will occur when the request body's size is larger than the "limit"
option. The `limit` property will be set to the byte limit and the `length`
property will be set to the request body's length. The `status` property is
set to `413`.
### request size did not match content length
This error will occur when the request's length did not match the length from
the `Content-Length` header. This typically occurs when the request is malformed,
typically when the `Content-Length` header was calculated based on characters
instead of bytes. The `status` property is set to `400`.
### stream encoding should not be set
This error will occur when something called the `req.setEncoding` method prior
to this middleware. This module operates directly on bytes only and you cannot
call `req.setEncoding` when using this module. The `status` property is set to
`500`.
### unsupported charset "BOGUS"
This error will occur when the request had a charset parameter in the
`Content-Type` header, but the `iconv-lite` module does not support it OR the
parser does not support it. The charset is contained in the message as well
as in the `charset` property. The `status` property is set to `415`.
### unsupported content encoding "bogus"
This error will occur when the request had a `Content-Encoding` header that
contained an unsupported encoding. The encoding is contained in the message
as well as in the `encoding` property. The `status` property is set to `415`.
## Examples
### Express/Connect top-level generic
This example demonstrates adding a generic JSON and URL-encoded parser as a
top-level middleware, which will parse the bodies of all incoming requests.
This is the simplest setup.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
```
### Express route-specific
This example demonstrates adding body parsers specifically to the routes that
need them. In general, this is the most recommended way to use body-parser with
Express.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})
```
### Change accepted type for parsers
All the parsers accept a `type` option which allows you to change the
`Content-Type` that the middleware will parse.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }))
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/body-parser.svg
[npm-url]: https://npmjs.org/package/body-parser
[travis-image]: https://img.shields.io/travis/expressjs/body-parser/master.svg
[travis-url]: https://travis-ci.org/expressjs/body-parser
[coveralls-image]: https://img.shields.io/coveralls/expressjs/body-parser/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
[downloads-image]: https://img.shields.io/npm/dm/body-parser.svg
[downloads-url]: https://npmjs.org/package/body-parser
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

View File

@@ -0,0 +1,157 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var deprecate = require('depd')('body-parser')
/**
* Cache of loaded parsers.
* @private
*/
var parsers = Object.create(null)
/**
* @typedef Parsers
* @type {function}
* @property {function} json
* @property {function} raw
* @property {function} text
* @property {function} urlencoded
*/
/**
* Module exports.
* @type {Parsers}
*/
exports = module.exports = deprecate.function(bodyParser,
'bodyParser: use individual json/urlencoded middlewares')
/**
* JSON parser.
* @public
*/
Object.defineProperty(exports, 'json', {
configurable: true,
enumerable: true,
get: createParserGetter('json')
})
/**
* Raw parser.
* @public
*/
Object.defineProperty(exports, 'raw', {
configurable: true,
enumerable: true,
get: createParserGetter('raw')
})
/**
* Text parser.
* @public
*/
Object.defineProperty(exports, 'text', {
configurable: true,
enumerable: true,
get: createParserGetter('text')
})
/**
* URL-encoded parser.
* @public
*/
Object.defineProperty(exports, 'urlencoded', {
configurable: true,
enumerable: true,
get: createParserGetter('urlencoded')
})
/**
* Create a middleware to parse json and urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @deprecated
* @public
*/
function bodyParser (options) {
var opts = {}
// exclude type option
if (options) {
for (var prop in options) {
if (prop !== 'type') {
opts[prop] = options[prop]
}
}
}
var _urlencoded = exports.urlencoded(opts)
var _json = exports.json(opts)
return function bodyParser (req, res, next) {
_json(req, res, function (err) {
if (err) return next(err)
_urlencoded(req, res, next)
})
}
}
/**
* Create a getter for loading a parser.
* @private
*/
function createParserGetter (name) {
return function get () {
return loadParser(name)
}
}
/**
* Load a parser module.
* @private
*/
function loadParser (parserName) {
var parser = parsers[parserName]
if (parser !== undefined) {
return parser
}
// this uses a switch for static require analysis
switch (parserName) {
case 'json':
parser = require('./lib/types/json')
break
case 'raw':
parser = require('./lib/types/raw')
break
case 'text':
parser = require('./lib/types/text')
break
case 'urlencoded':
parser = require('./lib/types/urlencoded')
break
}
// store to prevent invoking require()
return (parsers[parserName] = parser)
}

View File

@@ -0,0 +1,188 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var getBody = require('raw-body')
var iconv = require('iconv-lite')
var onFinished = require('on-finished')
var zlib = require('zlib')
/**
* Module exports.
*/
module.exports = read
/**
* Read a request into a buffer and parse.
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {function} parse
* @param {function} debug
* @param {object} [options]
* @api private
*/
function read (req, res, next, parse, debug, options) {
var length
var opts = options || {}
var stream
// flag as parsed
req._body = true
// read options
var encoding = opts.encoding !== null
? opts.encoding || 'utf-8'
: null
var verify = opts.verify
try {
// get the content stream
stream = contentstream(req, debug, opts.inflate)
length = stream.length
stream.length = undefined
} catch (err) {
return next(err)
}
// set raw-body options
opts.length = length
opts.encoding = verify
? null
: encoding
// assert charset is supported
if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase()
}))
}
// read body
debug('read body')
getBody(stream, opts, function (err, body) {
if (err) {
// default to 400
setErrorStatus(err, 400)
// echo back charset
if (err.type === 'encoding.unsupported') {
err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase()
})
}
// read off entire request
stream.resume()
onFinished(req, function onfinished () {
next(err)
})
return
}
// verify
if (verify) {
try {
debug('verify body')
verify(req, res, body, encoding)
} catch (err) {
// default to 403
setErrorStatus(err, 403)
next(err)
return
}
}
// parse
var str
try {
debug('parse body')
str = typeof body !== 'string' && encoding !== null
? iconv.decode(body, encoding)
: body
req.body = parse(str)
} catch (err) {
err.body = str === undefined
? body
: str
// default to 400
setErrorStatus(err, 400)
next(err)
return
}
next()
})
}
/**
* Get the content stream of the request.
*
* @param {object} req
* @param {function} debug
* @param {boolean} [inflate=true]
* @return {object}
* @api private
*/
function contentstream (req, debug, inflate) {
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
var length = req.headers['content-length']
var stream
debug('content-encoding "%s"', encoding)
if (inflate === false && encoding !== 'identity') {
throw createError(415, 'content encoding unsupported')
}
switch (encoding) {
case 'deflate':
stream = zlib.createInflate()
debug('inflate body')
req.pipe(stream)
break
case 'gzip':
stream = zlib.createGunzip()
debug('gunzip body')
req.pipe(stream)
break
case 'identity':
stream = req
stream.length = length
break
default:
throw createError(415, 'unsupported content encoding "' + encoding + '"', {
encoding: encoding
})
}
return stream
}
/**
* Set a status on an error object, if ones does not exist
* @private
*/
function setErrorStatus (error, status) {
if (!error.status && !error.statusCode) {
error.status = status
error.statusCode = status
}
}

View File

@@ -0,0 +1,175 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:json')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = json
/**
* RegExp to match the first non-space in a string.
*
* Allowed whitespace is defined in RFC 7159:
*
* ws = *(
* %x20 / ; Space
* %x09 / ; Horizontal tab
* %x0A / ; Line feed or New line
* %x0D ) ; Carriage return
*/
var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*(.)/ // eslint-disable-line no-control-regex
/**
* Create a middleware to parse JSON bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function json (options) {
var opts = options || {}
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var inflate = opts.inflate !== false
var reviver = opts.reviver
var strict = opts.strict !== false
var type = opts.type || 'application/json'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
if (body.length === 0) {
// special-case empty json body, as it's a common client-side mistake
// TODO: maybe make this configurable or part of "strict" option
return {}
}
if (strict) {
var first = firstchar(body)
if (first !== '{' && first !== '[') {
debug('strict violation')
throw new SyntaxError('Unexpected token ' + first)
}
}
debug('parse json')
return JSON.parse(body, reviver)
}
return function jsonParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset per RFC 7159 sec 8.1
var charset = getCharset(req) || 'utf-8'
if (charset.substr(0, 4) !== 'utf-') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the first non-whitespace character in a string.
*
* @param {string} str
* @return {function}
* @api public
*/
function firstchar (str) {
var match = FIRST_CHAR_REGEXP.exec(str)
return match ? match[1] : ''
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@@ -0,0 +1,101 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var debug = require('debug')('body-parser:raw')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = raw
/**
* Create a middleware to parse raw bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function raw (options) {
var opts = options || {}
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/octet-stream'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function rawParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// read
read(req, res, next, parse, debug, {
encoding: null,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@@ -0,0 +1,121 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var debug = require('debug')('body-parser:text')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = text
/**
* Create a middleware to parse text bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function text (options) {
var opts = options || {}
var defaultCharset = opts.defaultCharset || 'utf-8'
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'text/plain'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function textParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// get charset
var charset = getCharset(req) || defaultCharset
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@@ -0,0 +1,279 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = urlencoded
/**
* Cache of parser modules.
*/
var parsers = Object.create(null)
/**
* Create a middleware to parse urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function urlencoded (options) {
var opts = options || {}
// notice because option default will flip in next major
if (opts.extended === undefined) {
deprecate('undefined extended: provide extended option')
}
var extended = opts.extended !== false
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/x-www-form-urlencoded'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate query parser
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
return body.length
? queryparse(body)
: {}
}
return function urlencodedParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset
var charset = getCharset(req) || 'utf-8'
if (charset !== 'utf-8') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
debug: debug,
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the extended query parser.
*
* @param {object} options
*/
function extendedparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('qs')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
var arrayLimit = Math.max(100, paramCount)
debug('parse extended urlencoding')
return parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: Infinity,
parameterLimit: parameterLimit
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Count the number of parameters, stopping once limit reached
*
* @param {string} body
* @param {number} limit
* @api private
*/
function parameterCount (body, limit) {
var count = 0
var index = 0
while ((index = body.indexOf('&', index)) !== -1) {
count++
index++
if (count === limit) {
return undefined
}
}
return count
}
/**
* Get parser for module name dynamically.
*
* @param {string} name
* @return {function}
* @api private
*/
function parser (name) {
var mod = parsers[name]
if (mod !== undefined) {
return mod.parse
}
// this uses a switch for static require analysis
switch (name) {
case 'qs':
mod = require('qs')
break
case 'querystring':
mod = require('querystring')
break
}
// store to prevent invoking require()
parsers[name] = mod
return mod.parse
}
/**
* Get the simple query parser.
*
* @param {object} options
*/
function simpleparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('querystring')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
debug('parse urlencoding')
return parse(body, undefined, undefined, {maxKeys: parameterLimit})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@@ -0,0 +1,70 @@
2.4.0 / 2016-06-01
==================
* Add option "unitSeparator"
2.3.0 / 2016-02-15
==================
* Drop partial bytes on all parsed units
* Fix non-finite numbers to `.format` to return `null`
* Fix parsing byte string that looks like hex
* perf: hoist regular expressions
2.2.0 / 2015-11-13
==================
* add option "decimalPlaces"
* add option "fixedDecimals"
2.1.0 / 2015-05-21
==================
* add `.format` export
* add `.parse` export
2.0.2 / 2015-05-20
==================
* remove map recreation
* remove unnecessary object construction
2.0.1 / 2015-05-07
==================
* fix browserify require
* remove node.extend dependency
2.0.0 / 2015-04-12
==================
* add option "case"
* add option "thousandsSeparator"
* return "null" on invalid parse input
* support proper round-trip: bytes(bytes(num)) === num
* units no longer case sensitive when parsing
1.0.0 / 2014-05-05
==================
* add negative support. fixes #6
0.3.0 / 2014-03-19
==================
* added terabyte support
0.2.1 / 2013-04-01
==================
* add .component
0.2.0 / 2012-10-28
==================
* bytes(200).should.eql('200b')
0.1.0 / 2012-07-04
==================
* add bytes to string conversion [yields]

View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2012-2014 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2015 Jed Watson <jed.watson@me.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.

View File

@@ -0,0 +1,114 @@
# Bytes utility
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa.
## Usage
```js
var bytes = require('bytes');
```
#### bytes.format(number value, [options]): string|null
Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is
rounded.
**Arguments**
| Name | Type | Description |
|---------|--------|--------------------|
| value | `number` | Value in bytes |
| options | `Object` | Conversion options |
**Options**
| Property | Type | Description |
|-------------------|--------|-----------------------------------------------------------------------------------------|
| decimalPlaces | `number`&#124;`null` | Maximum number of decimal places to include in output. Default value to `2`. |
| fixedDecimals | `boolean`&#124;`null` | Whether to always display the maximum number of decimal places. Default value to `false` |
| thousandsSeparator | `string`&#124;`null` | Example of values: `' '`, `','` and `.`... Default value to `' '`. |
| unitSeparator | `string`&#124;`null` | Separator to use between number and unit. Default value to `''`. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `string`&#124;`null` | Return null upon error. String value otherwise. |
**Example**
```js
bytes(1024);
// output: '1kB'
bytes(1000);
// output: '1000B'
bytes(1000, {thousandsSeparator: ' '});
// output: '1 000B'
bytes(1024 * 1.7, {decimalPlaces: 0});
// output: '2kB'
bytes(1024, {unitSeparator: ' '});
// output: '1 kB'
```
#### bytes.parse(string value): number|null
Parse the string value into an integer in bytes. If no unit is given, it is assumed the value is in bytes.
Supported units and abbreviations are as follows and are case-insensitive:
* "b" for bytes
* "kb" for kilobytes
* "mb" for megabytes
* "gb" for gigabytes
* "tb" for terabytes
The units are in powers of two, not ten. This means 1kb = 1024b according to this parser.
**Arguments**
| Name | Type | Description |
|---------------|--------|--------------------|
| value | `string` | String to parse. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `number`&#124;`null` | Return null upon error. Value in bytes otherwise. |
**Example**
```js
bytes('1kB');
// output: 1024
bytes('1024');
// output: 1024
```
## Installation
```bash
npm install bytes --save
component install visionmedia/bytes.js
```
## License
[![npm](https://img.shields.io/npm/l/express.svg)](https://github.com/visionmedia/bytes.js/blob/master/LICENSE)
[downloads-image]: https://img.shields.io/npm/dm/bytes.svg
[downloads-url]: https://npmjs.org/package/bytes
[npm-image]: https://img.shields.io/npm/v/bytes.svg
[npm-url]: https://npmjs.org/package/bytes
[travis-image]: https://img.shields.io/travis/visionmedia/bytes.js/master.svg
[travis-url]: https://travis-ci.org/visionmedia/bytes.js

View File

@@ -0,0 +1,157 @@
/*!
* bytes
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015 Jed Watson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = bytes;
module.exports.format = format;
module.exports.parse = parse;
/**
* Module variables.
* @private
*/
var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
var map = {
b: 1,
kb: 1 << 10,
mb: 1 << 20,
gb: 1 << 30,
tb: ((1 << 30) * 1024)
};
// TODO: use is-finite module?
var numberIsFinite = Number.isFinite || function (v) { return typeof v === 'number' && isFinite(v); };
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i;
/**
* Convert the given value in bytes into a string or parse to string to an integer in bytes.
*
* @param {string|number} value
* @param {{
* case: [string],
* decimalPlaces: [number]
* fixedDecimals: [boolean]
* thousandsSeparator: [string]
* unitSeparator: [string]
* }} [options] bytes options.
*
* @returns {string|number|null}
*/
function bytes(value, options) {
if (typeof value === 'string') {
return parse(value);
}
if (typeof value === 'number') {
return format(value, options);
}
return null;
}
/**
* Format the given value in bytes into a string.
*
* If the value is negative, it is kept as such. If it is a float,
* it is rounded.
*
* @param {number} value
* @param {object} [options]
* @param {number} [options.decimalPlaces=2]
* @param {number} [options.fixedDecimals=false]
* @param {string} [options.thousandsSeparator=]
* @param {string} [options.unitSeparator=]
*
* @returns {string|null}
* @public
*/
function format(value, options) {
if (!numberIsFinite(value)) {
return null;
}
var mag = Math.abs(value);
var thousandsSeparator = (options && options.thousandsSeparator) || '';
var unitSeparator = (options && options.unitSeparator) || '';
var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
var fixedDecimals = Boolean(options && options.fixedDecimals);
var unit = 'B';
if (mag >= map.tb) {
unit = 'TB';
} else if (mag >= map.gb) {
unit = 'GB';
} else if (mag >= map.mb) {
unit = 'MB';
} else if (mag >= map.kb) {
unit = 'kB';
}
var val = value / map[unit.toLowerCase()];
var str = val.toFixed(decimalPlaces);
if (!fixedDecimals) {
str = str.replace(formatDecimalsRegExp, '$1');
}
if (thousandsSeparator) {
str = str.replace(formatThousandsRegExp, thousandsSeparator);
}
return str + unitSeparator + unit;
}
/**
* Parse the string value into an integer in bytes.
*
* If no unit is given, it is assumed the value is in bytes.
*
* @param {number|string} val
*
* @returns {number|null}
* @public
*/
function parse(val) {
if (typeof val === 'number' && !isNaN(val)) {
return val;
}
if (typeof val !== 'string') {
return null;
}
// Test if the string passed is valid
var results = parseRegExp.exec(val);
var floatValue;
var unit = 'b';
if (!results) {
// Nothing could be extracted from the given string
floatValue = parseInt(val, 10);
unit = 'b'
} else {
// Retrieve the value and the unit
floatValue = parseFloat(results[1]);
unit = results[4].toLowerCase();
}
return Math.floor(map[unit] * floatValue);
}

View File

@@ -0,0 +1,79 @@
{
"_from": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"_id": "bytes@2.4.0",
"_inBundle": false,
"_integrity": "sha512-SvUX8+c/Ga454a4fprIdIUzUN9xfd1YTvYh7ub5ZPJ+ZJ/+K2Bp6IpWGmnw8r3caLTsmhvJAKZz3qjIo9+XuCQ==",
"_location": "/skills-service-manager/body-parser/bytes",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "bytes@https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"name": "bytes",
"escapedName": "bytes",
"rawSpec": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"saveSpec": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"fetchSpec": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser",
"/skills-service-manager/body-parser/raw-body"
],
"_resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"_spec": "bytes@https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca",
"url": "http://tjholowaychuk.com"
},
"bugs": {
"url": "https://github.com/visionmedia/bytes.js/issues"
},
"bundleDependencies": false,
"component": {
"scripts": {
"bytes/index.js": "index.js"
}
},
"contributors": [
{
"name": "Jed Watson",
"email": "jed.watson@me.com"
},
{
"name": "Théo FIDRY",
"email": "theo.fidry@gmail.com"
}
],
"deprecated": false,
"description": "Utility to parse a string bytes to bytes and vice-versa",
"devDependencies": {
"mocha": "1.21.5"
},
"files": [
"History.md",
"LICENSE",
"Readme.md",
"index.js"
],
"homepage": "https://github.com/visionmedia/bytes.js#readme",
"keywords": [
"byte",
"bytes",
"utility",
"parse",
"parser",
"convert",
"converter"
],
"license": "MIT",
"name": "bytes",
"repository": {
"type": "git",
"url": "git+https://github.com/visionmedia/bytes.js.git"
},
"scripts": {
"test": "mocha --check-leaks --reporter spec"
},
"version": "2.4.0"
}

View File

@@ -0,0 +1,14 @@
1.0.2 / 2016-05-09
==================
* perf: enable strict mode
1.0.1 / 2015-02-13
==================
* Improve missing `Content-Type` header error message
1.0.0 / 2015-02-01
==================
* Initial implementation, derived from `media-typer@0.3.0`

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Douglas Christopher Wilson
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.

View File

@@ -0,0 +1,92 @@
# content-type
[![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]
Create and parse HTTP Content-Type header according to RFC 7231
## Installation
```sh
$ npm install content-type
```
## API
```js
var contentType = require('content-type')
```
### contentType.parse(string)
```js
var obj = contentType.parse('image/svg+xml; charset=utf-8')
```
Parse a content type string. This will return an object with the following
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (the type and subtype, always lower case).
Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of parameter
always lower case). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the string is missing or invalid.
### contentType.parse(req)
```js
var obj = contentType.parse(req)
```
Parse the `content-type` header from the given `req`. Short-cut for
`contentType.parse(req.headers['content-type'])`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.parse(res)
```js
var obj = contentType.parse(res)
```
Parse the `content-type` header set on the given `res`. Short-cut for
`contentType.parse(res.getHeader('content-type'))`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.format(obj)
```js
var str = contentType.format({type: 'image/svg+xml'})
```
Format an object into a content type string. This will return a string of the
content type for the given object with the following properties (examples are
shown that produce the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (will be lower-cased). Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of the
parameter will be lower-cased). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the object contains an invalid type or parameter names.
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/content-type.svg
[npm-url]: https://npmjs.org/package/content-type
[node-version-image]: https://img.shields.io/node/v/content-type.svg
[node-version-url]: http://nodejs.org/download/
[travis-image]: https://img.shields.io/travis/jshttp/content-type/master.svg
[travis-url]: https://travis-ci.org/jshttp/content-type
[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-type/master.svg
[coveralls-url]: https://coveralls.io/r/jshttp/content-type
[downloads-image]: https://img.shields.io/npm/dm/content-type.svg
[downloads-url]: https://npmjs.org/package/content-type

View File

@@ -0,0 +1,216 @@
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
*
* parameter = token "=" ( token / quoted-string )
* token = 1*tchar
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
* / DIGIT / ALPHA
* ; any VCHAR, except delimiters
* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
* obs-text = %x80-FF
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
*/
var paramRegExp = /; *([!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+) */g
var textRegExp = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/
var tokenRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
/**
* RegExp to match quoted-pair in RFC 7230 sec 3.2.6
*
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
* obs-text = %x80-FF
*/
var qescRegExp = /\\([\u000b\u0020-\u00ff])/g
/**
* RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6
*/
var quoteRegExp = /([\\"])/g
/**
* RegExp to match type in RFC 6838
*
* media-type = type "/" subtype
* type = token
* subtype = token
*/
var typeRegExp = /^[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+\/[!#$%&'\*\+\-\.\^_`\|~0-9A-Za-z]+$/
/**
* Module exports.
* @public
*/
exports.format = format
exports.parse = parse
/**
* Format object to media type.
*
* @param {object} obj
* @return {string}
* @public
*/
function format(obj) {
if (!obj || typeof obj !== 'object') {
throw new TypeError('argument obj is required')
}
var parameters = obj.parameters
var type = obj.type
if (!type || !typeRegExp.test(type)) {
throw new TypeError('invalid type')
}
var string = type
// append parameters
if (parameters && typeof parameters === 'object') {
var param
var params = Object.keys(parameters).sort()
for (var i = 0; i < params.length; i++) {
param = params[i]
if (!tokenRegExp.test(param)) {
throw new TypeError('invalid parameter name')
}
string += '; ' + param + '=' + qstring(parameters[param])
}
}
return string
}
/**
* Parse media type to object.
*
* @param {string|object} string
* @return {Object}
* @public
*/
function parse(string) {
if (!string) {
throw new TypeError('argument string is required')
}
if (typeof string === 'object') {
// support req/res-like objects as argument
string = getcontenttype(string)
if (typeof string !== 'string') {
throw new TypeError('content-type header is missing from object');
}
}
if (typeof string !== 'string') {
throw new TypeError('argument string is required to be a string')
}
var index = string.indexOf(';')
var type = index !== -1
? string.substr(0, index).trim()
: string.trim()
if (!typeRegExp.test(type)) {
throw new TypeError('invalid media type')
}
var key
var match
var obj = new ContentType(type.toLowerCase())
var value
paramRegExp.lastIndex = index
while (match = paramRegExp.exec(string)) {
if (match.index !== index) {
throw new TypeError('invalid parameter format')
}
index += match[0].length
key = match[1].toLowerCase()
value = match[2]
if (value[0] === '"') {
// remove quotes and escapes
value = value
.substr(1, value.length - 2)
.replace(qescRegExp, '$1')
}
obj.parameters[key] = value
}
if (index !== -1 && index !== string.length) {
throw new TypeError('invalid parameter format')
}
return obj
}
/**
* Get content-type from req/res objects.
*
* @param {object}
* @return {Object}
* @private
*/
function getcontenttype(obj) {
if (typeof obj.getHeader === 'function') {
// res-like
return obj.getHeader('content-type')
}
if (typeof obj.headers === 'object') {
// req-like
return obj.headers && obj.headers['content-type']
}
}
/**
* Quote a string if necessary.
*
* @param {string} val
* @return {string}
* @private
*/
function qstring(val) {
var str = String(val)
// no need to quote tokens
if (tokenRegExp.test(str)) {
return str
}
if (str.length > 0 && !textRegExp.test(str)) {
throw new TypeError('invalid parameter value')
}
return '"' + str.replace(quoteRegExp, '\\$1') + '"'
}
/**
* Class to represent a content type.
* @private
*/
function ContentType(type) {
this.parameters = Object.create(null)
this.type = type
}

View File

@@ -0,0 +1,66 @@
{
"_from": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"_id": "content-type@1.0.2",
"_inBundle": false,
"_integrity": "sha512-TFmXoAjJQD7hApJpE/GttZreniTw+DYE4zlDmPRc8Q75KXrU8hFt3Qeckml/mOTVAxwbMZ3WwdEcQCzTpfV5ZA==",
"_location": "/skills-service-manager/body-parser/content-type",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "content-type@https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"name": "content-type",
"escapedName": "content-type",
"rawSpec": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"saveSpec": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"fetchSpec": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser"
],
"_resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"_spec": "content-type@https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
"bugs": {
"url": "https://github.com/jshttp/content-type/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Create and parse HTTP Content-Type header",
"devDependencies": {
"istanbul": "0.4.3",
"mocha": "~1.21.5"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"homepage": "https://github.com/jshttp/content-type#readme",
"keywords": [
"content-type",
"http",
"req",
"res",
"rfc7231"
],
"license": "MIT",
"name": "content-type",
"repository": {
"type": "git",
"url": "git+https://github.com/jshttp/content-type.git"
},
"scripts": {
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
},
"version": "1.0.2"
}

View File

@@ -0,0 +1 @@
repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve

View File

@@ -0,0 +1,11 @@
{
"env": {
"browser": true,
"node": true
},
"rules": {
"no-console": 0,
"no-empty": [1, { "allowEmptyCatch": true }]
},
"extends": "eslint:recommended"
}

View File

@@ -0,0 +1,8 @@
support
test
examples
example
*.sock
dist
yarn.lock
coverage

View File

@@ -0,0 +1,14 @@
language: node_js
node_js:
- "6"
- "5"
- "4"
install:
- make node_modules
script:
- make lint
- make test
- make coveralls

View File

@@ -0,0 +1,309 @@
2.6.0 / 2016-12-28
==================
* Fix: added better null pointer checks for browser useColors (@thebigredgeek)
* Improvement: removed explicit `window.debug` export (#404, @tootallnate)
* Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate)
2.5.2 / 2016-12-25
==================
* Fix: reference error on window within webworkers (#393, @KlausTrainer)
* Docs: fixed README typo (#391, @lurch)
* Docs: added notice about v3 api discussion (@thebigredgeek)
2.5.1 / 2016-12-20
==================
* Fix: babel-core compatibility
2.5.0 / 2016-12-20
==================
* Fix: wrong reference in bower file (@thebigredgeek)
* Fix: webworker compatibility (@thebigredgeek)
* Fix: output formatting issue (#388, @kribblo)
* Fix: babel-loader compatibility (#383, @escwald)
* Misc: removed built asset from repo and publications (@thebigredgeek)
* Misc: moved source files to /src (#378, @yamikuronue)
* Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue)
* Test: coveralls integration (#378, @yamikuronue)
* Docs: simplified language in the opening paragraph (#373, @yamikuronue)
2.4.5 / 2016-12-17
==================
* Fix: `navigator` undefined in Rhino (#376, @jochenberger)
* Fix: custom log function (#379, @hsiliev)
* Improvement: bit of cleanup + linting fixes (@thebigredgeek)
* Improvement: rm non-maintainted `dist/` dir (#375, @freewil)
* Docs: simplified language in the opening paragraph. (#373, @yamikuronue)
2.4.4 / 2016-12-14
==================
* Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts)
2.4.3 / 2016-12-14
==================
* Fix: navigation.userAgent error for react native (#364, @escwald)
2.4.2 / 2016-12-14
==================
* Fix: browser colors (#367, @tootallnate)
* Misc: travis ci integration (@thebigredgeek)
* Misc: added linting and testing boilerplate with sanity check (@thebigredgeek)
2.4.1 / 2016-12-13
==================
* Fix: typo that broke the package (#356)
2.4.0 / 2016-12-13
==================
* Fix: bower.json references unbuilt src entry point (#342, @justmatt)
* Fix: revert "handle regex special characters" (@tootallnate)
* Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate)
* Feature: %O`(big O) pretty-prints objects (#322, @tootallnate)
* Improvement: allow colors in workers (#335, @botverse)
* Improvement: use same color for same namespace. (#338, @lchenay)
2.3.3 / 2016-11-09
==================
* Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne)
* Fix: Returning `localStorage` saved values (#331, Levi Thomason)
* Improvement: Don't create an empty object when no `process` (Nathan Rajlich)
2.3.2 / 2016-11-09
==================
* Fix: be super-safe in index.js as well (@TooTallNate)
* Fix: should check whether process exists (Tom Newby)
2.3.1 / 2016-11-09
==================
* Fix: Added electron compatibility (#324, @paulcbetts)
* Improvement: Added performance optimizations (@tootallnate)
* Readme: Corrected PowerShell environment variable example (#252, @gimre)
* Misc: Removed yarn lock file from source control (#321, @fengmk2)
2.3.0 / 2016-11-07
==================
* Fix: Consistent placement of ms diff at end of output (#215, @gorangajic)
* Fix: Escaping of regex special characters in namespace strings (#250, @zacronos)
* Fix: Fixed bug causing crash on react-native (#282, @vkarpov15)
* Feature: Enabled ES6+ compatible import via default export (#212 @bucaran)
* Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom)
* Package: Update "ms" to 0.7.2 (#315, @DevSide)
* Package: removed superfluous version property from bower.json (#207 @kkirsche)
* Readme: fix USE_COLORS to DEBUG_COLORS
* Readme: Doc fixes for format string sugar (#269, @mlucool)
* Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0)
* Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable)
* Readme: better docs for browser support (#224, @matthewmueller)
* Tooling: Added yarn integration for development (#317, @thebigredgeek)
* Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek)
* Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman)
* Misc: Updated contributors (@thebigredgeek)
2.2.0 / 2015-05-09
==================
* package: update "ms" to v0.7.1 (#202, @dougwilson)
* README: add logging to file example (#193, @DanielOchoa)
* README: fixed a typo (#191, @amir-s)
* browser: expose `storage` (#190, @stephenmathieson)
* Makefile: add a `distclean` target (#189, @stephenmathieson)
2.1.3 / 2015-03-13
==================
* Updated stdout/stderr example (#186)
* Updated example/stdout.js to match debug current behaviour
* Renamed example/stderr.js to stdout.js
* Update Readme.md (#184)
* replace high intensity foreground color for bold (#182, #183)
2.1.2 / 2015-03-01
==================
* dist: recompile
* update "ms" to v0.7.0
* package: update "browserify" to v9.0.3
* component: fix "ms.js" repo location
* changed bower package name
* updated documentation about using debug in a browser
* fix: security error on safari (#167, #168, @yields)
2.1.1 / 2014-12-29
==================
* browser: use `typeof` to check for `console` existence
* browser: check for `console.log` truthiness (fix IE 8/9)
* browser: add support for Chrome apps
* Readme: added Windows usage remarks
* Add `bower.json` to properly support bower install
2.1.0 / 2014-10-15
==================
* node: implement `DEBUG_FD` env variable support
* package: update "browserify" to v6.1.0
* package: add "license" field to package.json (#135, @panuhorsmalahti)
2.0.0 / 2014-09-01
==================
* package: update "browserify" to v5.11.0
* node: use stderr rather than stdout for logging (#29, @stephenmathieson)
1.0.4 / 2014-07-15
==================
* dist: recompile
* example: remove `console.info()` log usage
* example: add "Content-Type" UTF-8 header to browser example
* browser: place %c marker after the space character
* browser: reset the "content" color via `color: inherit`
* browser: add colors support for Firefox >= v31
* debug: prefer an instance `log()` function over the global one (#119)
* Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
1.0.3 / 2014-07-09
==================
* Add support for multiple wildcards in namespaces (#122, @seegno)
* browser: fix lint
1.0.2 / 2014-06-10
==================
* browser: update color palette (#113, @gscottolson)
* common: make console logging function configurable (#108, @timoxley)
* node: fix %o colors on old node <= 0.8.x
* Makefile: find node path using shell/which (#109, @timoxley)
1.0.1 / 2014-06-06
==================
* browser: use `removeItem()` to clear localStorage
* browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
* package: add "contributors" section
* node: fix comment typo
* README: list authors
1.0.0 / 2014-06-04
==================
* make ms diff be global, not be scope
* debug: ignore empty strings in enable()
* node: make DEBUG_COLORS able to disable coloring
* *: export the `colors` array
* npmignore: don't publish the `dist` dir
* Makefile: refactor to use browserify
* package: add "browserify" as a dev dependency
* Readme: add Web Inspector Colors section
* node: reset terminal color for the debug content
* node: map "%o" to `util.inspect()`
* browser: map "%j" to `JSON.stringify()`
* debug: add custom "formatters"
* debug: use "ms" module for humanizing the diff
* Readme: add "bash" syntax highlighting
* browser: add Firebug color support
* browser: add colors for WebKit browsers
* node: apply log to `console`
* rewrite: abstract common logic for Node & browsers
* add .jshintrc file
0.8.1 / 2014-04-14
==================
* package: re-add the "component" section
0.8.0 / 2014-03-30
==================
* add `enable()` method for nodejs. Closes #27
* change from stderr to stdout
* remove unnecessary index.js file
0.7.4 / 2013-11-13
==================
* remove "browserify" key from package.json (fixes something in browserify)
0.7.3 / 2013-10-30
==================
* fix: catch localStorage security error when cookies are blocked (Chrome)
* add debug(err) support. Closes #46
* add .browser prop to package.json. Closes #42
0.7.2 / 2013-02-06
==================
* fix package.json
* fix: Mobile Safari (private mode) is broken with debug
* fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
0.7.1 / 2013-02-05
==================
* add repository URL to package.json
* add DEBUG_COLORED to force colored output
* add browserify support
* fix component. Closes #24
0.7.0 / 2012-05-04
==================
* Added .component to package.json
* Added debug.component.js build
0.6.0 / 2012-03-16
==================
* Added support for "-" prefix in DEBUG [Vinay Pulim]
* Added `.enabled` flag to the node version [TooTallNate]
0.5.0 / 2012-02-02
==================
* Added: humanize diffs. Closes #8
* Added `debug.disable()` to the CS variant
* Removed padding. Closes #10
* Fixed: persist client-side variant again. Closes #9
0.4.0 / 2012-02-01
==================
* Added browser variant support for older browsers [TooTallNate]
* Added `debug.enable('project:*')` to browser variant [TooTallNate]
* Added padding to diff (moved it to the right)
0.3.0 / 2012-01-26
==================
* Added millisecond diff when isatty, otherwise UTC string
0.2.0 / 2012-01-22
==================
* Added wildcard support
0.1.0 / 2011-12-02
==================
* Added: remove colors unless stderr isatty [TooTallNate]
0.0.1 / 2010-01-03
==================
* Initial release

View File

@@ -0,0 +1,19 @@
(The MIT License)
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
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.

View File

@@ -0,0 +1,52 @@
# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
# BIN directory
BIN := $(THIS_DIR)/node_modules/.bin
# Path
PATH := node_modules/.bin:$(PATH)
SHELL := /bin/bash
# applications
NODE ?= $(shell which node)
YARN ?= $(shell which yarn)
PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
BROWSERIFY ?= $(NODE) $(BIN)/browserify
.FORCE:
all: dist/debug.js
install: node_modules
node_modules: package.json
@NODE_ENV= $(PKG) install
@touch node_modules
lint: .FORCE
eslint browser.js debug.js index.js node.js
test-node: .FORCE
istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
test-browser: .FORCE
mkdir -p dist
@$(BROWSERIFY) \
--standalone debug \
. > dist/debug.js
karma start --single-run
rimraf dist
test: .FORCE
concurrently \
"make test-node" \
"make test-browser"
coveralls:
cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
.PHONY: all install clean distclean

View File

@@ -0,0 +1,238 @@
# debug
[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master)
A tiny node.js debugging utility modelled after node core's debugging technique.
**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
## Installation
```bash
$ npm install debug
```
## Usage
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
Example _app.js_:
```js
var debug = require('debug')('http')
, http = require('http')
, name = 'My App';
// fake app
debug('booting %s', name);
http.createServer(function(req, res){
debug(req.method + ' ' + req.url);
res.end('hello\n');
}).listen(3000, function(){
debug('listening');
});
// fake worker of some kind
require('./worker');
```
Example _worker.js_:
```js
var debug = require('debug')('worker');
setInterval(function(){
debug('doing some work');
}, 1000);
```
The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
#### Windows note
On Windows the environment variable is set using the `set` command.
```cmd
set DEBUG=*,-not_this
```
Note that PowerShell uses different syntax to set environment variables.
```cmd
$env:DEBUG = "*,-not_this"
```
Then, run the program to be debugged as usual.
## Millisecond diff
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
## Conventions
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
## Wildcards
The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
## Environment Variables
When running through Node.js, you can set a few environment variables that will
change the behavior of the debug logging:
| Name | Purpose |
|-----------|-------------------------------------------------|
| `DEBUG` | Enables/disabled specific debugging namespaces. |
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
| `DEBUG_DEPTH` | Object inspection depth. |
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
__Note:__ The environment variables beginning with `DEBUG_` end up being
converted into an Options object that gets used with `%o`/`%O` formatters.
See the Node.js documentation for
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
for the complete list.
## Formatters
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
| Formatter | Representation |
|-----------|----------------|
| `%O` | Pretty-print an Object on multiple lines. |
| `%o` | Pretty-print an Object all on a single line. |
| `%s` | String. |
| `%d` | Number (both integer and float). |
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
| `%%` | Single percent sign ('%'). This does not consume an argument. |
### Custom formatters
You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
```js
const createDebug = require('debug')
createDebug.formatters.h = (v) => {
return v.toString('hex')
}
// …elsewhere
const debug = createDebug('foo')
debug('this is hex: %h', new Buffer('hello world'))
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
```
## Browser support
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
if you don't want to build it yourself.
Debug's enable state is currently persisted by `localStorage`.
Consider the situation shown below where you have `worker:a` and `worker:b`,
and wish to debug both. You can enable this using `localStorage.debug`:
```js
localStorage.debug = 'worker:*'
```
And then refresh the page.
```js
a = debug('worker:a');
b = debug('worker:b');
setInterval(function(){
a('doing some work');
}, 1000);
setInterval(function(){
b('doing some work');
}, 1200);
```
#### Web Inspector Colors
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
option. These are WebKit web inspectors, Firefox ([since version
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
and the Firebug plugin for Firefox (any version).
Colored output looks something like:
![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
## Output streams
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
Example _stdout.js_:
```js
var debug = require('debug');
var error = debug('app:error');
// by default stderr is used
error('goes to stderr!');
var log = debug('app:log');
// set this namespace to log via console.log
log.log = console.log.bind(console); // don't forget to bind to console!
log('goes to stdout');
error('still goes to stderr!');
// set all output to go via console.info
// overrides all per-namespace log settings
debug.log = console.info.bind(console);
error('now goes to stdout via console.info');
log('still goes to stdout, but via console.info now');
```
## Authors
- TJ Holowaychuk
- Nathan Rajlich
- Andrew Rhyne
## License
(The MIT License)
Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
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.

View File

@@ -0,0 +1,29 @@
{
"name": "visionmedia-debug",
"main": "./src/browser.js",
"homepage": "https://github.com/visionmedia/debug",
"authors": [
"TJ Holowaychuk <tj@vision-media.ca>",
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
"Andrew Rhyne <rhyneandrew@gmail.com>"
],
"description": "visionmedia-debug",
"moduleType": [
"amd",
"es6",
"globals",
"node"
],
"keywords": [
"visionmedia",
"debug"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@@ -0,0 +1,19 @@
{
"name": "debug",
"repo": "visionmedia/debug",
"description": "small debugging utility",
"version": "2.6.0",
"keywords": [
"debug",
"log",
"debugger"
],
"main": "src/browser.js",
"scripts": [
"src/browser.js",
"src/debug.js"
],
"dependencies": {
"rauchg/ms.js": "0.7.1"
}
}

View File

@@ -0,0 +1,70 @@
// Karma configuration
// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai', 'sinon'],
// list of files / patterns to load in the browser
files: [
'dist/debug.js',
'test/*spec.js'
],
// list of files to exclude
exclude: [
'src/node.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

View File

@@ -0,0 +1 @@
module.exports = require('./src/node');

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Zeit, Inc.
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.

View File

@@ -0,0 +1,52 @@
# ms
[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
[![Slack Channel](https://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)
Use this package to easily convert various time formats to milliseconds.
## Examples
```js
ms('2 days') // 172800000
ms('1d') // 86400000
ms('10h') // 36000000
ms('2.5 hrs') // 9000000
ms('2h') // 7200000
ms('1m') // 60000
ms('5s') // 5000
ms('1y') // 31557600000
ms('100') // 100
```
### Convert from milliseconds
```js
ms(60000) // "1m"
ms(2 * 60000) // "2m"
ms(ms('10 hours')) // "10h"
```
### Time format written-out
```js
ms(60000, { long: true }) // "1 minute"
ms(2 * 60000, { long: true }) // "2 minutes"
ms(ms('10 hours'), { long: true }) // "10 hours"
```
## Features
- Works both in [node](https://nodejs.org) and in the browser.
- If a number is supplied to `ms`, a string with a unit is returned.
- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).
- If you pass a string with a number and a valid unit, the number of equivalent ms is returned.
## Caught a bug?
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
2. Link the package to the global module directory: `npm link`
3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!
As always, you can run the tests using: `npm test`

View File

@@ -0,0 +1,149 @@
/**
* Helpers.
*/
var s = 1000
var m = s * 60
var h = m * 60
var d = h * 24
var y = d * 365.25
/**
* Parse or format the given `val`.
*
* Options:
*
* - `long` verbose formatting [false]
*
* @param {String|Number} val
* @param {Object} options
* @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number}
* @api public
*/
module.exports = function (val, options) {
options = options || {}
var type = typeof val
if (type === 'string' && val.length > 0) {
return parse(val)
} else if (type === 'number' && isNaN(val) === false) {
return options.long ?
fmtLong(val) :
fmtShort(val)
}
throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val))
}
/**
* Parse the given `str` and return milliseconds.
*
* @param {String} str
* @return {Number}
* @api private
*/
function parse(str) {
str = String(str)
if (str.length > 10000) {
return
}
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str)
if (!match) {
return
}
var n = parseFloat(match[1])
var type = (match[2] || 'ms').toLowerCase()
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y
case 'days':
case 'day':
case 'd':
return n * d
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n
default:
return undefined
}
}
/**
* Short format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtShort(ms) {
if (ms >= d) {
return Math.round(ms / d) + 'd'
}
if (ms >= h) {
return Math.round(ms / h) + 'h'
}
if (ms >= m) {
return Math.round(ms / m) + 'm'
}
if (ms >= s) {
return Math.round(ms / s) + 's'
}
return ms + 'ms'
}
/**
* Long format for `ms`.
*
* @param {Number} ms
* @return {String}
* @api private
*/
function fmtLong(ms) {
return plural(ms, d, 'day') ||
plural(ms, h, 'hour') ||
plural(ms, m, 'minute') ||
plural(ms, s, 'second') ||
ms + ' ms'
}
/**
* Pluralization helper.
*/
function plural(ms, n, name) {
if (ms < n) {
return
}
if (ms < n * 1.5) {
return Math.floor(ms / n) + ' ' + name
}
return Math.ceil(ms / n) + ' ' + name + 's'
}

View File

@@ -0,0 +1,66 @@
{
"_from": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"_id": "ms@0.7.2",
"_inBundle": false,
"_integrity": "sha512-5NnE67nQSQDJHVahPJna1PQ/zCXMnQop3yUCxjKPNzCxuyPSKWTQ/5Gu5CZmjetwGLWRA+PzeF5thlbOdbQldA==",
"_location": "/skills-service-manager/body-parser/debug/ms",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "ms@https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"name": "ms",
"escapedName": "ms",
"rawSpec": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"saveSpec": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"fetchSpec": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser/debug"
],
"_resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"_spec": "ms@https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"bugs": {
"url": "https://github.com/zeit/ms/issues"
},
"bundleDependencies": false,
"component": {
"scripts": {
"ms/index.js": "index.js"
}
},
"deprecated": false,
"description": "Tiny milisecond conversion utility",
"devDependencies": {
"expect.js": "^0.3.1",
"mocha": "^3.0.2",
"serve": "^1.4.0",
"xo": "^0.17.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/zeit/ms#readme",
"license": "MIT",
"main": "./index",
"name": "ms",
"repository": {
"type": "git",
"url": "git+https://github.com/zeit/ms.git"
},
"scripts": {
"test": "xo && mocha test/index.js",
"test-browser": "serve ./test"
},
"version": "0.7.2",
"xo": {
"space": true,
"semicolon": false,
"envs": [
"mocha"
],
"rules": {
"complexity": 0
}
}
}

View File

@@ -0,0 +1,86 @@
{
"_from": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"_id": "debug@2.6.0",
"_inBundle": false,
"_integrity": "sha512-XMYwiKKX0jdij1QRlpYn0O6gks0hW3iYUsx/h/RLPKouDGVeun2wlMYl29C85KBjnv1vw2vj+yti1ziHsXd7cg==",
"_location": "/skills-service-manager/body-parser/debug",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "debug@https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"name": "debug",
"escapedName": "debug",
"rawSpec": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"saveSpec": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"fetchSpec": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser"
],
"_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"_spec": "debug@https://registry.npmjs.org/debug/-/debug-2.6.0.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"browser": "./src/browser.js",
"bugs": {
"url": "https://github.com/visionmedia/debug/issues"
},
"bundleDependencies": false,
"component": {
"scripts": {
"debug/index.js": "browser.js",
"debug/debug.js": "debug.js"
}
},
"contributors": [
{
"name": "Nathan Rajlich",
"email": "nathan@tootallnate.net",
"url": "http://n8.io"
},
{
"name": "Andrew Rhyne",
"email": "rhyneandrew@gmail.com"
}
],
"dependencies": {
"ms": "0.7.2"
},
"deprecated": false,
"description": "small debugging utility",
"devDependencies": {
"browserify": "9.0.3",
"chai": "^3.5.0",
"concurrently": "^3.1.0",
"coveralls": "^2.11.15",
"eslint": "^3.12.1",
"istanbul": "^0.4.5",
"karma": "^1.3.0",
"karma-chai": "^0.1.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sinon": "^1.0.5",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.2.0",
"rimraf": "^2.5.4",
"sinon": "^1.17.6",
"sinon-chai": "^2.8.0"
},
"homepage": "https://github.com/visionmedia/debug#readme",
"keywords": [
"debug",
"log",
"debugger"
],
"license": "MIT",
"main": "./src/index.js",
"name": "debug",
"repository": {
"type": "git",
"url": "git://github.com/visionmedia/debug.git"
},
"version": "2.6.0"
}

View File

@@ -0,0 +1,182 @@
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
/**
* Colors.
*/
exports.colors = [
'lightseagreen',
'forestgreen',
'goldenrod',
'dodgerblue',
'darkorchid',
'crimson'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window && typeof window.process !== 'undefined' && window.process.type === 'renderer') {
return true;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document && 'WebkitAppearance' in document.documentElement.style) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window && window.console && (console.firebug || (console.exception && console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return;
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
try {
return exports.storage.debug;
} catch(e) {}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (typeof process !== 'undefined' && 'env' in process) {
return process.env.DEBUG;
}
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
}

View File

@@ -0,0 +1,199 @@
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = createDebug.debug = createDebug.default = createDebug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');
/**
* The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Map of special "%n" handling functions, for the debug "format" argument.
*
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
*/
exports.formatters = {};
/**
* Previous log timestamp.
*/
var prevTime;
/**
* Select a color.
* @param {String} namespace
* @return {Number}
* @api private
*/
function selectColor(namespace) {
var hash = 0, i;
for (i in namespace) {
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
hash |= 0; // Convert to 32bit integer
}
return exports.colors[Math.abs(hash) % exports.colors.length];
}
/**
* Create a debugger with the given `namespace`.
*
* @param {String} namespace
* @return {Function}
* @api public
*/
function createDebug(namespace) {
function debug() {
// disabled?
if (!debug.enabled) return;
var self = debug;
// set `diff` timestamp
var curr = +new Date();
var ms = curr - (prevTime || curr);
self.diff = ms;
self.prev = prevTime;
self.curr = curr;
prevTime = curr;
// turn the `arguments` into a proper Array
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
args[0] = exports.coerce(args[0]);
if ('string' !== typeof args[0]) {
// anything else let's inspect with %O
args.unshift('%O');
}
// apply any `formatters` transformations
var index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
// if we encounter an escaped % then don't increase the array index
if (match === '%%') return match;
index++;
var formatter = exports.formatters[format];
if ('function' === typeof formatter) {
var val = args[index];
match = formatter.call(self, val);
// now we need to remove `args[index]` since it's inlined in the `format`
args.splice(index, 1);
index--;
}
return match;
});
// apply env-specific formatting (colors, etc.)
exports.formatArgs.call(self, args);
var logFn = debug.log || exports.log || console.log.bind(console);
logFn.apply(self, args);
}
debug.namespace = namespace;
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespace);
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}
return debug;
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} namespaces
* @api public
*/
function enable(namespaces) {
exports.save(namespaces);
var split = (namespaces || '').split(/[\s,]+/);
var len = split.length;
for (var i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
}
/**
* Disable debug output.
*
* @api public
*/
function disable() {
exports.enable('');
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*
* @param {String} name
* @return {Boolean}
* @api public
*/
function enabled(name) {
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false;
}
}
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true;
}
}
return false;
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}

View File

@@ -0,0 +1,10 @@
/**
* Detect Electron renderer process, which is node, but we should
* treat as a browser.
*/
if (typeof process !== 'undefined' && process.type === 'renderer') {
module.exports = require('./browser.js');
} else {
module.exports = require('./node.js');
}

View File

@@ -0,0 +1,240 @@
/**
* Module dependencies.
*/
var tty = require('tty');
var util = require('util');
/**
* This is the Node.js implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
/**
* Colors.
*/
exports.colors = [6, 2, 3, 4, 5, 1];
/**
* Build up the default `inspectOpts` object from the environment variables.
*
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
*/
exports.inspectOpts = Object.keys(process.env).filter(function (key) {
return /^debug_/i.test(key);
}).reduce(function (obj, key) {
// camel-case
var prop = key
.substring(6)
.toLowerCase()
.replace(/_([a-z])/, function (_, k) { return k.toUpperCase() });
// coerce string value into JS value
var val = process.env[key];
if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
else if (val === 'null') val = null;
else val = Number(val);
obj[prop] = val;
return obj;
}, {});
/**
* The file descriptor to write the `debug()` calls to.
* Set the `DEBUG_FD` env variable to override with another value. i.e.:
*
* $ DEBUG_FD=3 node script.js 3>debug.log
*/
if ('DEBUG_FD' in process.env) {
util.deprecate(function(){}, '`DEBUG_FD` is deprecated. Override `debug.log` if you want to use a different log function (https://git.io/vMUyr)')()
}
var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
var stream = 1 === fd ? process.stdout :
2 === fd ? process.stderr :
createWritableStdioStream(fd);
/**
* Is stdout a TTY? Colored output is enabled when `true`.
*/
function useColors() {
return 'colors' in exports.inspectOpts
? Boolean(exports.inspectOpts.colors)
: tty.isatty(fd);
}
/**
* Map %o to `util.inspect()`, all on a single line.
*/
exports.formatters.o = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts)
.replace(/\s*\n\s*/g, ' ');
};
/**
* Map %o to `util.inspect()`, allowing multiple lines if needed.
*/
exports.formatters.O = function(v) {
this.inspectOpts.colors = this.useColors;
return util.inspect(v, this.inspectOpts);
};
/**
* Adds ANSI color escape codes if enabled.
*
* @api public
*/
function formatArgs(args) {
var name = this.namespace;
var useColors = this.useColors;
if (useColors) {
var c = this.color;
var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
} else {
args[0] = new Date().toUTCString()
+ ' ' + name + ' ' + args[0];
}
}
/**
* Invokes `util.format()` with the specified arguments and writes to `stream`.
*/
function log() {
return stream.write(util.format.apply(util, arguments) + '\n');
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
if (null == namespaces) {
// If you set a process.env field to null or undefined, it gets cast to the
// string 'null' or 'undefined'. Just delete instead.
delete process.env.DEBUG;
} else {
process.env.DEBUG = namespaces;
}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
return process.env.DEBUG;
}
/**
* Copied from `node/src/node.js`.
*
* XXX: It's lame that node doesn't expose this API out-of-the-box. It also
* relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
*/
function createWritableStdioStream (fd) {
var stream;
var tty_wrap = process.binding('tty_wrap');
// Note stream._type is used for test-module-load-list.js
switch (tty_wrap.guessHandleType(fd)) {
case 'TTY':
stream = new tty.WriteStream(fd);
stream._type = 'tty';
// Hack to have stream not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
if (stream._handle && stream._handle.unref) {
stream._handle.unref();
}
break;
case 'FILE':
var fs = require('fs');
stream = new fs.SyncWriteStream(fd, { autoClose: false });
stream._type = 'fs';
break;
case 'PIPE':
case 'TCP':
var net = require('net');
stream = new net.Socket({
fd: fd,
readable: false,
writable: true
});
// FIXME Should probably have an option in net.Socket to create a
// stream from an existing fd which is writable only. But for now
// we'll just add this hack and set the `readable` member to false.
// Test: ./node test/fixtures/echo.js < /etc/passwd
stream.readable = false;
stream.read = null;
stream._type = 'pipe';
// FIXME Hack to have stream not keep the event loop alive.
// See https://github.com/joyent/node/issues/1726
if (stream._handle && stream._handle.unref) {
stream._handle.unref();
}
break;
default:
// Probably an error on in uv_guess_handle()
throw new Error('Implement me. Unknown stream file type!');
}
// For supporting legacy API we put the FD here.
stream.fd = fd;
stream._isStdio = true;
return stream;
}
/**
* Init logic for `debug` instances.
*
* Create a new `inspectOpts` object in case `useColors` is set
* differently for a particular `debug` instance.
*/
function init (debug) {
debug.inspectOpts = util._extend({}, exports.inspectOpts);
}
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
exports.enable(load());

View File

@@ -0,0 +1,84 @@
1.1.0 / 2015-09-14
==================
* Enable strict mode in more places
* Support io.js 3.x
* Support io.js 2.x
* Support web browser loading
- Requires bundler like Browserify or webpack
1.0.1 / 2015-04-07
==================
* Fix `TypeError`s when under `'use strict'` code
* Fix useless type name on auto-generated messages
* Support io.js 1.x
* Support Node.js 0.12
1.0.0 / 2014-09-17
==================
* No changes
0.4.5 / 2014-09-09
==================
* Improve call speed to functions using the function wrapper
* Support Node.js 0.6
0.4.4 / 2014-07-27
==================
* Work-around v8 generating empty stack traces
0.4.3 / 2014-07-26
==================
* Fix exception when global `Error.stackTraceLimit` is too low
0.4.2 / 2014-07-19
==================
* Correct call site for wrapped functions and properties
0.4.1 / 2014-07-19
==================
* Improve automatic message generation for function properties
0.4.0 / 2014-07-19
==================
* Add `TRACE_DEPRECATION` environment variable
* Remove non-standard grey color from color output
* Support `--no-deprecation` argument
* Support `--trace-deprecation` argument
* Support `deprecate.property(fn, prop, message)`
0.3.0 / 2014-06-16
==================
* Add `NO_DEPRECATION` environment variable
0.2.0 / 2014-06-15
==================
* Add `deprecate.property(obj, prop, message)`
* Remove `supports-color` dependency for node.js 0.8
0.1.0 / 2014-06-15
==================
* Add `deprecate.function(fn, message)`
* Add `process.on('deprecation', fn)` emitter
* Automatically generate message when omitted from `deprecate()`
0.0.1 / 2014-06-15
==================
* Fix warning for dynamic calls at singe call site
0.0.0 / 2014-06-15
==================
* Initial implementation

View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2015 Douglas Christopher Wilson
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.

View File

@@ -0,0 +1,281 @@
# depd
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Linux Build][travis-image]][travis-url]
[![Windows Build][appveyor-image]][appveyor-url]
[![Coverage Status][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Deprecate all the things
> With great modules comes great responsibility; mark things deprecated!
## Install
This module is installed directly using `npm`:
```sh
$ npm install depd
```
This module can also be bundled with systems like
[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/),
though by default this module will alter it's API to no longer display or
track deprecations.
## API
```js
var deprecate = require('depd')('my-module')
```
This library allows you to display deprecation messages to your users.
This library goes above and beyond with deprecation warnings by
introspection of the call stack (but only the bits that it is interested
in).
Instead of just warning on the first invocation of a deprecated
function and never again, this module will warn on the first invocation
of a deprecated function per unique call site, making it ideal to alert
users of all deprecated uses across the code base, rather than just
whatever happens to execute first.
The deprecation warnings from this module also include the file and line
information for the call into the module that the deprecated function was
in.
**NOTE** this library has a similar interface to the `debug` module, and
this module uses the calling file to get the boundary for the call stacks,
so you should always create a new `deprecate` object in each file and not
within some central file.
### depd(namespace)
Create a new deprecate function that uses the given namespace name in the
messages and will display the call site prior to the stack entering the
file this function was called from. It is highly suggested you use the
name of your module as the namespace.
### deprecate(message)
Call this function from deprecated code to display a deprecation message.
This message will appear once per unique caller site. Caller site is the
first call site in the stack in a different file from the caller of this
function.
If the message is omitted, a message is generated for you based on the site
of the `deprecate()` call and will display the name of the function called,
similar to the name displayed in a stack trace.
### deprecate.function(fn, message)
Call this function to wrap a given function in a deprecation message on any
call to the function. An optional message can be supplied to provide a custom
message.
### deprecate.property(obj, prop, message)
Call this function to wrap a given property on object in a deprecation message
on any accessing or setting of the property. An optional message can be supplied
to provide a custom message.
The method must be called on the object where the property belongs (not
inherited from the prototype).
If the property is a data descriptor, it will be converted to an accessor
descriptor in order to display the deprecation message.
### process.on('deprecation', fn)
This module will allow easy capturing of deprecation errors by emitting the
errors as the type "deprecation" on the global `process`. If there are no
listeners for this type, the errors are written to STDERR as normal, but if
there are any listeners, nothing will be written to STDERR and instead only
emitted. From there, you can write the errors in a different format or to a
logging source.
The error represents the deprecation and is emitted only once with the same
rules as writing to STDERR. The error has the following properties:
- `message` - This is the message given by the library
- `name` - This is always `'DeprecationError'`
- `namespace` - This is the namespace the deprecation came from
- `stack` - This is the stack of the call to the deprecated thing
Example `error.stack` output:
```
DeprecationError: my-cool-module deprecated oldfunction
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:456:26)
at evalScript (node.js:532:25)
at startup (node.js:80:7)
at node.js:902:3
```
### process.env.NO_DEPRECATION
As a user of modules that are deprecated, the environment variable `NO_DEPRECATION`
is provided as a quick solution to silencing deprecation warnings from being
output. The format of this is similar to that of `DEBUG`:
```sh
$ NO_DEPRECATION=my-module,othermod node app.js
```
This will suppress deprecations from being output for "my-module" and "othermod".
The value is a list of comma-separated namespaces. To suppress every warning
across all namespaces, use the value `*` for a namespace.
Providing the argument `--no-deprecation` to the `node` executable will suppress
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not suppress the deperecations given to any "deprecation"
event listeners, just the output to STDERR.
### process.env.TRACE_DEPRECATION
As a user of modules that are deprecated, the environment variable `TRACE_DEPRECATION`
is provided as a solution to getting more detailed location information in deprecation
warnings by including the entire stack trace. The format of this is the same as
`NO_DEPRECATION`:
```sh
$ TRACE_DEPRECATION=my-module,othermod node app.js
```
This will include stack traces for deprecations being output for "my-module" and
"othermod". The value is a list of comma-separated namespaces. To trace every
warning across all namespaces, use the value `*` for a namespace.
Providing the argument `--trace-deprecation` to the `node` executable will trace
all deprecations (only available in Node.js 0.8 or higher).
**NOTE** This will not trace the deperecations silenced by `NO_DEPRECATION`.
## Display
![message](files/message.png)
When a user calls a function in your library that you mark deprecated, they
will see the following written to STDERR (in the given colors, similar colors
and layout to the `debug` module):
```
bright cyan bright yellow
| | reset cyan
| | | |
▼ ▼ ▼ ▼
my-cool-module deprecated oldfunction [eval]-wrapper:6:22
▲ ▲ ▲ ▲
| | | |
namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
If the user redirects their STDERR to a file or somewhere that does not support
colors, they see (similar layout to the `debug` module):
```
Sun, 15 Jun 2014 05:21:37 GMT my-cool-module deprecated oldfunction at [eval]-wrapper:6:22
▲ ▲ ▲ ▲ ▲
| | | | |
timestamp of message namespace | | location of mycoolmod.oldfunction() call
| deprecation message
the word "deprecated"
```
## Examples
### Deprecating all calls to a function
This will display a deprecated message about "oldfunction" being deprecated
from "my-module" on STDERR.
```js
var deprecate = require('depd')('my-cool-module')
// message automatically derived from function name
// Object.oldfunction
exports.oldfunction = deprecate.function(function oldfunction() {
// all calls to function are deprecated
})
// specific message
exports.oldfunction = deprecate.function(function () {
// all calls to function are deprecated
}, 'oldfunction')
```
### Conditionally deprecating a function call
This will display a deprecated message about "weirdfunction" being deprecated
from "my-module" on STDERR when called with less than 2 arguments.
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
}
}
```
When calling `deprecate` as a function, the warning is counted per call site
within your own module, so you can display different deprecations depending
on different situations and the users will still get all the warnings:
```js
var deprecate = require('depd')('my-cool-module')
exports.weirdfunction = function () {
if (arguments.length < 2) {
// calls with 0 or 1 args are deprecated
deprecate('weirdfunction args < 2')
} else if (typeof arguments[0] !== 'string') {
// calls with non-string first argument are deprecated
deprecate('weirdfunction non-string first arg')
}
}
```
### Deprecating property access
This will display a deprecated message about "oldprop" being deprecated
from "my-module" on STDERR when accessed. A deprecation will be displayed
when setting the value and when getting the value.
```js
var deprecate = require('depd')('my-cool-module')
exports.oldprop = 'something'
// message automatically derives from property name
deprecate.property(exports, 'oldprop')
// explicit message
deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
```
## License
[MIT](LICENSE)
[npm-version-image]: https://img.shields.io/npm/v/depd.svg
[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg
[npm-url]: https://npmjs.org/package/depd
[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux
[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg
[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
[node-image]: https://img.shields.io/node/v/depd.svg
[node-url]: http://nodejs.org/download/
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/

View File

@@ -0,0 +1,521 @@
/*!
* depd
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* Module dependencies.
*/
var callSiteToString = require('./lib/compat').callSiteToString
var eventListenerCount = require('./lib/compat').eventListenerCount
var relative = require('path').relative
/**
* Module exports.
*/
module.exports = depd
/**
* Get the path to base files on.
*/
var basePath = process.cwd()
/**
* Determine if namespace is contained in the string.
*/
function containsNamespace(str, namespace) {
var val = str.split(/[ ,]+/)
namespace = String(namespace).toLowerCase()
for (var i = 0 ; i < val.length; i++) {
if (!(str = val[i])) continue;
// namespace contained
if (str === '*' || str.toLowerCase() === namespace) {
return true
}
}
return false
}
/**
* Convert a data descriptor to accessor descriptor.
*/
function convertDataDescriptorToAccessor(obj, prop, message) {
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
var value = descriptor.value
descriptor.get = function getter() { return value }
if (descriptor.writable) {
descriptor.set = function setter(val) { return value = val }
}
delete descriptor.value
delete descriptor.writable
Object.defineProperty(obj, prop, descriptor)
return descriptor
}
/**
* Create arguments string to keep arity.
*/
function createArgumentsString(arity) {
var str = ''
for (var i = 0; i < arity; i++) {
str += ', arg' + i
}
return str.substr(2)
}
/**
* Create stack string from stack.
*/
function createStackString(stack) {
var str = this.name + ': ' + this.namespace
if (this.message) {
str += ' deprecated ' + this.message
}
for (var i = 0; i < stack.length; i++) {
str += '\n at ' + callSiteToString(stack[i])
}
return str
}
/**
* Create deprecate for namespace in caller.
*/
function depd(namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
var stack = getStack()
var site = callSiteLocation(stack[1])
var file = site[0]
function deprecate(message) {
// call to self as log
log.call(deprecate, message)
}
deprecate._file = file
deprecate._ignored = isignored(namespace)
deprecate._namespace = namespace
deprecate._traced = istraced(namespace)
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Determine if namespace is ignored.
*/
function isignored(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.noDeprecation) {
// --no-deprecation support
return true
}
var str = process.env.NO_DEPRECATION || ''
// namespace ignored
return containsNamespace(str, namespace)
}
/**
* Determine if namespace is traced.
*/
function istraced(namespace) {
/* istanbul ignore next: tested in a child processs */
if (process.traceDeprecation) {
// --trace-deprecation support
return true
}
var str = process.env.TRACE_DEPRECATION || ''
// namespace traced
return containsNamespace(str, namespace)
}
/**
* Display deprecation message.
*/
function log(message, site) {
var haslisteners = eventListenerCount(process, 'deprecation') !== 0
// abort early if no destination
if (!haslisteners && this._ignored) {
return
}
var caller
var callFile
var callSite
var i = 0
var seen = false
var stack = getStack()
var file = this._file
if (site) {
// provided site
callSite = callSiteLocation(stack[1])
callSite.name = site.name
file = callSite[0]
} else {
// get call site
i = 2
site = callSiteLocation(stack[i])
callSite = site
}
// get caller of deprecated thing in relation to file
for (; i < stack.length; i++) {
caller = callSiteLocation(stack[i])
callFile = caller[0]
if (callFile === file) {
seen = true
} else if (callFile === this._file) {
file = this._file
} else if (seen) {
break
}
}
var key = caller
? site.join(':') + '__' + caller.join(':')
: undefined
if (key !== undefined && key in this._warned) {
// already warned
return
}
this._warned[key] = true
// generate automatic message from call site
if (!message) {
message = callSite === site || !callSite.name
? defaultMessage(site)
: defaultMessage(callSite)
}
// emit deprecation if listeners exist
if (haslisteners) {
var err = DeprecationError(this._namespace, message, stack.slice(i))
process.emit('deprecation', err)
return
}
// format and write message
var format = process.stderr.isTTY
? formatColor
: formatPlain
var msg = format.call(this, message, caller, stack.slice(i))
process.stderr.write(msg + '\n', 'utf8')
return
}
/**
* Get call site location as array.
*/
function callSiteLocation(callSite) {
var file = callSite.getFileName() || '<anonymous>'
var line = callSite.getLineNumber()
var colm = callSite.getColumnNumber()
if (callSite.isEval()) {
file = callSite.getEvalOrigin() + ', ' + file
}
var site = [file, line, colm]
site.callSite = callSite
site.name = callSite.getFunctionName()
return site
}
/**
* Generate a default message from the site.
*/
function defaultMessage(site) {
var callSite = site.callSite
var funcName = site.name
// make useful anonymous name
if (!funcName) {
funcName = '<anonymous@' + formatLocation(site) + '>'
}
var context = callSite.getThis()
var typeName = context && callSite.getTypeName()
// ignore useless type name
if (typeName === 'Object') {
typeName = undefined
}
// make useful type name
if (typeName === 'Function') {
typeName = context.name || typeName
}
return typeName && callSite.getMethodName()
? typeName + '.' + funcName
: funcName
}
/**
* Format deprecation message without color.
*/
function formatPlain(msg, caller, stack) {
var timestamp = new Date().toUTCString()
var formatted = timestamp
+ ' ' + this._namespace
+ ' deprecated ' + msg
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n at ' + callSiteToString(stack[i])
}
return formatted
}
if (caller) {
formatted += ' at ' + formatLocation(caller)
}
return formatted
}
/**
* Format deprecation message with color.
*/
function formatColor(msg, caller, stack) {
var formatted = '\x1b[36;1m' + this._namespace + '\x1b[22;39m' // bold cyan
+ ' \x1b[33;1mdeprecated\x1b[22;39m' // bold yellow
+ ' \x1b[0m' + msg + '\x1b[39m' // reset
// add stack trace
if (this._traced) {
for (var i = 0; i < stack.length; i++) {
formatted += '\n \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
}
return formatted
}
if (caller) {
formatted += ' \x1b[36m' + formatLocation(caller) + '\x1b[39m' // cyan
}
return formatted
}
/**
* Format call site location.
*/
function formatLocation(callSite) {
return relative(basePath, callSite[0])
+ ':' + callSite[1]
+ ':' + callSite[2]
}
/**
* Get the stack as array of call sites.
*/
function getStack() {
var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
Error.prepareStackTrace = prepareObjectStackTrace
Error.stackTraceLimit = Math.max(10, limit)
// capture the stack
Error.captureStackTrace(obj)
// slice this function off the top
var stack = obj.stack.slice(1)
Error.prepareStackTrace = prep
Error.stackTraceLimit = limit
return stack
}
/**
* Capture call site stack from v8.
*/
function prepareObjectStackTrace(obj, stack) {
return stack
}
/**
* Return a wrapped function in a deprecation message.
*/
function wrapfunction(fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
var args = createArgumentsString(fn.length)
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
site.name = fn.name
var deprecatedfn = eval('(function (' + args + ') {\n'
+ '"use strict"\n'
+ 'log.call(deprecate, message, site)\n'
+ 'return fn.apply(this, arguments)\n'
+ '})')
return deprecatedfn
}
/**
* Wrap property in a deprecation message.
*/
function wrapproperty(obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
var deprecate = this
var stack = getStack()
var site = callSiteLocation(stack[1])
// set site name
site.name = prop
// convert data descriptor
if ('value' in descriptor) {
descriptor = convertDataDescriptorToAccessor(obj, prop, message)
}
var get = descriptor.get
var set = descriptor.set
// wrap getter
if (typeof get === 'function') {
descriptor.get = function getter() {
log.call(deprecate, message, site)
return get.apply(this, arguments)
}
}
// wrap setter
if (typeof set === 'function') {
descriptor.set = function setter() {
log.call(deprecate, message, site)
return set.apply(this, arguments)
}
}
Object.defineProperty(obj, prop, descriptor)
}
/**
* Create DeprecationError for deprecation
*/
function DeprecationError(namespace, message, stack) {
var error = new Error()
var stackString
Object.defineProperty(error, 'constructor', {
value: DeprecationError
})
Object.defineProperty(error, 'message', {
configurable: true,
enumerable: false,
value: message,
writable: true
})
Object.defineProperty(error, 'name', {
enumerable: false,
configurable: true,
value: 'DeprecationError',
writable: true
})
Object.defineProperty(error, 'namespace', {
configurable: true,
enumerable: false,
value: namespace,
writable: true
})
Object.defineProperty(error, 'stack', {
configurable: true,
enumerable: false,
get: function () {
if (stackString !== undefined) {
return stackString
}
// prepare stack trace
return stackString = createStackString.call(this, stack)
},
set: function setter(val) {
stackString = val
}
})
return error
}

View File

@@ -0,0 +1,79 @@
/*!
* depd
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = depd
/**
* Create deprecate for namespace in caller.
*/
function depd(namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}
function deprecate(message) {
// no-op in browser
}
deprecate._file = undefined
deprecate._ignored = true
deprecate._namespace = namespace
deprecate._traced = false
deprecate._warned = Object.create(null)
deprecate.function = wrapfunction
deprecate.property = wrapproperty
return deprecate
}
/**
* Return a wrapped function in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/
function wrapfunction(fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}
return fn
}
/**
* Wrap property in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/
function wrapproperty(obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}
var descriptor = Object.getOwnPropertyDescriptor(obj, prop)
if (!descriptor) {
throw new TypeError('must call property on owner object')
}
if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}
return
}

View File

@@ -0,0 +1,35 @@
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
*/
module.exports = bufferConcat
/**
* Concatenate an array of Buffers.
*/
function bufferConcat(bufs) {
var length = 0
for (var i = 0, len = bufs.length; i < len; i++) {
length += bufs[i].length
}
var buf = new Buffer(length)
var pos = 0
for (var i = 0, len = bufs.length; i < len; i++) {
bufs[i].copy(buf, pos)
pos += bufs[i].length
}
return buf
}

View File

@@ -0,0 +1,103 @@
/*!
* depd
* Copyright(c) 2014 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
*/
module.exports = callSiteToString
/**
* Format a CallSite file location to a string.
*/
function callSiteFileLocation(callSite) {
var fileName
var fileLocation = ''
if (callSite.isNative()) {
fileLocation = 'native'
} else if (callSite.isEval()) {
fileName = callSite.getScriptNameOrSourceURL()
if (!fileName) {
fileLocation = callSite.getEvalOrigin()
}
} else {
fileName = callSite.getFileName()
}
if (fileName) {
fileLocation += fileName
var lineNumber = callSite.getLineNumber()
if (lineNumber != null) {
fileLocation += ':' + lineNumber
var columnNumber = callSite.getColumnNumber()
if (columnNumber) {
fileLocation += ':' + columnNumber
}
}
}
return fileLocation || 'unknown source'
}
/**
* Format a CallSite to a string.
*/
function callSiteToString(callSite) {
var addSuffix = true
var fileLocation = callSiteFileLocation(callSite)
var functionName = callSite.getFunctionName()
var isConstructor = callSite.isConstructor()
var isMethodCall = !(callSite.isToplevel() || isConstructor)
var line = ''
if (isMethodCall) {
var methodName = callSite.getMethodName()
var typeName = getConstructorName(callSite)
if (functionName) {
if (typeName && functionName.indexOf(typeName) !== 0) {
line += typeName + '.'
}
line += functionName
if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) {
line += ' [as ' + methodName + ']'
}
} else {
line += typeName + '.' + (methodName || '<anonymous>')
}
} else if (isConstructor) {
line += 'new ' + (functionName || '<anonymous>')
} else if (functionName) {
line += functionName
} else {
addSuffix = false
line += fileLocation
}
if (addSuffix) {
line += ' (' + fileLocation + ')'
}
return line
}
/**
* Get constructor name of reviver.
*/
function getConstructorName(obj) {
var receiver = obj.receiver
return (receiver.constructor && receiver.constructor.name) || null
}

View File

@@ -0,0 +1,22 @@
/*!
* depd
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = eventListenerCount
/**
* Get the count of listeners on an event emitter of a specific type.
*/
function eventListenerCount(emitter, type) {
return emitter.listeners(type).length
}

View File

@@ -0,0 +1,84 @@
/*!
* depd
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var Buffer = require('buffer')
var EventEmitter = require('events').EventEmitter
/**
* Module exports.
* @public
*/
lazyProperty(module.exports, 'bufferConcat', function bufferConcat() {
return Buffer.concat || require('./buffer-concat')
})
lazyProperty(module.exports, 'callSiteToString', function callSiteToString() {
var limit = Error.stackTraceLimit
var obj = {}
var prep = Error.prepareStackTrace
function prepareObjectStackTrace(obj, stack) {
return stack
}
Error.prepareStackTrace = prepareObjectStackTrace
Error.stackTraceLimit = 2
// capture the stack
Error.captureStackTrace(obj)
// slice the stack
var stack = obj.stack.slice()
Error.prepareStackTrace = prep
Error.stackTraceLimit = limit
return stack[0].toString ? toString : require('./callsite-tostring')
})
lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount() {
return EventEmitter.listenerCount || require('./event-listener-count')
})
/**
* Define a lazy property.
*/
function lazyProperty(obj, prop, getter) {
function get() {
var val = getter()
Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
value: val
})
return val
}
Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
get: get
})
}
/**
* Call toString() on the obj
*/
function toString(obj) {
return obj.toString()
}

View File

@@ -0,0 +1,68 @@
{
"_from": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"_id": "depd@1.1.0",
"_inBundle": false,
"_integrity": "sha512-SN03SKT2SwhaAKUnRJ47Scnys7ZL2FuogA/6s9u5+58RAyqhsI2HBDZymMB0omazkYVBAwBHW9ONcjd4iZ8hDQ==",
"_location": "/skills-service-manager/body-parser/depd",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "depd@https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"name": "depd",
"escapedName": "depd",
"rawSpec": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"saveSpec": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"fetchSpec": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser"
],
"_resolved": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"_spec": "depd@https://registry.npmjs.org/depd/-/depd-1.1.0.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
"browser": "lib/browser/index.js",
"bugs": {
"url": "https://github.com/dougwilson/nodejs-depd/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Deprecate all the things",
"devDependencies": {
"beautify-benchmark": "0.2.4",
"benchmark": "1.0.0",
"istanbul": "0.3.5",
"mocha": "~1.21.5"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"lib/",
"History.md",
"LICENSE",
"index.js",
"Readme.md"
],
"homepage": "https://github.com/dougwilson/nodejs-depd#readme",
"keywords": [
"deprecate",
"deprecated"
],
"license": "MIT",
"name": "depd",
"repository": {
"type": "git",
"url": "git+https://github.com/dougwilson/nodejs-depd.git"
},
"scripts": {
"bench": "node benchmark/index.js",
"test": "mocha --reporter spec --bail test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/"
},
"version": "1.1.0"
}

View File

@@ -0,0 +1,103 @@
2016-11-16 / 1.5.1
==================
* deps: inherits@2.0.3
- Fix issue loading in browser
* deps: setprototypeof@1.0.2
* deps: statuses@'>= 1.3.1 < 2'
2016-05-18 / 1.5.0
==================
* Support new code `421 Misdirected Request`
* Use `setprototypeof` module to replace `__proto__` setting
* deps: statuses@'>= 1.3.0 < 2'
- Add `421 Misdirected Request`
- perf: enable strict mode
* perf: enable strict mode
2016-01-28 / 1.4.0
==================
* Add `HttpError` export, for `err instanceof createError.HttpError`
* deps: inherits@2.0.1
* deps: statuses@'>= 1.2.1 < 2'
- Fix message for status 451
- Remove incorrect nginx status code
2015-02-02 / 1.3.1
==================
* Fix regression where status can be overwritten in `createError` `props`
2015-02-01 / 1.3.0
==================
* Construct errors using defined constructors from `createError`
* Fix error names that are not identifiers
- `createError["I'mateapot"]` is now `createError.ImATeapot`
* Set a meaningful `name` property on constructed errors
2014-12-09 / 1.2.8
==================
* Fix stack trace from exported function
* Remove `arguments.callee` usage
2014-10-14 / 1.2.7
==================
* Remove duplicate line
2014-10-02 / 1.2.6
==================
* Fix `expose` to be `true` for `ClientError` constructor
2014-09-28 / 1.2.5
==================
* deps: statuses@1
2014-09-21 / 1.2.4
==================
* Fix dependency version to work with old `npm`s
2014-09-21 / 1.2.3
==================
* deps: statuses@~1.1.0
2014-09-21 / 1.2.2
==================
* Fix publish error
2014-09-21 / 1.2.1
==================
* Support Node.js 0.6
* Use `inherits` instead of `util`
2014-09-09 / 1.2.0
==================
* Fix the way inheriting functions
* Support `expose` being provided in properties argument
2014-09-08 / 1.1.0
==================
* Default status to 500
* Support provided `error` to extend
2014-09-08 / 1.0.1
==================
* Fix accepting string message
2014-09-08 / 1.0.0
==================
* Initial release

View File

@@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong me@jongleberry.com
Copyright (c) 2016 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.

View File

@@ -0,0 +1,132 @@
# http-errors
[![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]
Create HTTP errors for Express, Koa, Connect, etc. with ease.
## Install
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```bash
$ npm install http-errors
```
## Example
```js
var createError = require('http-errors')
var express = require('express')
var app = express()
app.use(function (req, res, next) {
if (!req.user) return next(createError(401, 'Please login to view this page.'))
next()
})
```
## API
This is the current API, currently extracted from Koa and subject to change.
All errors inherit from JavaScript `Error` and the exported `createError.HttpError`.
### Error Properties
- `expose` - can be used to signal if `message` should be sent to the client,
defaulting to `false` when `status` >= 500
- `headers` - can be an object of header names to values to be sent to the
client, defaulting to `undefined`. When defined, the key names should all
be lower-cased
- `message`
- `status` and `statusCode` - the status code of the error, defaulting to `500`
### createError([status], [message], [properties])
<!-- eslint-disable no-undef, no-unused-vars -->
```js
var err = createError(404, 'This video does not exist!')
```
- `status: 500` - the status code as a number
- `message` - the message of the error, defaulting to node's text for that status code.
- `properties` - custom properties to attach to the object
### new createError\[code || name\](\[msg]\))
<!-- eslint-disable no-undef, no-unused-vars -->
```js
var err = new createError.NotFound()
```
- `code` - the status code as a number
- `name` - the name of the error as a "bumpy case", i.e. `NotFound` or `InternalServerError`.
#### List of all constructors
|Status Code|Constructor Name |
|-----------|-----------------------------|
|400 |BadRequest |
|401 |Unauthorized |
|402 |PaymentRequired |
|403 |Forbidden |
|404 |NotFound |
|405 |MethodNotAllowed |
|406 |NotAcceptable |
|407 |ProxyAuthenticationRequired |
|408 |RequestTimeout |
|409 |Conflict |
|410 |Gone |
|411 |LengthRequired |
|412 |PreconditionFailed |
|413 |PayloadTooLarge |
|414 |URITooLong |
|415 |UnsupportedMediaType |
|416 |RangeNotSatisfiable |
|417 |ExpectationFailed |
|418 |ImATeapot |
|421 |MisdirectedRequest |
|422 |UnprocessableEntity |
|423 |Locked |
|424 |FailedDependency |
|425 |UnorderedCollection |
|426 |UpgradeRequired |
|428 |PreconditionRequired |
|429 |TooManyRequests |
|431 |RequestHeaderFieldsTooLarge |
|451 |UnavailableForLegalReasons |
|500 |InternalServerError |
|501 |NotImplemented |
|502 |BadGateway |
|503 |ServiceUnavailable |
|504 |GatewayTimeout |
|505 |HTTPVersionNotSupported |
|506 |VariantAlsoNegotiates |
|507 |InsufficientStorage |
|508 |LoopDetected |
|509 |BandwidthLimitExceeded |
|510 |NotExtended |
|511 |NetworkAuthenticationRequired|
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/http-errors.svg
[npm-url]: https://npmjs.org/package/http-errors
[node-version-image]: https://img.shields.io/node/v/http-errors.svg
[node-version-url]: https://nodejs.org/en/download/
[travis-image]: https://img.shields.io/travis/jshttp/http-errors.svg
[travis-url]: https://travis-ci.org/jshttp/http-errors
[coveralls-image]: https://img.shields.io/coveralls/jshttp/http-errors.svg
[coveralls-url]: https://coveralls.io/r/jshttp/http-errors
[downloads-image]: https://img.shields.io/npm/dm/http-errors.svg
[downloads-url]: https://npmjs.org/package/http-errors

View File

@@ -0,0 +1,223 @@
/*!
* http-errors
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var setPrototypeOf = require('setprototypeof')
var statuses = require('statuses')
var inherits = require('inherits')
/**
* Module exports.
* @public
*/
module.exports = createError
module.exports.HttpError = createHttpErrorConstructor()
// Populate exports for all constructors
populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
/**
* Create a new HTTP Error.
*
* @returns {Error}
* @public
*/
function createError () {
// so much arity going on ~_~
var err
var msg
var status = 500
var props = {}
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]
if (arg instanceof Error) {
err = arg
status = err.status || err.statusCode || status
continue
}
switch (typeof arg) {
case 'string':
msg = arg
break
case 'number':
status = arg
break
case 'object':
props = arg
break
}
}
if (typeof status !== 'number' || !statuses[status]) {
status = 500
}
// constructor
var HttpError = createError[status]
if (!err) {
// create error
err = HttpError
? new HttpError(msg)
: new Error(msg || statuses[status])
Error.captureStackTrace(err, createError)
}
if (!HttpError || !(err instanceof HttpError)) {
// add properties to generic error
err.expose = status < 500
err.status = err.statusCode = status
}
for (var key in props) {
if (key !== 'status' && key !== 'statusCode') {
err[key] = props[key]
}
}
return err
}
/**
* Create HTTP error abstract base class.
* @private
*/
function createHttpErrorConstructor () {
function HttpError () {
throw new TypeError('cannot construct abstract class')
}
inherits(HttpError, Error)
return HttpError
}
/**
* Create a constructor for a client error.
* @private
*/
function createClientErrorConstructor (HttpError, name, code) {
var className = name.match(/Error$/) ? name : name + 'Error'
function ClientError (message) {
// create the error object
var err = new Error(message != null ? message : statuses[code])
// capture a stack trace to the construction point
Error.captureStackTrace(err, ClientError)
// adjust the [[Prototype]]
setPrototypeOf(err, ClientError.prototype)
// redefine the error name
Object.defineProperty(err, 'name', {
enumerable: false,
configurable: true,
value: className,
writable: true
})
return err
}
inherits(ClientError, HttpError)
ClientError.prototype.status = code
ClientError.prototype.statusCode = code
ClientError.prototype.expose = true
return ClientError
}
/**
* Create a constructor for a server error.
* @private
*/
function createServerErrorConstructor (HttpError, name, code) {
var className = name.match(/Error$/) ? name : name + 'Error'
function ServerError (message) {
// create the error object
var err = new Error(message != null ? message : statuses[code])
// capture a stack trace to the construction point
Error.captureStackTrace(err, ServerError)
// adjust the [[Prototype]]
setPrototypeOf(err, ServerError.prototype)
// redefine the error name
Object.defineProperty(err, 'name', {
enumerable: false,
configurable: true,
value: className,
writable: true
})
return err
}
inherits(ServerError, HttpError)
ServerError.prototype.status = code
ServerError.prototype.statusCode = code
ServerError.prototype.expose = false
return ServerError
}
/**
* Populate the exports object with constructors for every error class.
* @private
*/
function populateConstructorExports (exports, codes, HttpError) {
codes.forEach(function forEachCode (code) {
var CodeError
var name = toIdentifier(statuses[code])
switch (String(code).charAt(0)) {
case '4':
CodeError = createClientErrorConstructor(HttpError, name, code)
break
case '5':
CodeError = createServerErrorConstructor(HttpError, name, code)
break
}
if (CodeError) {
// export the constructor
exports[code] = CodeError
exports[name] = CodeError
}
})
// backwards-compatibility
exports["I'mateapot"] = exports.ImATeapot
}
/**
* Convert a string of words to a JavaScript identifier.
* @private
*/
function toIdentifier (str) {
return str.split(' ').map(function (token) {
return token.slice(0, 1).toUpperCase() + token.slice(1)
}).join('').replace(/[^ _0-9a-z]/gi, '')
}

View File

@@ -0,0 +1,16 @@
The ISC License
Copyright (c) Isaac Z. Schlueter
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.

View File

@@ -0,0 +1,42 @@
Browser-friendly inheritance fully compatible with standard node.js
[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).
This package exports standard `inherits` from node.js `util` module in
node environment, but also provides alternative browser-friendly
implementation through [browser
field](https://gist.github.com/shtylman/4339901). Alternative
implementation is a literal copy of standard one located in standalone
module to avoid requiring of `util`. It also has a shim for old
browsers with no `Object.create` support.
While keeping you sure you are using standard `inherits`
implementation in node.js environment, it allows bundlers such as
[browserify](https://github.com/substack/node-browserify) to not
include full `util` package to your client code if all you need is
just `inherits` function. It worth, because browser shim for `util`
package is large and `inherits` is often the single function you need
from it.
It's recommended to use this package instead of
`require('util').inherits` for any code that has chances to be used
not only in node.js but in browser too.
## usage
```js
var inherits = require('inherits');
// then use exactly as the standard one
```
## note on version ~1.0
Version ~1.0 had completely different motivation and is not compatible
neither with 2.0 nor with standard node.js `inherits`.
If you are using version ~1.0 and planning to switch to ~2.0, be
careful:
* new version uses `super_` instead of `super` for referencing
superclass
* new version overwrites current prototype while old one preserves any
existing fields on it

View File

@@ -0,0 +1,7 @@
try {
var util = require('util');
if (typeof util.inherits !== 'function') throw '';
module.exports = util.inherits;
} catch (e) {
module.exports = require('./inherits_browser.js');
}

View File

@@ -0,0 +1,23 @@
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}

View File

@@ -0,0 +1,59 @@
{
"_from": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"_id": "inherits@2.0.3",
"_inBundle": false,
"_integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
"_location": "/skills-service-manager/body-parser/http-errors/inherits",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "inherits@https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"name": "inherits",
"escapedName": "inherits",
"rawSpec": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"saveSpec": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"fetchSpec": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser/http-errors"
],
"_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"_spec": "inherits@https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"browser": "./inherits_browser.js",
"bugs": {
"url": "https://github.com/isaacs/inherits/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
"devDependencies": {
"tap": "^7.1.0"
},
"files": [
"inherits.js",
"inherits_browser.js"
],
"homepage": "https://github.com/isaacs/inherits#readme",
"keywords": [
"inheritance",
"class",
"klass",
"oop",
"object-oriented",
"inherits",
"browser",
"browserify"
],
"license": "ISC",
"main": "./inherits.js",
"name": "inherits",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/inherits.git"
},
"scripts": {
"test": "node test"
},
"version": "2.0.3"
}

View File

@@ -0,0 +1,13 @@
Copyright (c) 2015, Wes Todd
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.

View File

@@ -0,0 +1,21 @@
# Polyfill for `Object.setPrototypeOf`
A simple cross platform implementation to set the prototype of an instianted object. Supports all modern browsers and at least back to IE8.
## Usage:
```
$ npm install --save setprototypeof
```
```javascript
var setPrototypeOf = require('setprototypeof');
var obj = {};
setPrototypeOf(obj, {
foo: function() {
return 'bar';
}
});
obj.foo(); // bar
```

View File

@@ -0,0 +1,13 @@
module.exports = Object.setPrototypeOf || ({__proto__:[]} instanceof Array ? setProtoOf : mixinProperties);
function setProtoOf(obj, proto) {
obj.__proto__ = proto;
return obj;
}
function mixinProperties(obj, proto) {
for (var prop in proto) {
obj[prop] = proto[prop];
}
return obj;
}

View File

@@ -0,0 +1,49 @@
{
"_from": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"_id": "setprototypeof@1.0.2",
"_inBundle": false,
"_integrity": "sha512-mNRSo7UFE4c4tjxlZ3KxO5r+3oQUD1M/KXbp/XTwTwybL4VR9T8Ltmv5DvZX8iRz6C3hQmQftXEV0EmTKRV6mg==",
"_location": "/skills-service-manager/body-parser/http-errors/setprototypeof",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "setprototypeof@https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"name": "setprototypeof",
"escapedName": "setprototypeof",
"rawSpec": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"saveSpec": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"fetchSpec": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser/http-errors"
],
"_resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"_spec": "setprototypeof@https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.2.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "Wes Todd"
},
"bugs": {
"url": "https://github.com/wesleytodd/setprototypeof/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "A small polyfill for Object.setprototypeof",
"homepage": "https://github.com/wesleytodd/setprototypeof",
"keywords": [
"polyfill",
"object",
"setprototypeof"
],
"license": "ISC",
"main": "index.js",
"name": "setprototypeof",
"repository": {
"type": "git",
"url": "git+https://github.com/wesleytodd/setprototypeof.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.0.2"
}

View File

@@ -0,0 +1,55 @@
1.3.1 / 2016-11-11
==================
* Fix return type in JSDoc
1.3.0 / 2016-05-17
==================
* Add `421 Misdirected Request`
* perf: enable strict mode
1.2.1 / 2015-02-01
==================
* Fix message for status 451
- `451 Unavailable For Legal Reasons`
1.2.0 / 2014-09-28
==================
* Add `208 Already Repored`
* Add `226 IM Used`
* Add `306 (Unused)`
* Add `415 Unable For Legal Reasons`
* Add `508 Loop Detected`
1.1.1 / 2014-09-24
==================
* Add missing 308 to `codes.json`
1.1.0 / 2014-09-21
==================
* Add `codes.json` for universal support
1.0.4 / 2014-08-20
==================
* Package cleanup
1.0.3 / 2014-06-08
==================
* Add 308 to `.redirect` category
1.0.2 / 2014-03-13
==================
* Add `.retry` category
1.0.1 / 2014-03-12
==================
* Initial release

View File

@@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2014 Jonathan Ong me@jongleberry.com
Copyright (c) 2016 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.

View File

@@ -0,0 +1,103 @@
# Statuses
[![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]
HTTP status utility for node.
## API
```js
var status = require('statuses')
```
### var code = status(Integer || String)
If `Integer` or `String` is a valid HTTP code or status message, then the appropriate `code` will be returned. Otherwise, an error will be thrown.
```js
status(403) // => 403
status('403') // => 403
status('forbidden') // => 403
status('Forbidden') // => 403
status(306) // throws, as it's not supported by node.js
```
### status.codes
Returns an array of all the status codes as `Integer`s.
### var msg = status[code]
Map of `code` to `status message`. `undefined` for invalid `code`s.
```js
status[404] // => 'Not Found'
```
### var code = status[msg]
Map of `status message` to `code`. `msg` can either be title-cased or lower-cased. `undefined` for invalid `status message`s.
```js
status['not found'] // => 404
status['Not Found'] // => 404
```
### status.redirect[code]
Returns `true` if a status code is a valid redirect status.
```js
status.redirect[200] // => undefined
status.redirect[301] // => true
```
### status.empty[code]
Returns `true` if a status code expects an empty body.
```js
status.empty[200] // => undefined
status.empty[204] // => true
status.empty[304] // => true
```
### status.retry[code]
Returns `true` if you should retry the rest.
```js
status.retry[501] // => undefined
status.retry[503] // => true
```
## Adding Status Codes
The status codes are primarily sourced from http://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv.
Additionally, custom codes are added from http://en.wikipedia.org/wiki/List_of_HTTP_status_codes.
These are added manually in the `lib/*.json` files.
If you would like to add a status code, add it to the appropriate JSON file.
To rebuild `codes.json`, run the following:
```bash
# update src/iana.json
npm run fetch
# build codes.json
npm run build
```
[npm-image]: https://img.shields.io/npm/v/statuses.svg
[npm-url]: https://npmjs.org/package/statuses
[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg
[node-version-url]: https://nodejs.org/en/download
[travis-image]: https://img.shields.io/travis/jshttp/statuses.svg
[travis-url]: https://travis-ci.org/jshttp/statuses
[coveralls-image]: https://img.shields.io/coveralls/jshttp/statuses.svg
[coveralls-url]: https://coveralls.io/r/jshttp/statuses?branch=master
[downloads-image]: https://img.shields.io/npm/dm/statuses.svg
[downloads-url]: https://npmjs.org/package/statuses

View File

@@ -0,0 +1,65 @@
{
"100": "Continue",
"101": "Switching Protocols",
"102": "Processing",
"200": "OK",
"201": "Created",
"202": "Accepted",
"203": "Non-Authoritative Information",
"204": "No Content",
"205": "Reset Content",
"206": "Partial Content",
"207": "Multi-Status",
"208": "Already Reported",
"226": "IM Used",
"300": "Multiple Choices",
"301": "Moved Permanently",
"302": "Found",
"303": "See Other",
"304": "Not Modified",
"305": "Use Proxy",
"306": "(Unused)",
"307": "Temporary Redirect",
"308": "Permanent Redirect",
"400": "Bad Request",
"401": "Unauthorized",
"402": "Payment Required",
"403": "Forbidden",
"404": "Not Found",
"405": "Method Not Allowed",
"406": "Not Acceptable",
"407": "Proxy Authentication Required",
"408": "Request Timeout",
"409": "Conflict",
"410": "Gone",
"411": "Length Required",
"412": "Precondition Failed",
"413": "Payload Too Large",
"414": "URI Too Long",
"415": "Unsupported Media Type",
"416": "Range Not Satisfiable",
"417": "Expectation Failed",
"418": "I'm a teapot",
"421": "Misdirected Request",
"422": "Unprocessable Entity",
"423": "Locked",
"424": "Failed Dependency",
"425": "Unordered Collection",
"426": "Upgrade Required",
"428": "Precondition Required",
"429": "Too Many Requests",
"431": "Request Header Fields Too Large",
"451": "Unavailable For Legal Reasons",
"500": "Internal Server Error",
"501": "Not Implemented",
"502": "Bad Gateway",
"503": "Service Unavailable",
"504": "Gateway Timeout",
"505": "HTTP Version Not Supported",
"506": "Variant Also Negotiates",
"507": "Insufficient Storage",
"508": "Loop Detected",
"509": "Bandwidth Limit Exceeded",
"510": "Not Extended",
"511": "Network Authentication Required"
}

View File

@@ -0,0 +1,110 @@
/*!
* statuses
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2016 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var codes = require('./codes.json')
/**
* Module exports.
* @public
*/
module.exports = status
// array of status codes
status.codes = populateStatusesMap(status, codes)
// status codes for redirects
status.redirect = {
300: true,
301: true,
302: true,
303: true,
305: true,
307: true,
308: true
}
// status codes for empty bodies
status.empty = {
204: true,
205: true,
304: true
}
// status codes for when you should retry the request
status.retry = {
502: true,
503: true,
504: true
}
/**
* Populate the statuses map for given codes.
* @private
*/
function populateStatusesMap (statuses, codes) {
var arr = []
Object.keys(codes).forEach(function forEachCode (code) {
var message = codes[code]
var status = Number(code)
// Populate properties
statuses[status] = message
statuses[message] = status
statuses[message.toLowerCase()] = status
// Add to array
arr.push(status)
})
return arr
}
/**
* Get the status code.
*
* Given a number, this will throw if it is not a known status
* code, otherwise the code will be returned. Given a string,
* the string will be parsed for a number and return the code
* if valid, otherwise will lookup the code assuming this is
* the status message.
*
* @param {string|number} code
* @returns {number}
* @public
*/
function status (code) {
if (typeof code === 'number') {
if (!status[code]) throw new Error('invalid status code: ' + code)
return code
}
if (typeof code !== 'string') {
throw new TypeError('code must be a number or string')
}
// '403'
var n = parseInt(code, 10)
if (!isNaN(n)) {
if (!status[n]) throw new Error('invalid status code: ' + n)
return n
}
n = status[code.toLowerCase()]
if (!n) throw new Error('invalid status message: "' + code + '"')
return n
}

View File

@@ -0,0 +1,81 @@
{
"_from": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"_id": "statuses@1.3.1",
"_inBundle": false,
"_integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==",
"_location": "/skills-service-manager/body-parser/http-errors/statuses",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "statuses@https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"name": "statuses",
"escapedName": "statuses",
"rawSpec": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"saveSpec": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"fetchSpec": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser/http-errors"
],
"_resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"_spec": "statuses@https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"bugs": {
"url": "https://github.com/jshttp/statuses/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
{
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
}
],
"deprecated": false,
"description": "HTTP status utility",
"devDependencies": {
"csv-parse": "1.1.7",
"eslint": "3.10.0",
"eslint-config-standard": "6.2.1",
"eslint-plugin-promise": "3.3.2",
"eslint-plugin-standard": "2.0.1",
"istanbul": "0.4.5",
"mocha": "1.21.5",
"stream-to-array": "2.3.0"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"HISTORY.md",
"index.js",
"codes.json",
"LICENSE"
],
"homepage": "https://github.com/jshttp/statuses#readme",
"keywords": [
"http",
"status",
"code"
],
"license": "MIT",
"name": "statuses",
"repository": {
"type": "git",
"url": "git+https://github.com/jshttp/statuses.git"
},
"scripts": {
"build": "node scripts/build.js",
"fetch": "node scripts/fetch.js",
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"update": "npm run fetch && npm run build"
},
"version": "1.3.1"
}

View File

@@ -0,0 +1,85 @@
{
"_from": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"_id": "http-errors@1.5.1",
"_inBundle": false,
"_integrity": "sha512-ftkc2U5ADKHv8Ny1QJaDn8xnE18G+fP5QYupx9c3Xk6L5Vgo3qK8Bgbpb4a+jRtaF/YQKjIuXA5J0tde4Tojng==",
"_location": "/skills-service-manager/body-parser/http-errors",
"_phantomChildren": {},
"_requested": {
"type": "remote",
"raw": "http-errors@https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"name": "http-errors",
"escapedName": "http-errors",
"rawSpec": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"saveSpec": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"fetchSpec": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz"
},
"_requiredBy": [
"/skills-service-manager/body-parser"
],
"_resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"_spec": "http-errors@https://registry.npmjs.org/http-errors/-/http-errors-1.5.1.tgz",
"_where": "/tmp/jibo-npm/jibo-cli-3.0.7",
"author": {
"name": "Jonathan Ong",
"email": "me@jongleberry.com",
"url": "http://jongleberry.com"
},
"bugs": {
"url": "https://github.com/jshttp/http-errors/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Alan Plum",
"email": "me@pluma.io"
},
{
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
}
],
"dependencies": {
"inherits": "2.0.3",
"setprototypeof": "1.0.2",
"statuses": ">= 1.3.1 < 2"
},
"deprecated": false,
"description": "Create HTTP error objects",
"devDependencies": {
"eslint": "3.10.2",
"eslint-config-standard": "6.2.1",
"eslint-plugin-markdown": "1.0.0-beta.3",
"eslint-plugin-promise": "3.3.2",
"eslint-plugin-standard": "2.0.1",
"istanbul": "0.4.5",
"mocha": "1.21.5"
},
"engines": {
"node": ">= 0.6"
},
"files": [
"index.js",
"HISTORY.md",
"LICENSE",
"README.md"
],
"homepage": "https://github.com/jshttp/http-errors#readme",
"keywords": [
"http",
"error"
],
"license": "MIT",
"name": "http-errors",
"repository": {
"type": "git",
"url": "git+https://github.com/jshttp/http-errors.git"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --bail",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot"
},
"version": "1.5.1"
}

View File

@@ -0,0 +1,6 @@
*~
*sublime-*
generation
test
wiki
coverage

View File

@@ -0,0 +1,22 @@
sudo: false
language: node_js
node_js:
- "0.10"
- "0.11"
- "0.12"
- "iojs"
- "4"
- "6"
- "node"
env:
- CXX=g++-4.8
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8

View File

@@ -0,0 +1,108 @@
# 0.4.15 / 2016-11-21
* Fixed typescript type definition (#137)
# 0.4.14 / 2016-11-20
* Preparation for v1.0
* Added Node v6 and latest Node versions to Travis CI test rig
* Deprecated Node v0.8 support
* Typescript typings (@larssn)
* Fix encoding of Euro character in GB 18030 (inspired by @lygstate)
* Add ms prefix to dbcs windows encodings (@rokoroku)
# 0.4.13 / 2015-10-01
* Fix silly mistake in deprecation notice.
# 0.4.12 / 2015-09-26
* Node v4 support:
* Added CESU-8 decoding (#106)
* Added deprecation notice for `extendNodeEncodings`
* Added Travis tests for Node v4 and io.js latest (#105 by @Mithgol)
# 0.4.11 / 2015-07-03
* Added CESU-8 encoding.
# 0.4.10 / 2015-05-26
* Changed UTF-16 endianness heuristic to take into account any ASCII chars, not
just spaces. This should minimize the importance of "default" endianness.
# 0.4.9 / 2015-05-24
* Streamlined BOM handling: strip BOM by default, add BOM when encoding if
addBOM: true. Added docs to Readme.
* UTF16 now uses UTF16-LE by default.
* Fixed minor issue with big5 encoding.
* Added io.js testing on Travis; updated node-iconv version to test against.
Now we just skip testing SBCS encodings that node-iconv doesn't support.
* (internal refactoring) Updated codec interface to use classes.
* Use strict mode in all files.
# 0.4.8 / 2015-04-14
* added alias UNICODE-1-1-UTF-7 for UTF-7 encoding (#94)
# 0.4.7 / 2015-02-05
* stop official support of Node.js v0.8. Should still work, but no guarantees.
reason: Packages needed for testing are hard to get on Travis CI.
* work in environment where Object.prototype is monkey patched with enumerable
props (#89).
# 0.4.6 / 2015-01-12
* fix rare aliases of single-byte encodings (thanks @mscdex)
* double the timeout for dbcs tests to make them less flaky on travis
# 0.4.5 / 2014-11-20
* fix windows-31j and x-sjis encoding support (@nleush)
* minor fix: undefined variable reference when internal error happens
# 0.4.4 / 2014-07-16
* added encodings UTF-7 (RFC2152) and UTF-7-IMAP (RFC3501 Section 5.1.3)
* fixed streaming base64 encoding
# 0.4.3 / 2014-06-14
* added encodings UTF-16BE and UTF-16 with BOM
# 0.4.2 / 2014-06-12
* don't throw exception if `extendNodeEncodings()` is called more than once
# 0.4.1 / 2014-06-11
* codepage 808 added
# 0.4.0 / 2014-06-10
* code is rewritten from scratch
* all widespread encodings are supported
* streaming interface added
* browserify compatibility added
* (optional) extend core primitive encodings to make usage even simpler
* moved from vows to mocha as the testing framework

View File

@@ -0,0 +1,21 @@
Copyright (c) 2011 Alexander Shtuchkin
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.

View File

@@ -0,0 +1,159 @@
## Pure JS character encoding conversion [![Build Status](https://travis-ci.org/ashtuchkin/iconv-lite.svg?branch=master)](https://travis-ci.org/ashtuchkin/iconv-lite)
* Doesn't need native code compilation. Works on Windows and in sandboxed environments like [Cloud9](http://c9.io).
* Used in popular projects like [Express.js (body_parser)](https://github.com/expressjs/body-parser),
[Grunt](http://gruntjs.com/), [Nodemailer](http://www.nodemailer.com/), [Yeoman](http://yeoman.io/) and others.
* Faster than [node-iconv](https://github.com/bnoordhuis/node-iconv) (see below for performance comparison).
* Intuitive encode/decode API
* Streaming support for Node v0.10+
* [Deprecated] Can extend Node.js primitives (buffers, streams) to support all iconv-lite encodings.
* In-browser usage via [Browserify](https://github.com/substack/node-browserify) (~180k gzip compressed with Buffer shim included).
* Typescript [type definition file](https://github.com/ashtuchkin/iconv-lite/blob/master/lib/index.d.ts) included.
* License: MIT.
[![NPM Stats](https://nodei.co/npm/iconv-lite.png?downloads=true&downloadRank=true)](https://npmjs.org/packages/iconv-lite/)
## Usage
### Basic API
```javascript
var iconv = require('iconv-lite');
// Convert from an encoded buffer to js string.
str = iconv.decode(new Buffer([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251');
// Convert from js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');
// Check if encoding is supported
iconv.encodingExists("us-ascii")
```
### Streaming API (Node v0.10+)
```javascript
// Decode stream (from binary stream to js strings)
http.createServer(function(req, res) {
var converterStream = iconv.decodeStream('win1251');
req.pipe(converterStream);
converterStream.on('data', function(str) {
console.log(str); // Do something with decoded strings, chunk-by-chunk.
});
});
// Convert encoding streaming example
fs.createReadStream('file-in-win1251.txt')
.pipe(iconv.decodeStream('win1251'))
.pipe(iconv.encodeStream('ucs2'))
.pipe(fs.createWriteStream('file-in-ucs2.txt'));
// Sugar: all encode/decode streams have .collect(cb) method to accumulate data.
http.createServer(function(req, res) {
req.pipe(iconv.decodeStream('win1251')).collect(function(err, body) {
assert(typeof body == 'string');
console.log(body); // full request body string
});
});
```
### [Deprecated] Extend Node.js own encodings
> NOTE: This doesn't work on latest Node versions. See [details](https://github.com/ashtuchkin/iconv-lite/wiki/Node-v4-compatibility).
```javascript
// After this call all Node basic primitives will understand iconv-lite encodings.
iconv.extendNodeEncodings();
// Examples:
buf = new Buffer(str, 'win1251');
buf.write(str, 'gbk');
str = buf.toString('latin1');
assert(Buffer.isEncoding('iso-8859-15'));
Buffer.byteLength(str, 'us-ascii');
http.createServer(function(req, res) {
req.setEncoding('big5');
req.collect(function(err, body) {
console.log(body);
});
});
fs.createReadStream("file.txt", "shift_jis");
// External modules are also supported (if they use Node primitives, which they probably do).
request = require('request');
request({
url: "http://github.com/",
encoding: "cp932"
});
// To remove extensions
iconv.undoExtendNodeEncodings();
```
## Supported encodings
* All node.js native encodings: utf8, ucs2 / utf16-le, ascii, binary, base64, hex.
* Additional unicode encodings: utf16, utf16-be, utf-7, utf-7-imap.
* All widespread singlebyte encodings: Windows 125x family, ISO-8859 family,
IBM/DOS codepages, Macintosh family, KOI8 family, all others supported by iconv library.
Aliases like 'latin1', 'us-ascii' also supported.
* All widespread multibyte encodings: CP932, CP936, CP949, CP950, GB2313, GBK, GB18030, Big5, Shift_JIS, EUC-JP.
See [all supported encodings on wiki](https://github.com/ashtuchkin/iconv-lite/wiki/Supported-Encodings).
Most singlebyte encodings are generated automatically from [node-iconv](https://github.com/bnoordhuis/node-iconv). Thank you Ben Noordhuis and libiconv authors!
Multibyte encodings are generated from [Unicode.org mappings](http://www.unicode.org/Public/MAPPINGS/) and [WHATWG Encoding Standard mappings](http://encoding.spec.whatwg.org/). Thank you, respective authors!
## Encoding/decoding speed
Comparison with node-iconv module (1000x256kb, on MacBook Pro, Core i5/2.6 GHz, Node v0.12.0).
Note: your results may vary, so please always check on your hardware.
operation iconv@2.1.4 iconv-lite@0.4.7
----------------------------------------------------------
encode('win1251') ~96 Mb/s ~320 Mb/s
decode('win1251') ~95 Mb/s ~246 Mb/s
## BOM handling
* Decoding: BOM is stripped by default, unless overridden by passing `stripBOM: false` in options
(f.ex. `iconv.decode(buf, enc, {stripBOM: false})`).
A callback might also be given as a `stripBOM` parameter - it'll be called if BOM character was actually found.
* If you want to detect UTF-8 BOM when decoding other encodings, use [node-autodetect-decoder-stream](https://github.com/danielgindi/node-autodetect-decoder-stream) module.
* Encoding: No BOM added, unless overridden by `addBOM: true` option.
## UTF-16 Encodings
This library supports UTF-16LE, UTF-16BE and UTF-16 encodings. First two are straightforward, but UTF-16 is trying to be
smart about endianness in the following ways:
* Decoding: uses BOM and 'spaces heuristic' to determine input endianness. Default is UTF-16LE, but can be
overridden with `defaultEncoding: 'utf-16be'` option. Strips BOM unless `stripBOM: false`.
* Encoding: uses UTF-16LE and writes BOM by default. Use `addBOM: false` to override.
## Other notes
When decoding, be sure to supply a Buffer to decode() method, otherwise [bad things usually happen](https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding).
Untranslatable characters are set to <20> or ?. No transliteration is currently supported.
Node versions 0.10.31 and 0.11.13 are buggy, don't use them (see #65, #77).
## Testing
```bash
$ git clone git@github.com:ashtuchkin/iconv-lite.git
$ cd iconv-lite
$ npm install
$ npm test
$ # To view performance:
$ node test/performance.js
$ # To view test coverage:
$ npm run coverage
$ open coverage/lcov-report/index.html
```
## Adoption
[![NPM](https://nodei.co/npm-dl/iconv-lite.png)](https://nodei.co/npm/iconv-lite/)
[![Codeship Status for ashtuchkin/iconv-lite](https://www.codeship.com/projects/81670840-fa72-0131-4520-4a01a6c01acc/status)](https://www.codeship.com/projects/29053)

View File

@@ -0,0 +1,554 @@
"use strict"
// Multibyte codec. In this scheme, a character is represented by 1 or more bytes.
// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences.
// To save memory and loading time, we read table files only when requested.
exports._dbcs = DBCSCodec;
var UNASSIGNED = -1,
GB18030_CODE = -2,
SEQ_START = -10,
NODE_START = -1000,
UNASSIGNED_NODE = new Array(0x100),
DEF_CHAR = -1;
for (var i = 0; i < 0x100; i++)
UNASSIGNED_NODE[i] = UNASSIGNED;
// Class DBCSCodec reads and initializes mapping tables.
function DBCSCodec(codecOptions, iconv) {
this.encodingName = codecOptions.encodingName;
if (!codecOptions)
throw new Error("DBCS codec is called without the data.")
if (!codecOptions.table)
throw new Error("Encoding '" + this.encodingName + "' has no data.");
// Load tables.
var mappingTable = codecOptions.table();
// Decode tables: MBCS -> Unicode.
// decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256.
// Trie root is decodeTables[0].
// Values: >= 0 -> unicode character code. can be > 0xFFFF
// == UNASSIGNED -> unknown/unassigned sequence.
// == GB18030_CODE -> this is the end of a GB18030 4-byte sequence.
// <= NODE_START -> index of the next node in our trie to process next byte.
// <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq.
this.decodeTables = [];
this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node.
// Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here.
this.decodeTableSeq = [];
// Actual mapping tables consist of chunks. Use them to fill up decode tables.
for (var i = 0; i < mappingTable.length; i++)
this._addDecodeChunk(mappingTable[i]);
this.defaultCharUnicode = iconv.defaultCharUnicode;
// Encode tables: Unicode -> DBCS.
// `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance.
// Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null.
// Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.).
// == UNASSIGNED -> no conversion found. Output a default char.
// <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence.
this.encodeTable = [];
// `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of
// objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key
// means end of sequence (needed when one sequence is a strict subsequence of another).
// Objects are kept separately from encodeTable to increase performance.
this.encodeTableSeq = [];
// Some chars can be decoded, but need not be encoded.
var skipEncodeChars = {};
if (codecOptions.encodeSkipVals)
for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) {
var val = codecOptions.encodeSkipVals[i];
if (typeof val === 'number')
skipEncodeChars[val] = true;
else
for (var j = val.from; j <= val.to; j++)
skipEncodeChars[j] = true;
}
// Use decode trie to recursively fill out encode tables.
this._fillEncodeTable(0, 0, skipEncodeChars);
// Add more encoding pairs when needed.
if (codecOptions.encodeAdd) {
for (var uChar in codecOptions.encodeAdd)
if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar))
this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]);
}
this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)];
if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?'];
if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0);
// Load & create GB18030 tables when needed.
if (typeof codecOptions.gb18030 === 'function') {
this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges.
// Add GB18030 decode tables.
var thirdByteNodeIdx = this.decodeTables.length;
var thirdByteNode = this.decodeTables[thirdByteNodeIdx] = UNASSIGNED_NODE.slice(0);
var fourthByteNodeIdx = this.decodeTables.length;
var fourthByteNode = this.decodeTables[fourthByteNodeIdx] = UNASSIGNED_NODE.slice(0);
for (var i = 0x81; i <= 0xFE; i++) {
var secondByteNodeIdx = NODE_START - this.decodeTables[0][i];
var secondByteNode = this.decodeTables[secondByteNodeIdx];
for (var j = 0x30; j <= 0x39; j++)
secondByteNode[j] = NODE_START - thirdByteNodeIdx;
}
for (var i = 0x81; i <= 0xFE; i++)
thirdByteNode[i] = NODE_START - fourthByteNodeIdx;
for (var i = 0x30; i <= 0x39; i++)
fourthByteNode[i] = GB18030_CODE
}
}
DBCSCodec.prototype.encoder = DBCSEncoder;
DBCSCodec.prototype.decoder = DBCSDecoder;
// Decoder helpers
DBCSCodec.prototype._getDecodeTrieNode = function(addr) {
var bytes = [];
for (; addr > 0; addr >>= 8)
bytes.push(addr & 0xFF);
if (bytes.length == 0)
bytes.push(0);
var node = this.decodeTables[0];
for (var i = bytes.length-1; i > 0; i--) { // Traverse nodes deeper into the trie.
var val = node[bytes[i]];
if (val == UNASSIGNED) { // Create new node.
node[bytes[i]] = NODE_START - this.decodeTables.length;
this.decodeTables.push(node = UNASSIGNED_NODE.slice(0));
}
else if (val <= NODE_START) { // Existing node.
node = this.decodeTables[NODE_START - val];
}
else
throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16));
}
return node;
}
DBCSCodec.prototype._addDecodeChunk = function(chunk) {
// First element of chunk is the hex mbcs code where we start.
var curAddr = parseInt(chunk[0], 16);
// Choose the decoding node where we'll write our chars.
var writeTable = this._getDecodeTrieNode(curAddr);
curAddr = curAddr & 0xFF;
// Write all other elements of the chunk to the table.
for (var k = 1; k < chunk.length; k++) {
var part = chunk[k];
if (typeof part === "string") { // String, write as-is.
for (var l = 0; l < part.length;) {
var code = part.charCodeAt(l++);
if (0xD800 <= code && code < 0xDC00) { // Decode surrogate
var codeTrail = part.charCodeAt(l++);
if (0xDC00 <= codeTrail && codeTrail < 0xE000)
writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00);
else
throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]);
}
else if (0x0FF0 < code && code <= 0x0FFF) { // Character sequence (our own encoding used)
var len = 0xFFF - code + 2;
var seq = [];
for (var m = 0; m < len; m++)
seq.push(part.charCodeAt(l++)); // Simple variation: don't support surrogates or subsequences in seq.
writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length;
this.decodeTableSeq.push(seq);
}
else
writeTable[curAddr++] = code; // Basic char
}
}
else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character.
var charCode = writeTable[curAddr - 1] + 1;
for (var l = 0; l < part; l++)
writeTable[curAddr++] = charCode++;
}
else
throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]);
}
if (curAddr > 0xFF)
throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr);
}
// Encoder helpers
DBCSCodec.prototype._getEncodeBucket = function(uCode) {
var high = uCode >> 8; // This could be > 0xFF because of astral characters.
if (this.encodeTable[high] === undefined)
this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand.
return this.encodeTable[high];
}
DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) {
var bucket = this._getEncodeBucket(uCode);
var low = uCode & 0xFF;
if (bucket[low] <= SEQ_START)
this.encodeTableSeq[SEQ_START-bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it.
else if (bucket[low] == UNASSIGNED)
bucket[low] = dbcsCode;
}
DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) {
// Get the root of character tree according to first character of the sequence.
var uCode = seq[0];
var bucket = this._getEncodeBucket(uCode);
var low = uCode & 0xFF;
var node;
if (bucket[low] <= SEQ_START) {
// There's already a sequence with - use it.
node = this.encodeTableSeq[SEQ_START-bucket[low]];
}
else {
// There was no sequence object - allocate a new one.
node = {};
if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence.
bucket[low] = SEQ_START - this.encodeTableSeq.length;
this.encodeTableSeq.push(node);
}
// Traverse the character tree, allocating new nodes as needed.
for (var j = 1; j < seq.length-1; j++) {
var oldVal = node[uCode];
if (typeof oldVal === 'object')
node = oldVal;
else {
node = node[uCode] = {}
if (oldVal !== undefined)
node[DEF_CHAR] = oldVal
}
}
// Set the leaf to given dbcsCode.
uCode = seq[seq.length-1];
node[uCode] = dbcsCode;
}
DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) {
var node = this.decodeTables[nodeIdx];
for (var i = 0; i < 0x100; i++) {
var uCode = node[i];
var mbCode = prefix + i;
if (skipEncodeChars[mbCode])
continue;
if (uCode >= 0)
this._setEncodeChar(uCode, mbCode);
else if (uCode <= NODE_START)
this._fillEncodeTable(NODE_START - uCode, mbCode << 8, skipEncodeChars);
else if (uCode <= SEQ_START)
this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode);
}
}
// == Encoder ==================================================================
function DBCSEncoder(options, codec) {
// Encoder state
this.leadSurrogate = -1;
this.seqObj = undefined;
// Static data
this.encodeTable = codec.encodeTable;
this.encodeTableSeq = codec.encodeTableSeq;
this.defaultCharSingleByte = codec.defCharSB;
this.gb18030 = codec.gb18030;
}
DBCSEncoder.prototype.write = function(str) {
var newBuf = new Buffer(str.length * (this.gb18030 ? 4 : 3)),
leadSurrogate = this.leadSurrogate,
seqObj = this.seqObj, nextChar = -1,
i = 0, j = 0;
while (true) {
// 0. Get next character.
if (nextChar === -1) {
if (i == str.length) break;
var uCode = str.charCodeAt(i++);
}
else {
var uCode = nextChar;
nextChar = -1;
}
// 1. Handle surrogates.
if (0xD800 <= uCode && uCode < 0xE000) { // Char is one of surrogates.
if (uCode < 0xDC00) { // We've got lead surrogate.
if (leadSurrogate === -1) {
leadSurrogate = uCode;
continue;
} else {
leadSurrogate = uCode;
// Double lead surrogate found.
uCode = UNASSIGNED;
}
} else { // We've got trail surrogate.
if (leadSurrogate !== -1) {
uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00);
leadSurrogate = -1;
} else {
// Incomplete surrogate pair - only trail surrogate found.
uCode = UNASSIGNED;
}
}
}
else if (leadSurrogate !== -1) {
// Incomplete surrogate pair - only lead surrogate found.
nextChar = uCode; uCode = UNASSIGNED; // Write an error, then current char.
leadSurrogate = -1;
}
// 2. Convert uCode character.
var dbcsCode = UNASSIGNED;
if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence
var resCode = seqObj[uCode];
if (typeof resCode === 'object') { // Sequence continues.
seqObj = resCode;
continue;
} else if (typeof resCode == 'number') { // Sequence finished. Write it.
dbcsCode = resCode;
} else if (resCode == undefined) { // Current character is not part of the sequence.
// Try default character for this sequence
resCode = seqObj[DEF_CHAR];
if (resCode !== undefined) {
dbcsCode = resCode; // Found. Write it.
nextChar = uCode; // Current character will be written too in the next iteration.
} else {
// TODO: What if we have no default? (resCode == undefined)
// Then, we should write first char of the sequence as-is and try the rest recursively.
// Didn't do it for now because no encoding has this situation yet.
// Currently, just skip the sequence and write current char.
}
}
seqObj = undefined;
}
else if (uCode >= 0) { // Regular character
var subtable = this.encodeTable[uCode >> 8];
if (subtable !== undefined)
dbcsCode = subtable[uCode & 0xFF];
if (dbcsCode <= SEQ_START) { // Sequence start
seqObj = this.encodeTableSeq[SEQ_START-dbcsCode];
continue;
}
if (dbcsCode == UNASSIGNED && this.gb18030) {
// Use GB18030 algorithm to find character(s) to write.
var idx = findIdx(this.gb18030.uChars, uCode);
if (idx != -1) {
var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]);
newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600;
newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260;
newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10;
newBuf[j++] = 0x30 + dbcsCode;
continue;
}
}
}
// 3. Write dbcsCode character.
if (dbcsCode === UNASSIGNED)
dbcsCode = this.defaultCharSingleByte;
if (dbcsCode < 0x100) {
newBuf[j++] = dbcsCode;
}
else if (dbcsCode < 0x10000) {
newBuf[j++] = dbcsCode >> 8; // high byte
newBuf[j++] = dbcsCode & 0xFF; // low byte
}
else {
newBuf[j++] = dbcsCode >> 16;
newBuf[j++] = (dbcsCode >> 8) & 0xFF;
newBuf[j++] = dbcsCode & 0xFF;
}
}
this.seqObj = seqObj;
this.leadSurrogate = leadSurrogate;
return newBuf.slice(0, j);
}
DBCSEncoder.prototype.end = function() {
if (this.leadSurrogate === -1 && this.seqObj === undefined)
return; // All clean. Most often case.
var newBuf = new Buffer(10), j = 0;
if (this.seqObj) { // We're in the sequence.
var dbcsCode = this.seqObj[DEF_CHAR];
if (dbcsCode !== undefined) { // Write beginning of the sequence.
if (dbcsCode < 0x100) {
newBuf[j++] = dbcsCode;
}
else {
newBuf[j++] = dbcsCode >> 8; // high byte
newBuf[j++] = dbcsCode & 0xFF; // low byte
}
} else {
// See todo above.
}
this.seqObj = undefined;
}
if (this.leadSurrogate !== -1) {
// Incomplete surrogate pair - only lead surrogate found.
newBuf[j++] = this.defaultCharSingleByte;
this.leadSurrogate = -1;
}
return newBuf.slice(0, j);
}
// Export for testing
DBCSEncoder.prototype.findIdx = findIdx;
// == Decoder ==================================================================
function DBCSDecoder(options, codec) {
// Decoder state
this.nodeIdx = 0;
this.prevBuf = new Buffer(0);
// Static data
this.decodeTables = codec.decodeTables;
this.decodeTableSeq = codec.decodeTableSeq;
this.defaultCharUnicode = codec.defaultCharUnicode;
this.gb18030 = codec.gb18030;
}
DBCSDecoder.prototype.write = function(buf) {
var newBuf = new Buffer(buf.length*2),
nodeIdx = this.nodeIdx,
prevBuf = this.prevBuf, prevBufOffset = this.prevBuf.length,
seqStart = -this.prevBuf.length, // idx of the start of current parsed sequence.
uCode;
if (prevBufOffset > 0) // Make prev buf overlap a little to make it easier to slice later.
prevBuf = Buffer.concat([prevBuf, buf.slice(0, 10)]);
for (var i = 0, j = 0; i < buf.length; i++) {
var curByte = (i >= 0) ? buf[i] : prevBuf[i + prevBufOffset];
// Lookup in current trie node.
var uCode = this.decodeTables[nodeIdx][curByte];
if (uCode >= 0) {
// Normal character, just use it.
}
else if (uCode === UNASSIGNED) { // Unknown char.
// TODO: Callback with seq.
//var curSeq = (seqStart >= 0) ? buf.slice(seqStart, i+1) : prevBuf.slice(seqStart + prevBufOffset, i+1 + prevBufOffset);
i = seqStart; // Try to parse again, after skipping first byte of the sequence ('i' will be incremented by 'for' cycle).
uCode = this.defaultCharUnicode.charCodeAt(0);
}
else if (uCode === GB18030_CODE) {
var curSeq = (seqStart >= 0) ? buf.slice(seqStart, i+1) : prevBuf.slice(seqStart + prevBufOffset, i+1 + prevBufOffset);
var ptr = (curSeq[0]-0x81)*12600 + (curSeq[1]-0x30)*1260 + (curSeq[2]-0x81)*10 + (curSeq[3]-0x30);
var idx = findIdx(this.gb18030.gbChars, ptr);
uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx];
}
else if (uCode <= NODE_START) { // Go to next trie node.
nodeIdx = NODE_START - uCode;
continue;
}
else if (uCode <= SEQ_START) { // Output a sequence of chars.
var seq = this.decodeTableSeq[SEQ_START - uCode];
for (var k = 0; k < seq.length - 1; k++) {
uCode = seq[k];
newBuf[j++] = uCode & 0xFF;
newBuf[j++] = uCode >> 8;
}
uCode = seq[seq.length-1];
}
else
throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte);
// Write the character to buffer, handling higher planes using surrogate pair.
if (uCode > 0xFFFF) {
uCode -= 0x10000;
var uCodeLead = 0xD800 + Math.floor(uCode / 0x400);
newBuf[j++] = uCodeLead & 0xFF;
newBuf[j++] = uCodeLead >> 8;
uCode = 0xDC00 + uCode % 0x400;
}
newBuf[j++] = uCode & 0xFF;
newBuf[j++] = uCode >> 8;
// Reset trie node.
nodeIdx = 0; seqStart = i+1;
}
this.nodeIdx = nodeIdx;
this.prevBuf = (seqStart >= 0) ? buf.slice(seqStart) : prevBuf.slice(seqStart + prevBufOffset);
return newBuf.slice(0, j).toString('ucs2');
}
DBCSDecoder.prototype.end = function() {
var ret = '';
// Try to parse all remaining chars.
while (this.prevBuf.length > 0) {
// Skip 1 character in the buffer.
ret += this.defaultCharUnicode;
var buf = this.prevBuf.slice(1);
// Parse remaining as usual.
this.prevBuf = new Buffer(0);
this.nodeIdx = 0;
if (buf.length > 0)
ret += this.write(buf);
}
this.nodeIdx = 0;
return ret;
}
// Binary search for GB18030. Returns largest i such that table[i] <= val.
function findIdx(table, val) {
if (table[0] > val)
return -1;
var l = 0, r = table.length;
while (l < r-1) { // always table[l] <= val < table[r]
var mid = l + Math.floor((r-l+1)/2);
if (table[mid] <= val)
l = mid;
else
r = mid;
}
return l;
}

Some files were not shown because too many files have changed in this diff Show More