@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Eslint config file
|
||||||
|
* Documentation: https://eslint.org/docs/user-guide/configuring/
|
||||||
|
* Install the Eslint extension before using this feature.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
es6: true,
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
ecmaFeatures: {
|
||||||
|
modules: true,
|
||||||
|
},
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2018,
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
wx: true,
|
||||||
|
App: true,
|
||||||
|
Page: true,
|
||||||
|
getCurrentPages: true,
|
||||||
|
getApp: true,
|
||||||
|
Component: true,
|
||||||
|
requirePlugin: true,
|
||||||
|
requireMiniProgram: true,
|
||||||
|
},
|
||||||
|
// extends: 'eslint:recommended',
|
||||||
|
rules: {},
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
// app.js
|
||||||
|
App({
|
||||||
|
onLaunch() {
|
||||||
|
// 展示本地存储能力
|
||||||
|
const logs = wx.getStorageSync('logs') || []
|
||||||
|
logs.unshift(Date.now())
|
||||||
|
wx.setStorageSync('logs', logs)
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
wx.login({
|
||||||
|
success: res => {
|
||||||
|
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
globalData: {
|
||||||
|
userInfo: null
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
"pages/music/music"
|
||||||
|
],
|
||||||
|
"window": {
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#87CEFA",
|
||||||
|
"navigationBarTitleText": "MayMusic"
|
||||||
|
},
|
||||||
|
"requireBackgroundModes": ["audio"]
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
/**app.wxss**/
|
||||||
|
.container {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 200rpx 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<swiper class="content-info-slide" indicator-color="rgba(255,255,255,.5)" indicator-active-color="#fff" indicator-dots circular autoplay>
|
||||||
|
<swiper-item>
|
||||||
|
<image src="/pictures/111.jpg" />
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<image src="/pictures/444.jpg" />
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<image src="/pictures/333.jpg" />
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
<view class="content-info-portal">
|
||||||
|
<view>
|
||||||
|
<image src="/pictures/04.png" />
|
||||||
|
<text>私人FM</text>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<image src="/pictures/05.png" />
|
||||||
|
<text>每日歌曲推荐</text>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<image src="/pictures/06.png" />
|
||||||
|
<text>云音乐新歌榜</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="content-info-list">
|
||||||
|
<view class="list-title">推荐歌曲</view>
|
||||||
|
<view class="list-inner">
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/1.jpg" />
|
||||||
|
<view>任意门</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/2.jpg" />
|
||||||
|
<view>你是唯一</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/3.jpg" />
|
||||||
|
<view>阿姆斯壮</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/4.jpg" />
|
||||||
|
<view>一千个世纪</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/5.jpg" />
|
||||||
|
<view>相信</view>
|
||||||
|
</view>
|
||||||
|
<view class="list-item">
|
||||||
|
<image src="/pictures/6.jpg" />
|
||||||
|
<view>反而</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,192 @@
|
|||||||
|
function formatTime(time){
|
||||||
|
var minute=Math.floor(time/60)%60;
|
||||||
|
var second=Math.floor(time)%60
|
||||||
|
return(minute<10?'0'+minute:minute)+':'+(second<10?'0'+second:second)
|
||||||
|
}
|
||||||
|
Page({
|
||||||
|
change(e){
|
||||||
|
this.setMusic(e.currentTarget.dataset.index)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 页面的初始数据
|
||||||
|
*/
|
||||||
|
data: {
|
||||||
|
item:0,
|
||||||
|
tab:0,
|
||||||
|
playlist:[{
|
||||||
|
id:1,
|
||||||
|
title:'哄我入睡',
|
||||||
|
singer:'阿信',
|
||||||
|
src:'http://127.0.0.1:3000/1.mp3',
|
||||||
|
coverImgURL:'/pictures/cover4.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:2,
|
||||||
|
title:'Enrich your life',
|
||||||
|
singer:'五月天',
|
||||||
|
src:'http://127.0.0.1:3000/2.mp3',
|
||||||
|
coverImgURL:'/pictures/cover1.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:1,
|
||||||
|
title:'阿姆斯壮',
|
||||||
|
singer:'五月天',
|
||||||
|
src:'http://127.0.0.1:3000/3.mp3',
|
||||||
|
coverImgURL:'/pictures/cover2.jpg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:1,
|
||||||
|
title:'听不到',
|
||||||
|
singer:'五月天',
|
||||||
|
src:'http://127.0.0.1:3000/4.mp3',
|
||||||
|
coverImgURL:'/pictures/cover3.jpg'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
state:'running',
|
||||||
|
playIndex:0,
|
||||||
|
play:{
|
||||||
|
currentTime:'00:00',
|
||||||
|
duration:'00:00',
|
||||||
|
percent:0,
|
||||||
|
title:'',
|
||||||
|
singer:'',
|
||||||
|
coverImgURL:'/pictures/cover.jpg'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
changeItem:function(e){
|
||||||
|
this.setData({
|
||||||
|
item: e.target.dataset.item
|
||||||
|
})
|
||||||
|
},
|
||||||
|
changeTab:function(e){
|
||||||
|
console.log(e)
|
||||||
|
this.setData({
|
||||||
|
tab:e.detail.current
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面加载
|
||||||
|
*/
|
||||||
|
onLoad(options) {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面初次渲染完成
|
||||||
|
*/
|
||||||
|
|
||||||
|
audioBam:null,
|
||||||
|
onReady:function() {
|
||||||
|
this.audioBam=wx.getBackgroundAudioManager()
|
||||||
|
this.setMusic(0)
|
||||||
|
this.audioBam.onError(()=>{
|
||||||
|
console.log('播放失败:'+this.audioBam.src)
|
||||||
|
})
|
||||||
|
this.audioBam.onEnded(()=>{
|
||||||
|
this.next()
|
||||||
|
})
|
||||||
|
var updateTime=0
|
||||||
|
this.audioBam.onTimeUpdate(()=>{
|
||||||
|
var currentTime =parseInt(this.audioBam.currentTime)
|
||||||
|
if(!this.sliderChangeLock&¤tTime!==updateTime){
|
||||||
|
updateTime=currentTime
|
||||||
|
this.setData({
|
||||||
|
'play.duration':formatTime(this.audioBam.duration||0),
|
||||||
|
'play.cuttentTime':formatTime(currentTime),
|
||||||
|
'play.percent':currentTime/this.audioBam.duration*100
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setMusic:function(index){
|
||||||
|
var music=this.data.playlist[index]
|
||||||
|
this.audioBam.src=music.src
|
||||||
|
this.audioBam.title=music.title
|
||||||
|
this.setData({
|
||||||
|
playIndex:index,
|
||||||
|
'play.title':music.title,
|
||||||
|
'play.singer':music.singer,
|
||||||
|
'play.coverImgUrl':music.coverImgURL,
|
||||||
|
'play.currentTime':'00:00',
|
||||||
|
'play.duration':'00:00',
|
||||||
|
'play.percent':0,
|
||||||
|
state:'running'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
play:function(){
|
||||||
|
this.audioBam.play()
|
||||||
|
this.setData({
|
||||||
|
state:'running'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
pause(){
|
||||||
|
this.audioBam.pause()
|
||||||
|
this.setData({
|
||||||
|
state:'paused'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
next(){
|
||||||
|
var index=this.data.playIndex>=this.data.playlist.length-1?0:this.data.playIndex+1
|
||||||
|
this.setMusic(index)
|
||||||
|
},
|
||||||
|
sliderChangeLock:false,
|
||||||
|
sliderChanging:function(e){
|
||||||
|
var second=e.detail.value*this.audioBam.duration/100
|
||||||
|
this.sliderChangeLock=true
|
||||||
|
this.setData({
|
||||||
|
'play.currentTime':formatTime(second),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
sliderChange:function(e){
|
||||||
|
var second=e.detail.value*this.audioBam.duration/100
|
||||||
|
this.audioBam.seek(second)
|
||||||
|
setTimeout(()=>{
|
||||||
|
this.sliderChangeLock=false
|
||||||
|
},1000)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面显示
|
||||||
|
*/
|
||||||
|
onShow() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面隐藏
|
||||||
|
*/
|
||||||
|
onHide() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生命周期函数--监听页面卸载
|
||||||
|
*/
|
||||||
|
onUnload() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面相关事件处理函数--监听用户下拉动作
|
||||||
|
*/
|
||||||
|
onPullDownRefresh() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面上拉触底事件的处理函数
|
||||||
|
*/
|
||||||
|
onReachBottom() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击右上角分享
|
||||||
|
*/
|
||||||
|
onShareAppMessage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"requiredBackModes":["audio"],
|
||||||
|
"usingComponents": {}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<!--pages/music/music.wxml-->
|
||||||
|
<view class="tab">
|
||||||
|
<view class="tab-item {{tab==0?'active':''}}" bind:tap="changeItem" data-item="0">音乐推荐</view>
|
||||||
|
<view class="tab-item {{tab==1?'active':''}}" bind:tap="changeItem" data-item="1">播放器</view>
|
||||||
|
<view class="tab-item {{tab==2?'active':''}}" bind:tap="changeItem" data-item="2">播放列表</view>
|
||||||
|
</view>
|
||||||
|
<view class="content">
|
||||||
|
|
||||||
|
<swiper current="{{ item }}" bindchange="changeTab">
|
||||||
|
<swiper-item>
|
||||||
|
<!-- 音乐推荐 -->
|
||||||
|
<include src="info.wxml"></include>
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<!-- 播放器 -->
|
||||||
|
<include src="play.wxml"></include>
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<!-- 播放列表 -->
|
||||||
|
<include src="playlist.wxml"></include>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="player">
|
||||||
|
<image class="player-cover" src="{{play.coverImgURL}}" data-item="1" bind:tap="changeItem" mode="" />
|
||||||
|
<view class="player-info">
|
||||||
|
<view class="player-info-title" data-item="1" bind:tap="changeItem">{{play.title}}</view>
|
||||||
|
<view class="player-info-singer" data-item="1" bind:tap="changeItem">{{play.item}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="playlist-controls">
|
||||||
|
<image src="/pictures/01.png" data-item="2" bind:tap="changeItem" mode="" />
|
||||||
|
<image wx:if="{{state=='paused'}}" src="/pictures/02.png" bind:tap="play" mode="" />
|
||||||
|
<image wx:else="" src="/pictures/02stop.png" bind:tap="paused" mode="" />
|
||||||
|
<image src="/pictures/03.png" bind:tap="next" mode="" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
@ -0,0 +1,241 @@
|
|||||||
|
/**index.wxss**/
|
||||||
|
page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #17181a;
|
||||||
|
color: #ccc;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 10pt;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 72rpx;
|
||||||
|
border-bottom: 6rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content>swiper {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player {
|
||||||
|
background: #222;
|
||||||
|
border-top: 1px solid #252525;
|
||||||
|
height: 112rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #c25b5b;
|
||||||
|
border-bottom-color: #c25b5b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
color: transparent;
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* 轮播图 */
|
||||||
|
|
||||||
|
.content-info-slide {
|
||||||
|
height: 302rpx;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-slide image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 功能按钮 */
|
||||||
|
|
||||||
|
.content-info-portal {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-portal>view {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 11pt;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-portal image {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
display: block;
|
||||||
|
margin: 20rpx auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 热门音乐 */
|
||||||
|
|
||||||
|
.content-info-list {
|
||||||
|
font-size: 11pt;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-list>.list-title {
|
||||||
|
margin: 20rpx 35rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-list>.list-inner {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-list>.list-inner>.list-item {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-list>.list-inner>.list-item>image {
|
||||||
|
display: block;
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
border: 1rpx solid #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-info-list>.list-inner>.list-item>view {
|
||||||
|
width: 200rpx;
|
||||||
|
margin: 10rpx auto;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 播放器 */
|
||||||
|
|
||||||
|
.content-play {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-play-info>view {
|
||||||
|
color: #888;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部播放器 */
|
||||||
|
|
||||||
|
.player {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #222;
|
||||||
|
border-top: 1px solid #252525;
|
||||||
|
height: 112rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-cover {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-left: 15rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-info {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 10pt;
|
||||||
|
line-height: 38rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-info-singer {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-controls image {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 显示专辑页面样式 */
|
||||||
|
|
||||||
|
.content-play-cover image {
|
||||||
|
animation: rotateImage 10s linear infinite;
|
||||||
|
width: 400rpx;
|
||||||
|
height: 400rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotateImage {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 播放进度和时间 */
|
||||||
|
|
||||||
|
.content-play-progress {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 35rpx;
|
||||||
|
font-size: 9pt;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-play-progress>view {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 播放列表 */
|
||||||
|
|
||||||
|
.playlist-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1rpx solid #333;
|
||||||
|
height: 112rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlist-cover {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
margin-left: 15rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
border: 1px solid #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlist-info {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 10pt;
|
||||||
|
line-height: 38rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
padding-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlist-info-singer {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playlist-controls {
|
||||||
|
font-size: 10pt;
|
||||||
|
margin-right: 50rpx;
|
||||||
|
color: #c25b5b;
|
||||||
|
}
|
||||||
|
.playlist-controls image{
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<view class="content-play">
|
||||||
|
<!-- 音乐信息 -->
|
||||||
|
<view class="content-play-form">
|
||||||
|
<text>{{play.title}}</text>
|
||||||
|
<view>--{{play.singer}}--</view>
|
||||||
|
</view>
|
||||||
|
<!-- 专辑封面 -->
|
||||||
|
<view class="content-play-cover">
|
||||||
|
<image src="{{play.coverImgURL}}" style="animation-play-state: {{state}};"/>
|
||||||
|
</view>
|
||||||
|
<!-- 播放进度与时间 -->
|
||||||
|
<view class="content-play-progress">
|
||||||
|
<text>{{play.currentTime}}</text>
|
||||||
|
<view>
|
||||||
|
<slider bindchange="sliderChange" bindchanging="sliderChanging" activeColor="#d33a31" block-size="12" backgroundColor="#dadada" value="{{play.percent}}"/>
|
||||||
|
</view>
|
||||||
|
<text>{{play.duration}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
@ -0,0 +1,12 @@
|
|||||||
|
<scroll-view class="content-playlist" scroll-y>
|
||||||
|
<view class="playlist-item" wx:for="{{ playlist }}" wx:key="id" bindtap="change" data-index="{{ index }}">
|
||||||
|
<image class="playlist-cover" src="{{ item.coverImgURL }}" />
|
||||||
|
<view class="playlist-info">
|
||||||
|
<view class="playlist-info-title">{{ item.title }}</view>
|
||||||
|
<view class="playlist-info-singer">{{ item.singer }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="playlist-controls">
|
||||||
|
<text wx:if="{{ index == playIndex }}">正在播放</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 124 KiB |
After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 28 KiB |
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compileType": "miniprogram",
|
||||||
|
"libVersion": "trial",
|
||||||
|
"packOptions": {
|
||||||
|
"ignore": [],
|
||||||
|
"include": []
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"coverView": true,
|
||||||
|
"es6": true,
|
||||||
|
"postcss": true,
|
||||||
|
"minified": true,
|
||||||
|
"enhance": true,
|
||||||
|
"showShadowRootInWxmlPanel": true,
|
||||||
|
"packNpmRelationList": [],
|
||||||
|
"babelSetting": {
|
||||||
|
"ignore": [],
|
||||||
|
"disablePlugins": [],
|
||||||
|
"outputPath": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"condition": {},
|
||||||
|
"editorSetting": {
|
||||||
|
"tabIndent": "auto",
|
||||||
|
"tabSize": 2
|
||||||
|
},
|
||||||
|
"appid": "wxc15fead6ca65fb7b"
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||||
|
"rules": [{
|
||||||
|
"action": "allow",
|
||||||
|
"page": "*"
|
||||||
|
}]
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
const formatTime = date => {
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = date.getMonth() + 1
|
||||||
|
const day = date.getDate()
|
||||||
|
const hour = date.getHours()
|
||||||
|
const minute = date.getMinutes()
|
||||||
|
const second = date.getSeconds()
|
||||||
|
|
||||||
|
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatNumber = n => {
|
||||||
|
n = n.toString()
|
||||||
|
return n[1] ? n : `0${n}`
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
formatTime
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../mime/cli.js" "$@"
|
||||||
|
fi
|
@ -0,0 +1,17 @@
|
|||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
@ -0,0 +1,856 @@
|
|||||||
|
{
|
||||||
|
"name": "music",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
|
},
|
||||||
|
"node_modules/batch": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY="
|
||||||
|
},
|
||||||
|
"node_modules/body-parser": {
|
||||||
|
"version": "1.20.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.0.tgz",
|
||||||
|
"integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"destroy": "1.2.0",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"qs": "6.10.3",
|
||||||
|
"raw-body": "2.5.1",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/body-parser/node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bytes": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/call-bind": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"get-intrinsic": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition": {
|
||||||
|
"version": "0.5.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
|
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "5.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/content-disposition/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"node_modules/content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/destroy": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8",
|
||||||
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||||
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express": {
|
||||||
|
"version": "4.18.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/express/-/express-4.18.1.tgz",
|
||||||
|
"integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.8",
|
||||||
|
"array-flatten": "1.1.1",
|
||||||
|
"body-parser": "1.20.0",
|
||||||
|
"content-disposition": "0.5.4",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"cookie": "0.5.0",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"finalhandler": "1.2.0",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"merge-descriptors": "1.0.1",
|
||||||
|
"methods": "~1.1.2",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"path-to-regexp": "0.1.7",
|
||||||
|
"proxy-addr": "~2.0.7",
|
||||||
|
"qs": "6.10.3",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"safe-buffer": "5.2.1",
|
||||||
|
"send": "0.18.0",
|
||||||
|
"serve-static": "1.15.0",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"type-is": "~1.6.18",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/express/node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fd-slicer": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||||
|
"dependencies": {
|
||||||
|
"pend": "~1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/finalhandler/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/forwarded": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"has": "^1.0.3",
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "1.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||||
|
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.0",
|
||||||
|
"statuses": ">= 1.4.0 < 2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/iconv-lite": {
|
||||||
|
"version": "0.4.24",
|
||||||
|
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
|
"dependencies": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"node_modules/ipaddr.js": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
|
},
|
||||||
|
"node_modules/methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"node_modules/multiparty": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-AvESCnNoQlZiOfP9R4mxN8M9csy2L16EIbWIkt3l4FuGti9kXBS8QVzlfyg4HEnarJhrzZilgNFlZtqmoiAIIA==",
|
||||||
|
"dependencies": {
|
||||||
|
"fd-slicer": "1.1.0",
|
||||||
|
"http-errors": "~1.7.0",
|
||||||
|
"safe-buffer": "5.1.2",
|
||||||
|
"uid-safe": "2.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/multiparty/node_modules/http-errors": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.0",
|
||||||
|
"statuses": ">= 1.5.0 < 2",
|
||||||
|
"toidentifier": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/multiparty/node_modules/statuses": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.12.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz",
|
||||||
|
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
|
||||||
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/parseurl": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
|
},
|
||||||
|
"node_modules/pend": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
|
||||||
|
},
|
||||||
|
"node_modules/proxy-addr": {
|
||||||
|
"version": "2.0.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
|
"dependencies": {
|
||||||
|
"forwarded": "0.2.0",
|
||||||
|
"ipaddr.js": "1.9.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.10.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz",
|
||||||
|
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/random-bytes": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
|
||||||
|
"dependencies": {
|
||||||
|
"bytes": "3.1.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"iconv-lite": "0.4.24",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/raw-body/node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
},
|
||||||
|
"node_modules/safer-buffer": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "0.18.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz",
|
||||||
|
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"destroy": "1.2.0",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "2.0.0",
|
||||||
|
"mime": "1.6.0",
|
||||||
|
"ms": "2.1.3",
|
||||||
|
"on-finished": "2.4.1",
|
||||||
|
"range-parser": "~1.2.1",
|
||||||
|
"statuses": "2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/http-errors": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/statuses": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/send/node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-index": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
|
||||||
|
"integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"batch": "0.6.1",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"http-errors": "~1.6.2",
|
||||||
|
"mime-types": "~2.1.17",
|
||||||
|
"parseurl": "~1.3.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/serve-static": {
|
||||||
|
"version": "1.15.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz",
|
||||||
|
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
||||||
|
"dependencies": {
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"parseurl": "~1.3.3",
|
||||||
|
"send": "0.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.0",
|
||||||
|
"get-intrinsic": "^1.0.2",
|
||||||
|
"object-inspect": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-is": {
|
||||||
|
"version": "1.6.18",
|
||||||
|
"resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||||
|
"dependencies": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.24"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uid-safe": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
|
||||||
|
"dependencies": {
|
||||||
|
"random-bytes": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,243 @@
|
|||||||
|
1.3.8 / 2022-02-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.34
|
||||||
|
- deps: mime-db@~1.51.0
|
||||||
|
* deps: negotiator@0.6.3
|
||||||
|
|
||||||
|
1.3.7 / 2019-04-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.6.2
|
||||||
|
- Fix sorting charset, encoding, and language with extra parameters
|
||||||
|
|
||||||
|
1.3.6 / 2019-04-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.24
|
||||||
|
- deps: mime-db@~1.40.0
|
||||||
|
|
||||||
|
1.3.5 / 2018-02-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.18
|
||||||
|
- deps: mime-db@~1.33.0
|
||||||
|
|
||||||
|
1.3.4 / 2017-08-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.16
|
||||||
|
- deps: mime-db@~1.29.0
|
||||||
|
|
||||||
|
1.3.3 / 2016-05-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.11
|
||||||
|
- deps: mime-db@~1.23.0
|
||||||
|
* deps: negotiator@0.6.1
|
||||||
|
- perf: improve `Accept` parsing speed
|
||||||
|
- perf: improve `Accept-Charset` parsing speed
|
||||||
|
- perf: improve `Accept-Encoding` parsing speed
|
||||||
|
- perf: improve `Accept-Language` parsing speed
|
||||||
|
|
||||||
|
1.3.2 / 2016-03-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.10
|
||||||
|
- Fix extension of `application/dash+xml`
|
||||||
|
- Update primary extension for `audio/mp4`
|
||||||
|
- deps: mime-db@~1.22.0
|
||||||
|
|
||||||
|
1.3.1 / 2016-01-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.9
|
||||||
|
- deps: mime-db@~1.21.0
|
||||||
|
|
||||||
|
1.3.0 / 2015-09-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.7
|
||||||
|
- deps: mime-db@~1.19.0
|
||||||
|
* deps: negotiator@0.6.0
|
||||||
|
- Fix including type extensions in parameters in `Accept` parsing
|
||||||
|
- Fix parsing `Accept` parameters with quoted equals
|
||||||
|
- Fix parsing `Accept` parameters with quoted semicolons
|
||||||
|
- Lazy-load modules from main entry point
|
||||||
|
- perf: delay type concatenation until needed
|
||||||
|
- perf: enable strict mode
|
||||||
|
- perf: hoist regular expressions
|
||||||
|
- perf: remove closures getting spec properties
|
||||||
|
- perf: remove a closure from media type parsing
|
||||||
|
- perf: remove property delete from media type parsing
|
||||||
|
|
||||||
|
1.2.13 / 2015-09-06
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.6
|
||||||
|
- deps: mime-db@~1.18.0
|
||||||
|
|
||||||
|
1.2.12 / 2015-07-30
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.4
|
||||||
|
- deps: mime-db@~1.16.0
|
||||||
|
|
||||||
|
1.2.11 / 2015-07-16
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.3
|
||||||
|
- deps: mime-db@~1.15.0
|
||||||
|
|
||||||
|
1.2.10 / 2015-07-01
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.2
|
||||||
|
- deps: mime-db@~1.14.0
|
||||||
|
|
||||||
|
1.2.9 / 2015-06-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.1
|
||||||
|
- perf: fix deopt during mapping
|
||||||
|
|
||||||
|
1.2.8 / 2015-06-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.1.0
|
||||||
|
- deps: mime-db@~1.13.0
|
||||||
|
* perf: avoid argument reassignment & argument slice
|
||||||
|
* perf: avoid negotiator recursive construction
|
||||||
|
* perf: enable strict mode
|
||||||
|
* perf: remove unnecessary bitwise operator
|
||||||
|
|
||||||
|
1.2.7 / 2015-05-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.5.3
|
||||||
|
- Fix media type parameter matching to be case-insensitive
|
||||||
|
|
||||||
|
1.2.6 / 2015-05-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.11
|
||||||
|
- deps: mime-db@~1.9.1
|
||||||
|
* deps: negotiator@0.5.2
|
||||||
|
- Fix comparing media types with quoted values
|
||||||
|
- Fix splitting media types with quoted commas
|
||||||
|
|
||||||
|
1.2.5 / 2015-03-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.10
|
||||||
|
- deps: mime-db@~1.8.0
|
||||||
|
|
||||||
|
1.2.4 / 2015-02-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Support Node.js 0.6
|
||||||
|
* deps: mime-types@~2.0.9
|
||||||
|
- deps: mime-db@~1.7.0
|
||||||
|
* deps: negotiator@0.5.1
|
||||||
|
- Fix preference sorting to be stable for long acceptable lists
|
||||||
|
|
||||||
|
1.2.3 / 2015-01-31
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.8
|
||||||
|
- deps: mime-db@~1.6.0
|
||||||
|
|
||||||
|
1.2.2 / 2014-12-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.7
|
||||||
|
- deps: mime-db@~1.5.0
|
||||||
|
|
||||||
|
1.2.1 / 2014-12-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.5
|
||||||
|
- deps: mime-db@~1.3.1
|
||||||
|
|
||||||
|
1.2.0 / 2014-12-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.5.0
|
||||||
|
- Fix list return order when large accepted list
|
||||||
|
- Fix missing identity encoding when q=0 exists
|
||||||
|
- Remove dynamic building of Negotiator class
|
||||||
|
|
||||||
|
1.1.4 / 2014-12-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.4
|
||||||
|
- deps: mime-db@~1.3.0
|
||||||
|
|
||||||
|
1.1.3 / 2014-11-09
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.3
|
||||||
|
- deps: mime-db@~1.2.0
|
||||||
|
|
||||||
|
1.1.2 / 2014-10-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.9
|
||||||
|
- Fix error when media type has invalid parameter
|
||||||
|
|
||||||
|
1.1.1 / 2014-09-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: mime-types@~2.0.2
|
||||||
|
- deps: mime-db@~1.1.0
|
||||||
|
* deps: negotiator@0.4.8
|
||||||
|
- Fix all negotiations to be case-insensitive
|
||||||
|
- Stable sort preferences of same quality according to client order
|
||||||
|
|
||||||
|
1.1.0 / 2014-09-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* update `mime-types`
|
||||||
|
|
||||||
|
1.0.7 / 2014-07-04
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix wrong type returned from `type` when match after unknown extension
|
||||||
|
|
||||||
|
1.0.6 / 2014-06-24
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.7
|
||||||
|
|
||||||
|
1.0.5 / 2014-06-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* fix crash when unknown extension given
|
||||||
|
|
||||||
|
1.0.4 / 2014-06-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* use `mime-types`
|
||||||
|
|
||||||
|
1.0.3 / 2014-06-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: negotiator@0.4.6
|
||||||
|
- Order by specificity when quality is the same
|
||||||
|
|
||||||
|
1.0.2 / 2014-05-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix interpretation when header not in request
|
||||||
|
* deps: pin negotiator@0.4.5
|
||||||
|
|
||||||
|
1.0.1 / 2014-01-18
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Identity encoding isn't always acceptable
|
||||||
|
* deps: negotiator@~0.4.0
|
||||||
|
|
||||||
|
1.0.0 / 2013-12-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Genesis
|
@ -0,0 +1,23 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||||
|
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -0,0 +1,140 @@
|
|||||||
|
# accepts
|
||||||
|
|
||||||
|
[![NPM Version][npm-version-image]][npm-url]
|
||||||
|
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||||
|
[![Node.js Version][node-version-image]][node-version-url]
|
||||||
|
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||||
|
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||||
|
|
||||||
|
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
|
||||||
|
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||||
|
|
||||||
|
In addition to negotiator, it allows:
|
||||||
|
|
||||||
|
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
|
||||||
|
as well as `('text/html', 'application/json')`.
|
||||||
|
- Allows type shorthands such as `json`.
|
||||||
|
- Returns `false` when no types match
|
||||||
|
- Treats non-existent headers as `*`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
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):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm install accepts
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```js
|
||||||
|
var accepts = require('accepts')
|
||||||
|
```
|
||||||
|
|
||||||
|
### accepts(req)
|
||||||
|
|
||||||
|
Create a new `Accepts` object for the given `req`.
|
||||||
|
|
||||||
|
#### .charset(charsets)
|
||||||
|
|
||||||
|
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .charsets()
|
||||||
|
|
||||||
|
Return the charsets that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .encoding(encodings)
|
||||||
|
|
||||||
|
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .encodings()
|
||||||
|
|
||||||
|
Return the encodings that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .language(languages)
|
||||||
|
|
||||||
|
Return the first accepted language. If nothing in `languages` is accepted,
|
||||||
|
then `false` is returned.
|
||||||
|
|
||||||
|
#### .languages()
|
||||||
|
|
||||||
|
Return the languages that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
#### .type(types)
|
||||||
|
|
||||||
|
Return the first accepted type (and it is returned as the same text as what
|
||||||
|
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||||
|
is returned.
|
||||||
|
|
||||||
|
The `types` array can contain full MIME types or file extensions. Any value
|
||||||
|
that is not a full MIME types is passed to `require('mime-types').lookup`.
|
||||||
|
|
||||||
|
#### .types()
|
||||||
|
|
||||||
|
Return the types that the request accepts, in the order of the client's
|
||||||
|
preference (most preferred first).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Simple type negotiation
|
||||||
|
|
||||||
|
This simple example shows how to use `accepts` to return a different typed
|
||||||
|
respond body based on what the client wants to accept. The server lists it's
|
||||||
|
preferences in order and will get back the best match between the client and
|
||||||
|
server.
|
||||||
|
|
||||||
|
```js
|
||||||
|
var accepts = require('accepts')
|
||||||
|
var http = require('http')
|
||||||
|
|
||||||
|
function app (req, res) {
|
||||||
|
var accept = accepts(req)
|
||||||
|
|
||||||
|
// the order of this list is significant; should be server preferred order
|
||||||
|
switch (accept.type(['json', 'html'])) {
|
||||||
|
case 'json':
|
||||||
|
res.setHeader('Content-Type', 'application/json')
|
||||||
|
res.write('{"hello":"world!"}')
|
||||||
|
break
|
||||||
|
case 'html':
|
||||||
|
res.setHeader('Content-Type', 'text/html')
|
||||||
|
res.write('<b>hello, world!</b>')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
// the fallback is text/plain, so no need to specify it above
|
||||||
|
res.setHeader('Content-Type', 'text/plain')
|
||||||
|
res.write('hello, world!')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
res.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
http.createServer(app).listen(3000)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can test this out with the cURL program:
|
||||||
|
```sh
|
||||||
|
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
||||||
|
|
||||||
|
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
|
||||||
|
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
|
||||||
|
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
|
||||||
|
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
|
||||||
|
[node-version-image]: https://badgen.net/npm/node/accepts
|
||||||
|
[node-version-url]: https://nodejs.org/en/download
|
||||||
|
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
|
||||||
|
[npm-url]: https://npmjs.org/package/accepts
|
||||||
|
[npm-version-image]: https://badgen.net/npm/v/accepts
|
@ -0,0 +1,238 @@
|
|||||||
|
/*!
|
||||||
|
* accepts
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Negotiator = require('negotiator')
|
||||||
|
var mime = require('mime-types')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module exports.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Accepts
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Accepts object for the given req.
|
||||||
|
*
|
||||||
|
* @param {object} req
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Accepts (req) {
|
||||||
|
if (!(this instanceof Accepts)) {
|
||||||
|
return new Accepts(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.headers = req.headers
|
||||||
|
this.negotiator = new Negotiator(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given `type(s)` is acceptable, returning
|
||||||
|
* the best match when true, otherwise `undefined`, in which
|
||||||
|
* case you should respond with 406 "Not Acceptable".
|
||||||
|
*
|
||||||
|
* The `type` value may be a single mime type string
|
||||||
|
* such as "application/json", the extension name
|
||||||
|
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||||
|
* or array is given the _best_ match, if any is returned.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* // Accept: text/html
|
||||||
|
* this.types('html');
|
||||||
|
* // => "html"
|
||||||
|
*
|
||||||
|
* // Accept: text/*, application/json
|
||||||
|
* this.types('html');
|
||||||
|
* // => "html"
|
||||||
|
* this.types('text/html');
|
||||||
|
* // => "text/html"
|
||||||
|
* this.types('json', 'text');
|
||||||
|
* // => "json"
|
||||||
|
* this.types('application/json');
|
||||||
|
* // => "application/json"
|
||||||
|
*
|
||||||
|
* // Accept: text/*, application/json
|
||||||
|
* this.types('image/png');
|
||||||
|
* this.types('png');
|
||||||
|
* // => undefined
|
||||||
|
*
|
||||||
|
* // Accept: text/*;q=.5, application/json
|
||||||
|
* this.types(['html', 'json']);
|
||||||
|
* this.types('html', 'json');
|
||||||
|
* // => "json"
|
||||||
|
*
|
||||||
|
* @param {String|Array} types...
|
||||||
|
* @return {String|Array|Boolean}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.type =
|
||||||
|
Accepts.prototype.types = function (types_) {
|
||||||
|
var types = types_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (types && !Array.isArray(types)) {
|
||||||
|
types = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < types.length; i++) {
|
||||||
|
types[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no types, return all requested types
|
||||||
|
if (!types || types.length === 0) {
|
||||||
|
return this.negotiator.mediaTypes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// no accept header, return first given type
|
||||||
|
if (!this.headers.accept) {
|
||||||
|
return types[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var mimes = types.map(extToMime)
|
||||||
|
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
|
||||||
|
var first = accepts[0]
|
||||||
|
|
||||||
|
return first
|
||||||
|
? types[mimes.indexOf(first)]
|
||||||
|
: false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted encodings or best fit based on `encodings`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Encoding: gzip, deflate`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['gzip', 'deflate']
|
||||||
|
*
|
||||||
|
* @param {String|Array} encodings...
|
||||||
|
* @return {String|Array}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.encoding =
|
||||||
|
Accepts.prototype.encodings = function (encodings_) {
|
||||||
|
var encodings = encodings_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (encodings && !Array.isArray(encodings)) {
|
||||||
|
encodings = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < encodings.length; i++) {
|
||||||
|
encodings[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no encodings, return all requested encodings
|
||||||
|
if (!encodings || encodings.length === 0) {
|
||||||
|
return this.negotiator.encodings()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.encodings(encodings)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted charsets or best fit based on `charsets`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||||
|
*
|
||||||
|
* @param {String|Array} charsets...
|
||||||
|
* @return {String|Array}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.charset =
|
||||||
|
Accepts.prototype.charsets = function (charsets_) {
|
||||||
|
var charsets = charsets_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (charsets && !Array.isArray(charsets)) {
|
||||||
|
charsets = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < charsets.length; i++) {
|
||||||
|
charsets[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no charsets, return all requested charsets
|
||||||
|
if (!charsets || charsets.length === 0) {
|
||||||
|
return this.negotiator.charsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.charsets(charsets)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return accepted languages or best fit based on `langs`.
|
||||||
|
*
|
||||||
|
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||||
|
* an array sorted by quality is returned:
|
||||||
|
*
|
||||||
|
* ['es', 'pt', 'en']
|
||||||
|
*
|
||||||
|
* @param {String|Array} langs...
|
||||||
|
* @return {Array|String}
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Accepts.prototype.lang =
|
||||||
|
Accepts.prototype.langs =
|
||||||
|
Accepts.prototype.language =
|
||||||
|
Accepts.prototype.languages = function (languages_) {
|
||||||
|
var languages = languages_
|
||||||
|
|
||||||
|
// support flattened arguments
|
||||||
|
if (languages && !Array.isArray(languages)) {
|
||||||
|
languages = new Array(arguments.length)
|
||||||
|
for (var i = 0; i < languages.length; i++) {
|
||||||
|
languages[i] = arguments[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no languages, return all requested languages
|
||||||
|
if (!languages || languages.length === 0) {
|
||||||
|
return this.negotiator.languages()
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.negotiator.languages(languages)[0] || false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert extnames to mime.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {String}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function extToMime (type) {
|
||||||
|
return type.indexOf('/') === -1
|
||||||
|
? mime.lookup(type)
|
||||||
|
: type
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if mime is valid.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {String}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function validMime (type) {
|
||||||
|
return typeof type === 'string'
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
{
|
||||||
|
"name": "accepts",
|
||||||
|
"description": "Higher-level content negotiation",
|
||||||
|
"version": "1.3.8",
|
||||||
|
"contributors": [
|
||||||
|
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||||
|
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "jshttp/accepts",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"deep-equal": "1.0.1",
|
||||||
|
"eslint": "7.32.0",
|
||||||
|
"eslint-config-standard": "14.1.1",
|
||||||
|
"eslint-plugin-import": "2.25.4",
|
||||||
|
"eslint-plugin-markdown": "2.2.1",
|
||||||
|
"eslint-plugin-node": "11.1.0",
|
||||||
|
"eslint-plugin-promise": "4.3.1",
|
||||||
|
"eslint-plugin-standard": "4.1.0",
|
||||||
|
"mocha": "9.2.0",
|
||||||
|
"nyc": "15.1.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"LICENSE",
|
||||||
|
"HISTORY.md",
|
||||||
|
"index.js"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint .",
|
||||||
|
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||||
|
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||||
|
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"content",
|
||||||
|
"negotiation",
|
||||||
|
"accept",
|
||||||
|
"accepts"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -0,0 +1,43 @@
|
|||||||
|
# Array Flatten
|
||||||
|
|
||||||
|
[![NPM version][npm-image]][npm-url]
|
||||||
|
[![NPM downloads][downloads-image]][downloads-url]
|
||||||
|
[![Build status][travis-image]][travis-url]
|
||||||
|
[![Test coverage][coveralls-image]][coveralls-url]
|
||||||
|
|
||||||
|
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install array-flatten --save
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var flatten = require('array-flatten')
|
||||||
|
|
||||||
|
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
|
||||||
|
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
|
||||||
|
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
flatten(arguments) //=> [1, 2, 3]
|
||||||
|
})(1, [2, 3])
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
|
||||||
|
[npm-url]: https://npmjs.org/package/array-flatten
|
||||||
|
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
|
||||||
|
[downloads-url]: https://npmjs.org/package/array-flatten
|
||||||
|
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
|
||||||
|
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
|
||||||
|
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
|
||||||
|
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master
|
@ -0,0 +1,64 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `arrayFlatten`.
|
||||||
|
*/
|
||||||
|
module.exports = arrayFlatten
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive flatten function with depth.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Array} result
|
||||||
|
* @param {Number} depth
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function flattenWithDepth (array, result, depth) {
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
var value = array[i]
|
||||||
|
|
||||||
|
if (depth > 0 && Array.isArray(value)) {
|
||||||
|
flattenWithDepth(value, result, depth - 1)
|
||||||
|
} else {
|
||||||
|
result.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive flatten function. Omitting depth is slightly faster.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Array} result
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function flattenForever (array, result) {
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
var value = array[i]
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
flattenForever(value, result)
|
||||||
|
} else {
|
||||||
|
result.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten an array, with the ability to define a depth.
|
||||||
|
*
|
||||||
|
* @param {Array} array
|
||||||
|
* @param {Number} depth
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
function arrayFlatten (array, depth) {
|
||||||
|
if (depth == null) {
|
||||||
|
return flattenForever(array, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return flattenWithDepth(array, [], depth)
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "array-flatten",
|
||||||
|
"version": "1.1.1",
|
||||||
|
"description": "Flatten an array of nested arrays into a single flat array",
|
||||||
|
"main": "array-flatten.js",
|
||||||
|
"files": [
|
||||||
|
"array-flatten.js",
|
||||||
|
"LICENSE"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "istanbul cover _mocha -- -R spec"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git://github.com/blakeembrey/array-flatten.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"array",
|
||||||
|
"flatten",
|
||||||
|
"arguments",
|
||||||
|
"depth"
|
||||||
|
],
|
||||||
|
"author": {
|
||||||
|
"name": "Blake Embrey",
|
||||||
|
"email": "hello@blakeembrey.com",
|
||||||
|
"url": "http://blakeembrey.me"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/blakeembrey/array-flatten/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/blakeembrey/array-flatten",
|
||||||
|
"devDependencies": {
|
||||||
|
"istanbul": "^0.3.13",
|
||||||
|
"mocha": "^2.2.4",
|
||||||
|
"pre-commit": "^1.0.7",
|
||||||
|
"standard": "^3.7.3"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
support
|
||||||
|
test
|
||||||
|
examples
|
||||||
|
*.sock
|
@ -0,0 +1,93 @@
|
|||||||
|
0.6.1 / 2017-05-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* fix `process.nextTick` detection in Node.js
|
||||||
|
|
||||||
|
0.6.0 / 2017-03-25
|
||||||
|
==================
|
||||||
|
|
||||||
|
* always invoke end callback asynchronously
|
||||||
|
* fix compatibility with component v1
|
||||||
|
* fix license field
|
||||||
|
|
||||||
|
0.5.3 / 2015-10-01
|
||||||
|
==================
|
||||||
|
|
||||||
|
* fix for browserify
|
||||||
|
|
||||||
|
0.5.2 / 2014-12-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add brower field
|
||||||
|
* add license to package.json
|
||||||
|
|
||||||
|
0.5.1 / 2014-06-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add repository field to readme (exciting)
|
||||||
|
|
||||||
|
0.5.0 / 2013-07-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add `.throws(true)` to opt-in to responding with an array of error objects
|
||||||
|
* make `new` optional
|
||||||
|
|
||||||
|
0.4.0 / 2013-06-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add catching of immediate callback errors
|
||||||
|
|
||||||
|
0.3.2 / 2013-03-15
|
||||||
|
==================
|
||||||
|
|
||||||
|
* remove Emitter call in constructor
|
||||||
|
|
||||||
|
0.3.1 / 2013-03-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add Emitter() mixin for client. Closes #8
|
||||||
|
|
||||||
|
0.3.0 / 2013-03-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add component.json
|
||||||
|
* add result example
|
||||||
|
* add .concurrency support
|
||||||
|
* add concurrency example
|
||||||
|
* add parallel example
|
||||||
|
|
||||||
|
0.2.1 / 2012-11-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add .start, .end, and .duration properties
|
||||||
|
* change dependencies to devDependencies
|
||||||
|
|
||||||
|
0.2.0 / 2012-10-04
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add progress events. Closes #5 (__BREAKING CHANGE__)
|
||||||
|
|
||||||
|
0.1.1 / 2012-07-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* change "complete" event to "progress"
|
||||||
|
|
||||||
|
0.1.0 / 2012-07-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* add Emitter inheritance and emit "complete" [burcu]
|
||||||
|
|
||||||
|
0.0.3 / 2012-06-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Callback results should be in the order of the queued functions.
|
||||||
|
|
||||||
|
0.0.2 / 2012-02-12
|
||||||
|
==================
|
||||||
|
|
||||||
|
* any node
|
||||||
|
|
||||||
|
0.0.1 / 2010-01-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Initial release
|
@ -0,0 +1,22 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2013 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.
|
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
test:
|
||||||
|
@./node_modules/.bin/mocha \
|
||||||
|
--require should
|
||||||
|
|
||||||
|
.PHONY: test
|
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
# batch
|
||||||
|
|
||||||
|
Simple async batch with concurrency control and progress reporting.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm install batch
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```js
|
||||||
|
var Batch = require('batch')
|
||||||
|
, batch = new Batch;
|
||||||
|
|
||||||
|
batch.concurrency(4);
|
||||||
|
|
||||||
|
ids.forEach(function(id){
|
||||||
|
batch.push(function(done){
|
||||||
|
User.get(id, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
batch.on('progress', function(e){
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
batch.end(function(err, users){
|
||||||
|
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Progress events
|
||||||
|
|
||||||
|
Contain the "job" index, response value, duration information, and completion data.
|
||||||
|
|
||||||
|
```
|
||||||
|
{ index: 1,
|
||||||
|
value: 'bar',
|
||||||
|
pending: 2,
|
||||||
|
total: 3,
|
||||||
|
complete: 2,
|
||||||
|
percent: 66,
|
||||||
|
start: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT),
|
||||||
|
end: Thu Oct 04 2012 12:25:53 GMT-0700 (PDT),
|
||||||
|
duration: 0 }
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "batch",
|
||||||
|
"repo": "visionmedia/batch",
|
||||||
|
"description": "Async task batching",
|
||||||
|
"version": "0.6.1",
|
||||||
|
"keywords": ["batch", "async", "utility", "concurrency", "concurrent"],
|
||||||
|
"dependencies": {
|
||||||
|
"component/emitter": "*"
|
||||||
|
},
|
||||||
|
"development": {},
|
||||||
|
"scripts": [
|
||||||
|
"index.js"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
if (!EventEmitter) throw new Error();
|
||||||
|
} catch (err) {
|
||||||
|
var Emitter = require('emitter');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var defer = typeof process !== 'undefined' && process && typeof process.nextTick === 'function'
|
||||||
|
? process.nextTick
|
||||||
|
: function(fn){ setTimeout(fn); };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noop.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function noop(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `Batch`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Batch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Batch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Batch() {
|
||||||
|
if (!(this instanceof Batch)) return new Batch;
|
||||||
|
this.fns = [];
|
||||||
|
this.concurrency(Infinity);
|
||||||
|
this.throws(true);
|
||||||
|
for (var i = 0, len = arguments.length; i < len; ++i) {
|
||||||
|
this.push(arguments[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `EventEmitter.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (EventEmitter) {
|
||||||
|
Batch.prototype.__proto__ = EventEmitter.prototype;
|
||||||
|
} else {
|
||||||
|
Emitter(Batch.prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set concurrency to `n`.
|
||||||
|
*
|
||||||
|
* @param {Number} n
|
||||||
|
* @return {Batch}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Batch.prototype.concurrency = function(n){
|
||||||
|
this.n = n;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a function.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Batch}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Batch.prototype.push = function(fn){
|
||||||
|
this.fns.push(fn);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set wether Batch will or will not throw up.
|
||||||
|
*
|
||||||
|
* @param {Boolean} throws
|
||||||
|
* @return {Batch}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
Batch.prototype.throws = function(throws) {
|
||||||
|
this.e = !!throws;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute all queued functions in parallel,
|
||||||
|
* executing `cb(err, results)`.
|
||||||
|
*
|
||||||
|
* @param {Function} cb
|
||||||
|
* @return {Batch}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Batch.prototype.end = function(cb){
|
||||||
|
var self = this
|
||||||
|
, total = this.fns.length
|
||||||
|
, pending = total
|
||||||
|
, results = []
|
||||||
|
, errors = []
|
||||||
|
, cb = cb || noop
|
||||||
|
, fns = this.fns
|
||||||
|
, max = this.n
|
||||||
|
, throws = this.e
|
||||||
|
, index = 0
|
||||||
|
, done;
|
||||||
|
|
||||||
|
// empty
|
||||||
|
if (!fns.length) return defer(function(){
|
||||||
|
cb(null, results);
|
||||||
|
});
|
||||||
|
|
||||||
|
// process
|
||||||
|
function next() {
|
||||||
|
var i = index++;
|
||||||
|
var fn = fns[i];
|
||||||
|
if (!fn) return;
|
||||||
|
var start = new Date;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fn(callback);
|
||||||
|
} catch (err) {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
function callback(err, res){
|
||||||
|
if (done) return;
|
||||||
|
if (err && throws) return done = true, defer(function(){
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
var complete = total - pending + 1;
|
||||||
|
var end = new Date;
|
||||||
|
|
||||||
|
results[i] = res;
|
||||||
|
errors[i] = err;
|
||||||
|
|
||||||
|
self.emit('progress', {
|
||||||
|
index: i,
|
||||||
|
value: res,
|
||||||
|
error: err,
|
||||||
|
pending: pending,
|
||||||
|
total: total,
|
||||||
|
complete: complete,
|
||||||
|
percent: complete / total * 100 | 0,
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
duration: end - start
|
||||||
|
});
|
||||||
|
|
||||||
|
if (--pending) next();
|
||||||
|
else defer(function(){
|
||||||
|
if(!throws) cb(errors, results);
|
||||||
|
else cb(null, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// concurrency
|
||||||
|
for (var i = 0; i < fns.length; i++) {
|
||||||
|
if (i == max) break;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "batch",
|
||||||
|
"description": "Simple async batch with concurrency control and progress reporting.",
|
||||||
|
"version": "0.6.1",
|
||||||
|
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"mocha": "*",
|
||||||
|
"should": "*"
|
||||||
|
},
|
||||||
|
"main": "index",
|
||||||
|
"browser": {
|
||||||
|
"emitter": "events"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/visionmedia/batch.git"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,651 @@
|
|||||||
|
1.20.0 / 2022-04-02
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Fix error message for json parse whitespace in `strict`
|
||||||
|
* Fix internal error when inflated body exceeds limit
|
||||||
|
* Prevent loss of async hooks context
|
||||||
|
* Prevent hanging when request already read
|
||||||
|
* deps: depd@2.0.0
|
||||||
|
- Replace internal `eval` usage with `Function` constructor
|
||||||
|
- Use instance methods on `process` to check for listeners
|
||||||
|
* deps: http-errors@2.0.0
|
||||||
|
- deps: depd@2.0.0
|
||||||
|
- deps: statuses@2.0.1
|
||||||
|
* deps: on-finished@2.4.1
|
||||||
|
* deps: qs@6.10.3
|
||||||
|
* deps: raw-body@2.5.1
|
||||||
|
- deps: http-errors@2.0.0
|
||||||
|
|
||||||
|
1.19.2 / 2022-02-15
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: bytes@3.1.2
|
||||||
|
* deps: qs@6.9.7
|
||||||
|
* Fix handling of `__proto__` keys
|
||||||
|
* deps: raw-body@2.4.3
|
||||||
|
- deps: bytes@3.1.2
|
||||||
|
|
||||||
|
1.19.1 / 2021-12-10
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: bytes@3.1.1
|
||||||
|
* deps: http-errors@1.8.1
|
||||||
|
- deps: inherits@2.0.4
|
||||||
|
- deps: toidentifier@1.0.1
|
||||||
|
- deps: setprototypeof@1.2.0
|
||||||
|
* deps: qs@6.9.6
|
||||||
|
* deps: raw-body@2.4.2
|
||||||
|
- deps: bytes@3.1.1
|
||||||
|
- deps: http-errors@1.8.1
|
||||||
|
* deps: safe-buffer@5.2.1
|
||||||
|
* deps: type-is@~1.6.18
|
||||||
|
|
||||||
|
1.19.0 / 2019-04-25
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: bytes@3.1.0
|
||||||
|
- Add petabyte (`pb`) support
|
||||||
|
* deps: http-errors@1.7.2
|
||||||
|
- Set constructor name when possible
|
||||||
|
- deps: setprototypeof@1.1.1
|
||||||
|
- deps: statuses@'>= 1.5.0 < 2'
|
||||||
|
* deps: iconv-lite@0.4.24
|
||||||
|
- Added encoding MIK
|
||||||
|
* deps: qs@6.7.0
|
||||||
|
- Fix parsing array brackets after index
|
||||||
|
* deps: raw-body@2.4.0
|
||||||
|
- deps: bytes@3.1.0
|
||||||
|
- deps: http-errors@1.7.2
|
||||||
|
- deps: iconv-lite@0.4.24
|
||||||
|
* deps: type-is@~1.6.17
|
||||||
|
- deps: mime-types@~2.1.24
|
||||||
|
- perf: prevent internal `throw` on invalid type
|
||||||
|
|
||||||
|
1.18.3 / 2018-05-14
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Fix stack trace for strict json parse error
|
||||||
|
* deps: depd@~1.1.2
|
||||||
|
- perf: remove argument reassignment
|
||||||
|
* deps: http-errors@~1.6.3
|
||||||
|
- deps: depd@~1.1.2
|
||||||
|
- deps: setprototypeof@1.1.0
|
||||||
|
- deps: statuses@'>= 1.3.1 < 2'
|
||||||
|
* deps: iconv-lite@0.4.23
|
||||||
|
- Fix loading encoding with year appended
|
||||||
|
- Fix deprecation warnings on Node.js 10+
|
||||||
|
* deps: qs@6.5.2
|
||||||
|
* deps: raw-body@2.3.3
|
||||||
|
- deps: http-errors@1.6.3
|
||||||
|
- deps: iconv-lite@0.4.23
|
||||||
|
* deps: type-is@~1.6.16
|
||||||
|
- deps: mime-types@~2.1.18
|
||||||
|
|
||||||
|
1.18.2 / 2017-09-22
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: debug@2.6.9
|
||||||
|
* perf: remove argument reassignment
|
||||||
|
|
||||||
|
1.18.1 / 2017-09-12
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: content-type@~1.0.4
|
||||||
|
- perf: remove argument reassignment
|
||||||
|
- perf: skip parameter parsing when no parameters
|
||||||
|
* deps: iconv-lite@0.4.19
|
||||||
|
- Fix ISO-8859-1 regression
|
||||||
|
- Update Windows-1255
|
||||||
|
* deps: qs@6.5.1
|
||||||
|
- Fix parsing & compacting very deep objects
|
||||||
|
* deps: raw-body@2.3.2
|
||||||
|
- deps: iconv-lite@0.4.19
|
||||||
|
|
||||||
|
1.18.0 / 2017-09-08
|
||||||
|
===================
|
||||||
|
|
||||||
|
* Fix JSON strict violation error to match native parse error
|
||||||
|
* Include the `body` property on verify errors
|
||||||
|
* Include the `type` property on all generated errors
|
||||||
|
* Use `http-errors` to set status code on errors
|
||||||
|
* deps: bytes@3.0.0
|
||||||
|
* deps: debug@2.6.8
|
||||||
|
* deps: depd@~1.1.1
|
||||||
|
- Remove unnecessary `Buffer` loading
|
||||||
|
* deps: http-errors@~1.6.2
|
||||||
|
- deps: depd@1.1.1
|
||||||
|
* deps: iconv-lite@0.4.18
|
||||||
|
- Add support for React Native
|
||||||
|
- Add a warning if not loaded as utf-8
|
||||||
|
- Fix CESU-8 decoding in Node.js 8
|
||||||
|
- Improve speed of ISO-8859-1 encoding
|
||||||
|
* deps: qs@6.5.0
|
||||||
|
* deps: raw-body@2.3.1
|
||||||
|
- Use `http-errors` for standard emitted errors
|
||||||
|
- deps: bytes@3.0.0
|
||||||
|
- deps: iconv-lite@0.4.18
|
||||||
|
- perf: skip buffer decoding on overage chunk
|
||||||
|
* perf: prevent internal `throw` when missing charset
|
||||||
|
|
||||||
|
1.17.2 / 2017-05-17
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: debug@2.6.7
|
||||||
|
- Fix `DEBUG_MAX_ARRAY_LENGTH`
|
||||||
|
- deps: ms@2.0.0
|
||||||
|
* deps: type-is@~1.6.15
|
||||||
|
- deps: mime-types@~2.1.15
|
||||||
|
|
||||||
|
1.17.1 / 2017-03-06
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: qs@6.4.0
|
||||||
|
- Fix regression parsing keys starting with `[`
|
||||||
|
|
||||||
|
1.17.0 / 2017-03-01
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: http-errors@~1.6.1
|
||||||
|
- Make `message` property enumerable for `HttpError`s
|
||||||
|
- deps: setprototypeof@1.0.3
|
||||||
|
* deps: qs@6.3.1
|
||||||
|
- Fix compacting nested arrays
|
||||||
|
|
||||||
|
1.16.1 / 2017-02-10
|
||||||
|
===================
|
||||||
|
|
||||||
|
* deps: debug@2.6.1
|
||||||
|
- Fix deprecation messages in WebStorm and other editors
|
||||||
|
- Undeprecate `DEBUG_FD` set to `1` or `2`
|
||||||
|
|
||||||
|
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.2.1
|
||||||
|
- Fix array parsing from skipping empty values
|
||||||
|
* 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
|
@ -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.
|
@ -0,0 +1,464 @@
|
|||||||
|
# body-parser
|
||||||
|
|
||||||
|
[![NPM Version][npm-image]][npm-url]
|
||||||
|
[![NPM Downloads][downloads-image]][downloads-url]
|
||||||
|
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||||
|
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||||
|
|
||||||
|
Node.js body parsing middleware.
|
||||||
|
|
||||||
|
Parse incoming request bodies in a middleware before your handlers, available
|
||||||
|
under the `req.body` property.
|
||||||
|
|
||||||
|
**Note** As `req.body`'s shape is based on user-controlled input, all
|
||||||
|
properties and values in this object are untrusted and should be validated
|
||||||
|
before trusting. For example, `req.body.foo.toString()` may fail in multiple
|
||||||
|
ways, for example the `foo` property may not be there or may not be a string,
|
||||||
|
and `toString` may not be a function and instead a string or other user input.
|
||||||
|
|
||||||
|
[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
|
||||||
|
|
||||||
|
```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 when
|
||||||
|
the `Content-Type` request header matches the `type` option, or an empty
|
||||||
|
object (`{}`) if there was no body to parse, the `Content-Type` was not matched,
|
||||||
|
or an error occurred.
|
||||||
|
|
||||||
|
The various errors returned by this module are described in the
|
||||||
|
[errors section](#errors).
|
||||||
|
|
||||||
|
### bodyParser.json([options])
|
||||||
|
|
||||||
|
Returns middleware that only parses `json` and only looks at requests where
|
||||||
|
the `Content-Type` header matches the `type` option. 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 optional `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 string, array of strings, or a function. If not a
|
||||||
|
function, `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` and only looks at
|
||||||
|
requests where the `Content-Type` header matches the `type` option. 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 optional `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 string, array of strings, or a function.
|
||||||
|
If not a function, `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 and only looks at
|
||||||
|
requests where the `Content-Type` header matches the `type` option. 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 optional `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 string, array of strings, or a function. If not
|
||||||
|
a function, `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 and only looks at
|
||||||
|
requests where the `Content-Type` header matches the `type` option. 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 optional `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 string, array of strings, or a function. If not
|
||||||
|
a function, `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 using the
|
||||||
|
[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
|
||||||
|
will typically have a `status`/`statusCode` property that contains the suggested
|
||||||
|
HTTP response code, an `expose` property to determine if the `message` property
|
||||||
|
should be displayed to the client, a `type` property to determine the type of
|
||||||
|
error without matching against the `message`, and a `body` property containing
|
||||||
|
the read body, if available.
|
||||||
|
|
||||||
|
The following are the common errors created, 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`, the `type` property is set to
|
||||||
|
`'encoding.unsupported'`, and the `charset` property will be set to the
|
||||||
|
encoding that is unsupported.
|
||||||
|
|
||||||
|
### entity parse failed
|
||||||
|
|
||||||
|
This error will occur when the request contained an entity that could not be
|
||||||
|
parsed by the middleware. The `status` property is set to `400`, the `type`
|
||||||
|
property is set to `'entity.parse.failed'`, and the `body` property is set to
|
||||||
|
the entity value that failed parsing.
|
||||||
|
|
||||||
|
### entity verify failed
|
||||||
|
|
||||||
|
This error will occur when the request contained an entity that could not be
|
||||||
|
failed verification by the defined `verify` option. The `status` property is
|
||||||
|
set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
|
||||||
|
`body` property is set to the entity value that failed verification.
|
||||||
|
|
||||||
|
### 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`
|
||||||
|
and `type` property is set to `'request.aborted'`.
|
||||||
|
|
||||||
|
### 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` and the `type` property is set to `'entity.too.large'`.
|
||||||
|
|
||||||
|
### 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` and the `type` property
|
||||||
|
is set to `'request.size.invalid'`.
|
||||||
|
|
||||||
|
### 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` and the `type` property is set to `'stream.encoding.set'`.
|
||||||
|
|
||||||
|
### stream is not readable
|
||||||
|
|
||||||
|
This error will occur when the request is no longer readable when this middleware
|
||||||
|
attempts to read it. This typically means something other than a middleware from
|
||||||
|
this module read the reqest body already and the middleware was also configured to
|
||||||
|
read the same request. The `status` property is set to `500` and the `type`
|
||||||
|
property is set to `'stream.not.readable'`.
|
||||||
|
|
||||||
|
### too many parameters
|
||||||
|
|
||||||
|
This error will occur when the content of the request exceeds the configured
|
||||||
|
`parameterLimit` for the `urlencoded` parser. The `status` property is set to
|
||||||
|
`413` and the `type` property is set to `'parameters.too.many'`.
|
||||||
|
|
||||||
|
### 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`, the
|
||||||
|
`type` property is set to `'charset.unsupported'`, and the `charset` property
|
||||||
|
is set to the charset that is unsupported.
|
||||||
|
|
||||||
|
### 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`,
|
||||||
|
the `type` property is set to `'encoding.unsupported'`, and the `encoding`
|
||||||
|
property is set to the encoding that is unsupported.
|
||||||
|
|
||||||
|
## 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) {
|
||||||
|
res.send('welcome, ' + req.body.username)
|
||||||
|
})
|
||||||
|
|
||||||
|
// POST /api/users gets JSON bodies
|
||||||
|
app.post('/api/users', jsonParser, function (req, res) {
|
||||||
|
// 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
|
||||||
|
[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
|
||||||
|
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/expressjs/body-parser/ci/master?label=ci
|
||||||
|
[github-actions-ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
|
@ -0,0 +1,25 @@
|
|||||||
|
# Security Policies and Procedures
|
||||||
|
|
||||||
|
## Reporting a Bug
|
||||||
|
|
||||||
|
The Express team and community take all security bugs seriously. Thank you
|
||||||
|
for improving the security of Express. We appreciate your efforts and
|
||||||
|
responsible disclosure and will make every effort to acknowledge your
|
||||||
|
contributions.
|
||||||
|
|
||||||
|
Report security bugs by emailing the current owner(s) of `body-parser`. This
|
||||||
|
information can be found in the npm registry using the command
|
||||||
|
`npm owner ls body-parser`.
|
||||||
|
If unsure or unable to get the information from the above, open an issue
|
||||||
|
in the [project issue tracker](https://github.com/expressjs/body-parser/issues)
|
||||||
|
asking for the current contact information.
|
||||||
|
|
||||||
|
To ensure the timely response to your report, please ensure that the entirety
|
||||||
|
of the report is contained within the email body and not solely behind a web
|
||||||
|
link or an attachment.
|
||||||
|
|
||||||
|
At least one owner will acknowledge your email within 48 hours, and will send a
|
||||||
|
more detailed response within 48 hours indicating the next steps in handling
|
||||||
|
your report. After the initial reply to your report, the owners will
|
||||||
|
endeavor to keep you informed of the progress towards a fix and full
|
||||||
|
announcement, and may ask for additional information or guidance.
|
@ -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)
|
||||||
|
}
|
@ -0,0 +1,205 @@
|
|||||||
|
/*!
|
||||||
|
* body-parser
|
||||||
|
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var createError = require('http-errors')
|
||||||
|
var destroy = require('destroy')
|
||||||
|
var getBody = require('raw-body')
|
||||||
|
var iconv = require('iconv-lite')
|
||||||
|
var onFinished = require('on-finished')
|
||||||
|
var unpipe = require('unpipe')
|
||||||
|
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
|
||||||
|
* @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
|
||||||
|
: 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(),
|
||||||
|
type: 'charset.unsupported'
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// read body
|
||||||
|
debug('read body')
|
||||||
|
getBody(stream, opts, function (error, body) {
|
||||||
|
if (error) {
|
||||||
|
var _error
|
||||||
|
|
||||||
|
if (error.type === 'encoding.unsupported') {
|
||||||
|
// echo back charset
|
||||||
|
_error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
|
||||||
|
charset: encoding.toLowerCase(),
|
||||||
|
type: 'charset.unsupported'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// set status code on error
|
||||||
|
_error = createError(400, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpipe from stream and destroy
|
||||||
|
if (stream !== req) {
|
||||||
|
unpipe(req)
|
||||||
|
destroy(stream, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// read off entire request
|
||||||
|
dump(req, function onfinished () {
|
||||||
|
next(createError(400, _error))
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify
|
||||||
|
if (verify) {
|
||||||
|
try {
|
||||||
|
debug('verify body')
|
||||||
|
verify(req, res, body, encoding)
|
||||||
|
} catch (err) {
|
||||||
|
next(createError(403, err, {
|
||||||
|
body: body,
|
||||||
|
type: err.type || 'entity.verify.failed'
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse
|
||||||
|
var str = body
|
||||||
|
try {
|
||||||
|
debug('parse body')
|
||||||
|
str = typeof body !== 'string' && encoding !== null
|
||||||
|
? iconv.decode(body, encoding)
|
||||||
|
: body
|
||||||
|
req.body = parse(str)
|
||||||
|
} catch (err) {
|
||||||
|
next(createError(400, err, {
|
||||||
|
body: str,
|
||||||
|
type: err.type || 'entity.parse.failed'
|
||||||
|
}))
|
||||||
|
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', {
|
||||||
|
encoding: encoding,
|
||||||
|
type: '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,
|
||||||
|
type: 'encoding.unsupported'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump the contents of a request.
|
||||||
|
*
|
||||||
|
* @param {object} req
|
||||||
|
* @param {function} callback
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function dump (req, callback) {
|
||||||
|
if (onFinished.isFinished(req)) {
|
||||||
|
callback(null)
|
||||||
|
} else {
|
||||||
|
onFinished(req, callback)
|
||||||
|
req.resume()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,236 @@
|
|||||||
|
/*!
|
||||||
|
* 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]*([^\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 createStrictSyntaxError(body, first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
debug('parse json')
|
||||||
|
return JSON.parse(body, reviver)
|
||||||
|
} catch (e) {
|
||||||
|
throw normalizeJsonSyntaxError(e, {
|
||||||
|
message: e.message,
|
||||||
|
stack: e.stack
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.slice(0, 4) !== 'utf-') {
|
||||||
|
debug('invalid charset')
|
||||||
|
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
|
||||||
|
charset: charset,
|
||||||
|
type: 'charset.unsupported'
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// read
|
||||||
|
read(req, res, next, parse, debug, {
|
||||||
|
encoding: charset,
|
||||||
|
inflate: inflate,
|
||||||
|
limit: limit,
|
||||||
|
verify: verify
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create strict violation syntax error matching native error.
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @param {string} char
|
||||||
|
* @return {Error}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createStrictSyntaxError (str, char) {
|
||||||
|
var index = str.indexOf(char)
|
||||||
|
var partial = index !== -1
|
||||||
|
? str.substring(0, index) + '#'
|
||||||
|
: ''
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation')
|
||||||
|
} catch (e) {
|
||||||
|
return normalizeJsonSyntaxError(e, {
|
||||||
|
message: e.message.replace('#', char),
|
||||||
|
stack: e.stack
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the first non-whitespace character in a string.
|
||||||
|
*
|
||||||
|
* @param {string} str
|
||||||
|
* @return {function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function firstchar (str) {
|
||||||
|
var match = FIRST_CHAR_REGEXP.exec(str)
|
||||||
|
|
||||||
|
return match
|
||||||
|
? match[1]
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a SyntaxError for JSON.parse.
|
||||||
|
*
|
||||||
|
* @param {SyntaxError} error
|
||||||
|
* @param {object} obj
|
||||||
|
* @return {SyntaxError}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function normalizeJsonSyntaxError (error, obj) {
|
||||||
|
var keys = Object.getOwnPropertyNames(error)
|
||||||
|
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
var key = keys[i]
|
||||||
|
if (key !== 'stack' && key !== 'message') {
|
||||||
|
delete error[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace stack before message for Node.js 0.10 and below
|
||||||
|
error.stack = obj.stack.replace(error.message, obj.message)
|
||||||
|
error.message = obj.message
|
||||||
|
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the simple type checker.
|
||||||
|
*
|
||||||
|
* @param {string} type
|
||||||
|
* @return {function}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function typeChecker (type) {
|
||||||
|
return function checkType (req) {
|
||||||
|
return Boolean(typeis(req, type))
|
||||||
|
}
|
||||||
|
}
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,284 @@
|
|||||||
|
/*!
|
||||||
|
* 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,
|
||||||
|
type: 'charset.unsupported'
|
||||||
|
}))
|
||||||
|
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', {
|
||||||
|
type: 'parameters.too.many'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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', {
|
||||||
|
type: 'parameters.too.many'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
2.0.0 / 2018-10-26
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Drop support for Node.js 0.6
|
||||||
|
* Replace internal `eval` usage with `Function` constructor
|
||||||
|
* Use instance methods on `process` to check for listeners
|
||||||
|
|
||||||
|
1.1.2 / 2018-01-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* perf: remove argument reassignment
|
||||||
|
* Support Node.js 0.6 to 9.x
|
||||||
|
|
||||||
|
1.1.1 / 2017-07-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Remove unnecessary `Buffer` loading
|
||||||
|
* Support Node.js 0.6 to 8.x
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,22 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2018 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.
|
@ -0,0 +1,280 @@
|
|||||||
|
# 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]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
<!-- eslint-disable no-unused-vars -->
|
||||||
|
|
||||||
|
```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)
|
||||||
|
|
||||||
|
[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/nodejs-depd/master?label=windows
|
||||||
|
[appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
|
||||||
|
[coveralls-image]: https://badgen.net/coveralls/c/github/dougwilson/nodejs-depd/master
|
||||||
|
[coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
|
||||||
|
[node-image]: https://badgen.net/npm/node/depd
|
||||||
|
[node-url]: https://nodejs.org/en/download/
|
||||||
|
[npm-downloads-image]: https://badgen.net/npm/dm/depd
|
||||||
|
[npm-url]: https://npmjs.org/package/depd
|
||||||
|
[npm-version-image]: https://badgen.net/npm/v/depd
|
||||||
|
[travis-image]: https://badgen.net/travis/dougwilson/nodejs-depd/master?label=linux
|
||||||
|
[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
|
@ -0,0 +1,538 @@
|
|||||||
|
/*!
|
||||||
|
* depd
|
||||||
|
* Copyright(c) 2014-2018 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 vals = str.split(/[ ,]+/)
|
||||||
|
var ns = String(namespace).toLowerCase()
|
||||||
|
|
||||||
|
for (var i = 0; i < vals.length; i++) {
|
||||||
|
var val = vals[i]
|
||||||
|
|
||||||
|
// namespace contained
|
||||||
|
if (val && (val === '*' || val.toLowerCase() === ns)) {
|
||||||
|
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 ' + stack[i].toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 event emitter has listeners of a given type.
|
||||||
|
*
|
||||||
|
* The way to do this check is done three different ways in Node.js >= 0.8
|
||||||
|
* so this consolidates them into a minimal set using instance methods.
|
||||||
|
*
|
||||||
|
* @param {EventEmitter} emitter
|
||||||
|
* @param {string} type
|
||||||
|
* @returns {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function eehaslisteners (emitter, type) {
|
||||||
|
var count = typeof emitter.listenerCount !== 'function'
|
||||||
|
? emitter.listeners(type).length
|
||||||
|
: emitter.listenerCount(type)
|
||||||
|
|
||||||
|
return count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if namespace is ignored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isignored (namespace) {
|
||||||
|
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) {
|
||||||
|
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 = eehaslisteners(process, 'deprecation')
|
||||||
|
|
||||||
|
// abort early if no destination
|
||||||
|
if (!haslisteners && this._ignored) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var caller
|
||||||
|
var callFile
|
||||||
|
var callSite
|
||||||
|
var depSite
|
||||||
|
var i = 0
|
||||||
|
var seen = false
|
||||||
|
var stack = getStack()
|
||||||
|
var file = this._file
|
||||||
|
|
||||||
|
if (site) {
|
||||||
|
// provided site
|
||||||
|
depSite = site
|
||||||
|
callSite = callSiteLocation(stack[1])
|
||||||
|
callSite.name = depSite.name
|
||||||
|
file = callSite[0]
|
||||||
|
} else {
|
||||||
|
// get call site
|
||||||
|
i = 2
|
||||||
|
depSite = callSiteLocation(stack[i])
|
||||||
|
callSite = depSite
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
? depSite.join(':') + '__' + caller.join(':')
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (key !== undefined && key in this._warned) {
|
||||||
|
// already warned
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._warned[key] = true
|
||||||
|
|
||||||
|
// generate automatic message from call site
|
||||||
|
var msg = message
|
||||||
|
if (!msg) {
|
||||||
|
msg = callSite === depSite || !callSite.name
|
||||||
|
? defaultMessage(depSite)
|
||||||
|
: defaultMessage(callSite)
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit deprecation if listeners exist
|
||||||
|
if (haslisteners) {
|
||||||
|
var err = DeprecationError(this._namespace, msg, stack.slice(i))
|
||||||
|
process.emit('deprecation', err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// format and write message
|
||||||
|
var format = process.stderr.isTTY
|
||||||
|
? formatColor
|
||||||
|
: formatPlain
|
||||||
|
var output = format.call(this, msg, caller, stack.slice(i))
|
||||||
|
process.stderr.write(output + '\n', 'utf8')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ' + stack[i].toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ' + stack[i].toString() + '\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 stack = getStack()
|
||||||
|
var site = callSiteLocation(stack[1])
|
||||||
|
|
||||||
|
site.name = fn.name
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-new-func
|
||||||
|
var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
|
||||||
|
'"use strict"\n' +
|
||||||
|
'return function (' + args + ') {' +
|
||||||
|
'log.call(deprecate, message, site)\n' +
|
||||||
|
'return fn.apply(this, arguments)\n' +
|
||||||
|
'}')(fn, log, this, message, site)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*!
|
||||||
|
* 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')
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"name": "depd",
|
||||||
|
"description": "Deprecate all the things",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"deprecate",
|
||||||
|
"deprecated"
|
||||||
|
],
|
||||||
|
"repository": "dougwilson/nodejs-depd",
|
||||||
|
"browser": "lib/browser/index.js",
|
||||||
|
"devDependencies": {
|
||||||
|
"benchmark": "2.1.4",
|
||||||
|
"beautify-benchmark": "0.2.4",
|
||||||
|
"eslint": "5.7.0",
|
||||||
|
"eslint-config-standard": "12.0.0",
|
||||||
|
"eslint-plugin-import": "2.14.0",
|
||||||
|
"eslint-plugin-markdown": "1.0.0-beta.7",
|
||||||
|
"eslint-plugin-node": "7.0.1",
|
||||||
|
"eslint-plugin-promise": "4.0.1",
|
||||||
|
"eslint-plugin-standard": "4.0.0",
|
||||||
|
"istanbul": "0.4.5",
|
||||||
|
"mocha": "5.2.0",
|
||||||
|
"safe-buffer": "5.1.2",
|
||||||
|
"uid-safe": "2.1.5"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"lib/",
|
||||||
|
"History.md",
|
||||||
|
"LICENSE",
|
||||||
|
"index.js",
|
||||||
|
"Readme.md"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"bench": "node benchmark/index.js",
|
||||||
|
"lint": "eslint --plugin markdown --ext js,md .",
|
||||||
|
"test": "mocha --reporter spec --bail test/",
|
||||||
|
"test-ci": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter spec test/ && istanbul report lcovonly text-summary",
|
||||||
|
"test-cov": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter dot test/ && istanbul report lcov text-summary"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,180 @@
|
|||||||
|
2.0.0 / 2021-12-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Drop support for Node.js 0.6
|
||||||
|
* Remove `I'mateapot` export; use `ImATeapot` instead
|
||||||
|
* Remove support for status being non-first argument
|
||||||
|
* Rename `UnorderedCollection` constructor to `TooEarly`
|
||||||
|
* deps: depd@2.0.0
|
||||||
|
- Replace internal `eval` usage with `Function` constructor
|
||||||
|
- Use instance methods on `process` to check for listeners
|
||||||
|
* deps: statuses@2.0.1
|
||||||
|
- Fix messaging casing of `418 I'm a Teapot`
|
||||||
|
- Remove code 306
|
||||||
|
- Rename `425 Unordered Collection` to standard `425 Too Early`
|
||||||
|
|
||||||
|
2021-11-14 / 1.8.1
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: toidentifier@1.0.1
|
||||||
|
|
||||||
|
2020-06-29 / 1.8.0
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Add `isHttpError` export to determine if value is an HTTP error
|
||||||
|
* deps: setprototypeof@1.2.0
|
||||||
|
|
||||||
|
2019-06-24 / 1.7.3
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: inherits@2.0.4
|
||||||
|
|
||||||
|
2019-02-18 / 1.7.2
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: setprototypeof@1.1.1
|
||||||
|
|
||||||
|
2018-09-08 / 1.7.1
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix error creating objects in some environments
|
||||||
|
|
||||||
|
2018-07-30 / 1.7.0
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Set constructor name when possible
|
||||||
|
* Use `toidentifier` module to make class names
|
||||||
|
* deps: statuses@'>= 1.5.0 < 2'
|
||||||
|
|
||||||
|
2018-03-29 / 1.6.3
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: depd@~1.1.2
|
||||||
|
- perf: remove argument reassignment
|
||||||
|
* deps: setprototypeof@1.1.0
|
||||||
|
* deps: statuses@'>= 1.4.0 < 2'
|
||||||
|
|
||||||
|
2017-08-04 / 1.6.2
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: depd@1.1.1
|
||||||
|
- Remove unnecessary `Buffer` loading
|
||||||
|
|
||||||
|
2017-02-20 / 1.6.1
|
||||||
|
==================
|
||||||
|
|
||||||
|
* deps: setprototypeof@1.0.3
|
||||||
|
- Fix shim for old browsers
|
||||||
|
|
||||||
|
2017-02-14 / 1.6.0
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Accept custom 4xx and 5xx status codes in factory
|
||||||
|
* Add deprecation message to `"I'mateapot"` export
|
||||||
|
* Deprecate passing status code as anything except first argument in factory
|
||||||
|
* Deprecate using non-error status codes
|
||||||
|
* Make `message` property enumerable for `HttpError`s
|
||||||
|
|
||||||
|
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
|
@ -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.
|
@ -0,0 +1,169 @@
|
|||||||
|
# http-errors
|
||||||
|
|
||||||
|
[![NPM Version][npm-version-image]][npm-url]
|
||||||
|
[![NPM Downloads][npm-downloads-image]][node-url]
|
||||||
|
[![Node.js Version][node-image]][node-url]
|
||||||
|
[![Build Status][ci-image]][ci-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):
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ 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.
|
||||||
|
|
||||||
|
### 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` - the traditional error message, which should be kept short and all
|
||||||
|
single line
|
||||||
|
- `status` - the status code of the error, mirroring `statusCode` for general
|
||||||
|
compatibility
|
||||||
|
- `statusCode` - the status code of the error, defaulting to `500`
|
||||||
|
|
||||||
|
### createError([status], [message], [properties])
|
||||||
|
|
||||||
|
Create a new error object with the given message `msg`.
|
||||||
|
The error object inherits from `createError.HttpError`.
|
||||||
|
|
||||||
|
```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
|
||||||
|
|
||||||
|
### createError([status], [error], [properties])
|
||||||
|
|
||||||
|
Extend the given `error` object with `createError.HttpError`
|
||||||
|
properties. This will not alter the inheritance of the given
|
||||||
|
`error` object, and the modified `error` object is the
|
||||||
|
return value.
|
||||||
|
|
||||||
|
<!-- eslint-disable no-redeclare -->
|
||||||
|
|
||||||
|
```js
|
||||||
|
fs.readFile('foo.txt', function (err, buf) {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
var httpError = createError(404, err, { expose: false })
|
||||||
|
} else {
|
||||||
|
var httpError = createError(500, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
- `status` - the status code as a number
|
||||||
|
- `error` - the error object to extend
|
||||||
|
- `properties` - custom properties to attach to the object
|
||||||
|
|
||||||
|
### createError.isHttpError(val)
|
||||||
|
|
||||||
|
Determine if the provided `val` is an `HttpError`. This will return `true`
|
||||||
|
if the error inherits from the `HttpError` constructor of this module or
|
||||||
|
matches the "duck type" for an error this module creates. All outputs from
|
||||||
|
the `createError` factory will return `true` for this function, including
|
||||||
|
if an non-`HttpError` was passed into the factory.
|
||||||
|
|
||||||
|
### new createError\[code || name\](\[msg]\))
|
||||||
|
|
||||||
|
Create a new error object with the given message `msg`.
|
||||||
|
The error object inherits from `createError.HttpError`.
|
||||||
|
|
||||||
|
```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 |TooEarly |
|
||||||
|
|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)
|
||||||
|
|
||||||
|
[ci-image]: https://badgen.net/github/checks/jshttp/http-errors/master?label=ci
|
||||||
|
[ci-url]: https://github.com/jshttp/http-errors/actions?query=workflow%3Aci
|
||||||
|
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/http-errors/master
|
||||||
|
[coveralls-url]: https://coveralls.io/r/jshttp/http-errors?branch=master
|
||||||
|
[node-image]: https://badgen.net/npm/node/http-errors
|
||||||
|
[node-url]: https://nodejs.org/en/download
|
||||||
|
[npm-downloads-image]: https://badgen.net/npm/dm/http-errors
|
||||||
|
[npm-url]: https://npmjs.org/package/http-errors
|
||||||
|
[npm-version-image]: https://badgen.net/npm/v/http-errors
|
||||||
|
[travis-image]: https://badgen.net/travis/jshttp/http-errors/master
|
||||||
|
[travis-url]: https://travis-ci.org/jshttp/http-errors
|
@ -0,0 +1,289 @@
|
|||||||
|
/*!
|
||||||
|
* http-errors
|
||||||
|
* Copyright(c) 2014 Jonathan Ong
|
||||||
|
* Copyright(c) 2016 Douglas Christopher Wilson
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var deprecate = require('depd')('http-errors')
|
||||||
|
var setPrototypeOf = require('setprototypeof')
|
||||||
|
var statuses = require('statuses')
|
||||||
|
var inherits = require('inherits')
|
||||||
|
var toIdentifier = require('toidentifier')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module exports.
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = createError
|
||||||
|
module.exports.HttpError = createHttpErrorConstructor()
|
||||||
|
module.exports.isHttpError = createIsHttpErrorFunction(module.exports.HttpError)
|
||||||
|
|
||||||
|
// Populate exports for all constructors
|
||||||
|
populateConstructorExports(module.exports, statuses.codes, module.exports.HttpError)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the code class of a status code.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function codeClass (status) {
|
||||||
|
return Number(String(status).charAt(0) + '00')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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]
|
||||||
|
var type = typeof arg
|
||||||
|
if (type === 'object' && arg instanceof Error) {
|
||||||
|
err = arg
|
||||||
|
status = err.status || err.statusCode || status
|
||||||
|
} else if (type === 'number' && i === 0) {
|
||||||
|
status = arg
|
||||||
|
} else if (type === 'string') {
|
||||||
|
msg = arg
|
||||||
|
} else if (type === 'object') {
|
||||||
|
props = arg
|
||||||
|
} else {
|
||||||
|
throw new TypeError('argument #' + (i + 1) + ' unsupported type ' + type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof status === 'number' && (status < 400 || status >= 600)) {
|
||||||
|
deprecate('non-error status code; use only 4xx or 5xx status codes')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof status !== 'number' ||
|
||||||
|
(!statuses.message[status] && (status < 400 || status >= 600))) {
|
||||||
|
status = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
var HttpError = createError[status] || createError[codeClass(status)]
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
// create error
|
||||||
|
err = HttpError
|
||||||
|
? new HttpError(msg)
|
||||||
|
: new Error(msg || statuses.message[status])
|
||||||
|
Error.captureStackTrace(err, createError)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HttpError || !(err instanceof HttpError) || err.status !== status) {
|
||||||
|
// 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 = toClassName(name)
|
||||||
|
|
||||||
|
function ClientError (message) {
|
||||||
|
// create the error object
|
||||||
|
var msg = message != null ? message : statuses.message[code]
|
||||||
|
var err = new Error(msg)
|
||||||
|
|
||||||
|
// capture a stack trace to the construction point
|
||||||
|
Error.captureStackTrace(err, ClientError)
|
||||||
|
|
||||||
|
// adjust the [[Prototype]]
|
||||||
|
setPrototypeOf(err, ClientError.prototype)
|
||||||
|
|
||||||
|
// redefine the error message
|
||||||
|
Object.defineProperty(err, 'message', {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
value: msg,
|
||||||
|
writable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// redefine the error name
|
||||||
|
Object.defineProperty(err, 'name', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: true,
|
||||||
|
value: className,
|
||||||
|
writable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
inherits(ClientError, HttpError)
|
||||||
|
nameFunc(ClientError, className)
|
||||||
|
|
||||||
|
ClientError.prototype.status = code
|
||||||
|
ClientError.prototype.statusCode = code
|
||||||
|
ClientError.prototype.expose = true
|
||||||
|
|
||||||
|
return ClientError
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create function to test is a value is a HttpError.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createIsHttpErrorFunction (HttpError) {
|
||||||
|
return function isHttpError (val) {
|
||||||
|
if (!val || typeof val !== 'object') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val instanceof HttpError) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return val instanceof Error &&
|
||||||
|
typeof val.expose === 'boolean' &&
|
||||||
|
typeof val.statusCode === 'number' && val.status === val.statusCode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a constructor for a server error.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createServerErrorConstructor (HttpError, name, code) {
|
||||||
|
var className = toClassName(name)
|
||||||
|
|
||||||
|
function ServerError (message) {
|
||||||
|
// create the error object
|
||||||
|
var msg = message != null ? message : statuses.message[code]
|
||||||
|
var err = new Error(msg)
|
||||||
|
|
||||||
|
// capture a stack trace to the construction point
|
||||||
|
Error.captureStackTrace(err, ServerError)
|
||||||
|
|
||||||
|
// adjust the [[Prototype]]
|
||||||
|
setPrototypeOf(err, ServerError.prototype)
|
||||||
|
|
||||||
|
// redefine the error message
|
||||||
|
Object.defineProperty(err, 'message', {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
value: msg,
|
||||||
|
writable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// redefine the error name
|
||||||
|
Object.defineProperty(err, 'name', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: true,
|
||||||
|
value: className,
|
||||||
|
writable: true
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
inherits(ServerError, HttpError)
|
||||||
|
nameFunc(ServerError, className)
|
||||||
|
|
||||||
|
ServerError.prototype.status = code
|
||||||
|
ServerError.prototype.statusCode = code
|
||||||
|
ServerError.prototype.expose = false
|
||||||
|
|
||||||
|
return ServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of a function, if possible.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function nameFunc (func, name) {
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(func, 'name')
|
||||||
|
|
||||||
|
if (desc && desc.configurable) {
|
||||||
|
desc.value = name
|
||||||
|
Object.defineProperty(func, 'name', desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.message[code])
|
||||||
|
|
||||||
|
switch (codeClass(code)) {
|
||||||
|
case 400:
|
||||||
|
CodeError = createClientErrorConstructor(HttpError, name, code)
|
||||||
|
break
|
||||||
|
case 500:
|
||||||
|
CodeError = createServerErrorConstructor(HttpError, name, code)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CodeError) {
|
||||||
|
// export the constructor
|
||||||
|
exports[code] = CodeError
|
||||||
|
exports[name] = CodeError
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a class name from a name identifier.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function toClassName (name) {
|
||||||
|
return name.substr(-5) !== 'Error'
|
||||||
|
? name + 'Error'
|
||||||
|
: name
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"name": "http-errors",
|
||||||
|
"description": "Create HTTP error objects",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"author": "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)",
|
||||||
|
"contributors": [
|
||||||
|
"Alan Plum <me@pluma.io>",
|
||||||
|
"Douglas Christopher Wilson <doug@somethingdoug.com>"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "jshttp/http-errors",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "2.0.0",
|
||||||
|
"inherits": "2.0.4",
|
||||||
|
"setprototypeof": "1.2.0",
|
||||||
|
"statuses": "2.0.1",
|
||||||
|
"toidentifier": "1.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "7.32.0",
|
||||||
|
"eslint-config-standard": "14.1.1",
|
||||||
|
"eslint-plugin-import": "2.25.3",
|
||||||
|
"eslint-plugin-markdown": "2.2.1",
|
||||||
|
"eslint-plugin-node": "11.1.0",
|
||||||
|
"eslint-plugin-promise": "5.2.0",
|
||||||
|
"eslint-plugin-standard": "4.1.0",
|
||||||
|
"mocha": "9.1.3",
|
||||||
|
"nyc": "15.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint . && node ./scripts/lint-readme-list.js",
|
||||||
|
"test": "mocha --reporter spec --bail",
|
||||||
|
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||||
|
"test-cov": "nyc --reporter=html --reporter=text npm test",
|
||||||
|
"version": "node scripts/version-history.js && git add HISTORY.md"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"HISTORY.md",
|
||||||
|
"LICENSE",
|
||||||
|
"README.md"
|
||||||
|
]
|
||||||
|
}
|
@ -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.
|
||||||
|
|
@ -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
|
@ -0,0 +1,9 @@
|
|||||||
|
try {
|
||||||
|
var util = require('util');
|
||||||
|
/* istanbul ignore next */
|
||||||
|
if (typeof util.inherits !== 'function') throw '';
|
||||||
|
module.exports = util.inherits;
|
||||||
|
} catch (e) {
|
||||||
|
/* istanbul ignore next */
|
||||||
|
module.exports = require('./inherits_browser.js');
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
if (typeof Object.create === 'function') {
|
||||||
|
// implementation from standard node.js 'util' module
|
||||||
|
module.exports = function inherits(ctor, superCtor) {
|
||||||
|
if (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) {
|
||||||
|
if (superCtor) {
|
||||||
|
ctor.super_ = superCtor
|
||||||
|
var TempCtor = function () {}
|
||||||
|
TempCtor.prototype = superCtor.prototype
|
||||||
|
ctor.prototype = new TempCtor()
|
||||||
|
ctor.prototype.constructor = ctor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "inherits",
|
||||||
|
"description": "Browser-friendly inheritance fully compatible with standard node.js inherits()",
|
||||||
|
"version": "2.0.4",
|
||||||
|
"keywords": [
|
||||||
|
"inheritance",
|
||||||
|
"class",
|
||||||
|
"klass",
|
||||||
|
"oop",
|
||||||
|
"object-oriented",
|
||||||
|
"inherits",
|
||||||
|
"browser",
|
||||||
|
"browserify"
|
||||||
|
],
|
||||||
|
"main": "./inherits.js",
|
||||||
|
"browser": "./inherits_browser.js",
|
||||||
|
"repository": "git://github.com/isaacs/inherits",
|
||||||
|
"license": "ISC",
|
||||||
|
"scripts": {
|
||||||
|
"test": "tap"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"tap": "^14.2.4"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"inherits.js",
|
||||||
|
"inherits_browser.js"
|
||||||
|
]
|
||||||
|
}
|
@ -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.
|
@ -0,0 +1,31 @@
|
|||||||
|
# Polyfill for `Object.setPrototypeOf`
|
||||||
|
|
||||||
|
[![NPM Version](https://img.shields.io/npm/v/setprototypeof.svg)](https://npmjs.org/package/setprototypeof)
|
||||||
|
[![NPM Downloads](https://img.shields.io/npm/dm/setprototypeof.svg)](https://npmjs.org/package/setprototypeof)
|
||||||
|
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](https://github.com/standard/standard)
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
TypeScript is also supported:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import setPrototypeOf from 'setprototypeof'
|
||||||
|
```
|
@ -0,0 +1,2 @@
|
|||||||
|
declare function setPrototypeOf(o: any, proto: object | null): any;
|
||||||
|
export = setPrototypeOf;
|
@ -0,0 +1,17 @@
|
|||||||
|
'use strict'
|
||||||
|
/* eslint no-proto: 0 */
|
||||||
|
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) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
|
||||||
|
obj[prop] = proto[prop]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"name": "setprototypeof",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"description": "A small polyfill for Object.setprototypeof",
|
||||||
|
"main": "index.js",
|
||||||
|
"typings": "index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "standard && mocha",
|
||||||
|
"testallversions": "npm run node010 && npm run node4 && npm run node6 && npm run node9 && npm run node11",
|
||||||
|
"testversion": "docker run -it --rm -v $(PWD):/usr/src/app -w /usr/src/app node:${NODE_VER} npm install mocha@${MOCHA_VER:-latest} && npm t",
|
||||||
|
"node010": "NODE_VER=0.10 MOCHA_VER=3 npm run testversion",
|
||||||
|
"node4": "NODE_VER=4 npm run testversion",
|
||||||
|
"node6": "NODE_VER=6 npm run testversion",
|
||||||
|
"node9": "NODE_VER=9 npm run testversion",
|
||||||
|
"node11": "NODE_VER=11 npm run testversion",
|
||||||
|
"prepublishOnly": "npm t",
|
||||||
|
"postpublish": "git push origin && git push origin --tags"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/wesleytodd/setprototypeof.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"polyfill",
|
||||||
|
"object",
|
||||||
|
"setprototypeof"
|
||||||
|
],
|
||||||
|
"author": "Wes Todd",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/wesleytodd/setprototypeof/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/wesleytodd/setprototypeof",
|
||||||
|
"devDependencies": {
|
||||||
|
"mocha": "^6.1.4",
|
||||||
|
"standard": "^13.0.2"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
'use strict'
|
||||||
|
/* eslint-env mocha */
|
||||||
|
/* eslint no-proto: 0 */
|
||||||
|
var assert = require('assert')
|
||||||
|
var setPrototypeOf = require('..')
|
||||||
|
|
||||||
|
describe('setProtoOf(obj, proto)', function () {
|
||||||
|
it('should merge objects', function () {
|
||||||
|
var obj = { a: 1, b: 2 }
|
||||||
|
var proto = { b: 3, c: 4 }
|
||||||
|
var mergeObj = setPrototypeOf(obj, proto)
|
||||||
|
|
||||||
|
if (Object.getPrototypeOf) {
|
||||||
|
assert.strictEqual(Object.getPrototypeOf(obj), proto)
|
||||||
|
} else if ({ __proto__: [] } instanceof Array) {
|
||||||
|
assert.strictEqual(obj.__proto__, proto)
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(obj.a, 1)
|
||||||
|
assert.strictEqual(obj.b, 2)
|
||||||
|
assert.strictEqual(obj.c, 4)
|
||||||
|
}
|
||||||
|
assert.strictEqual(mergeObj, obj)
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,82 @@
|
|||||||
|
2.0.1 / 2021-01-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fix returning values from `Object.prototype`
|
||||||
|
|
||||||
|
2.0.0 / 2020-04-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Drop support for Node.js 0.6
|
||||||
|
* Fix messaging casing of `418 I'm a Teapot`
|
||||||
|
* Remove code 306
|
||||||
|
* Remove `status[code]` exports; use `status.message[code]`
|
||||||
|
* Remove `status[msg]` exports; use `status.code[msg]`
|
||||||
|
* Rename `425 Unordered Collection` to standard `425 Too Early`
|
||||||
|
* Rename `STATUS_CODES` export to `message`
|
||||||
|
* Return status message for `statuses(code)` when given code
|
||||||
|
|
||||||
|
1.5.0 / 2018-03-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Add `103 Early Hints`
|
||||||
|
|
||||||
|
1.4.0 / 2017-10-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Add `STATUS_CODES` export
|
||||||
|
|
||||||
|
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
|