Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b68595e92 | ||
|
|
7a8617b7a7 | ||
|
|
45f8f23fcc | ||
|
|
6040e37da2 | ||
|
|
b30b8ffc30 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1 @@
|
||||
# 忽略提交文件
|
||||
/unpackage
|
||||
node_modules/
|
||||
.vscode/
|
||||
.hbuilderx/
|
||||
/unpackage
|
||||
@@ -1,27 +1,16 @@
|
||||
{
|
||||
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version" : "0.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"app-plus" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"default" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"mp-weixin" : {
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
},
|
||||
{
|
||||
"playground" : "custom",
|
||||
"type" : "uni-app:app-android"
|
||||
},
|
||||
{
|
||||
"playground" : "standard",
|
||||
"type" : "uni-app:app-ios"
|
||||
}
|
||||
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version": "0.0",
|
||||
"configurations": [{
|
||||
"default" :
|
||||
{
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"mp-weixin" :
|
||||
{
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
91
App.vue
91
App.vue
@@ -1,94 +1,15 @@
|
||||
<template>
|
||||
</template>
|
||||
<script>
|
||||
import Api from '@/common/js/api.js'
|
||||
import useStorage from '@/utils/useStroage.js';
|
||||
export default {
|
||||
globalData: {
|
||||
systemInfo: null,
|
||||
tableCode: null,
|
||||
shopId: null,
|
||||
queueId: null,
|
||||
},
|
||||
onLaunch: function(options) {
|
||||
if ( options.query&&options.query.qrCode ) {
|
||||
if (this.getQueryString(options.query.qrCode, 'code')) {
|
||||
this.globalData.tableCode = this.getQueryString(options.query.qrCode, 'code')
|
||||
}
|
||||
if (this.getQueryString(options.query.qrCode, 'shopId')) {
|
||||
this.globalData.shopId = this.getQueryString(options.query.qrCode, 'shopId')
|
||||
}
|
||||
if (this.getQueryString(options.query.qrCode, 'queueId')) {
|
||||
this.globalData.queueId = this.getQueryString(options.query.qrCode, 'queueId')
|
||||
}
|
||||
}
|
||||
if ( uni.getStorageSync("NAME") && !uni.getStorageSync("NAME").data) {
|
||||
uni.cache.clear();
|
||||
}
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.cache.set('menuInfo', uni.getMenuButtonBoundingClientRect());
|
||||
// #endif
|
||||
uni.cache.set('NAME', '零点八零');
|
||||
if (!uni.cache.get('token')) {
|
||||
this.$store.dispatch("loginEvent")
|
||||
}
|
||||
|
||||
},
|
||||
onLoad() {
|
||||
onLaunch: function() {
|
||||
// console.log('App Launch');
|
||||
useStorage.set('menuInfo', uni.getMenuButtonBoundingClientRect());
|
||||
},
|
||||
onShow: function() {
|
||||
// 获取导航栏信息
|
||||
wx.getSystemInfo({
|
||||
success: res => {
|
||||
this.globalData.systemInfo = res;
|
||||
}
|
||||
})
|
||||
this.$store.dispatch("HeightActions"); //获取随时获取页面的高度
|
||||
// #ifdef MP-WEIXIN
|
||||
// 当向小程序后台请求完新版本信息,会进行回调。res: {hasUpdate: true, version: 1.0.0}
|
||||
const updateManager = uni.getUpdateManager();
|
||||
updateManager.onCheckForUpdate(function(res) {
|
||||
if (res.hasUpdate) { // 有更新
|
||||
uni.showLoading({
|
||||
title: '更新中...'
|
||||
}); // 开始下载前,显示Loading
|
||||
}
|
||||
});
|
||||
// 当新版本下载完成,会进行回调
|
||||
updateManager.onUpdateReady(function() {
|
||||
uni.hideLoading(); // 关闭 Loading
|
||||
uni.showModal({ // 弹确认框(强制更新)
|
||||
title: '更新提示',
|
||||
content: '更新完毕,是否重启?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
updateManager.applyUpdate(); // 强制小程序重启并使用新版本。
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
// 当新版本下载失败,会进行回调
|
||||
updateManager.onUpdateFailed(function() {
|
||||
uni.hideLoading(); // 关闭 Loading
|
||||
uni.showToast({
|
||||
title: '更新失败,稍后再试...',
|
||||
icon: "error"
|
||||
});
|
||||
});
|
||||
// #endif
|
||||
|
||||
// console.log('App Show');
|
||||
},
|
||||
onHide: function() {
|
||||
// console.log('App Hide');
|
||||
},
|
||||
methods: {
|
||||
getQueryString(url, name) { //解码
|
||||
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
|
||||
var r = url.substr(1).match(reg)
|
||||
if (r != null) {
|
||||
return r[2]
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -149,7 +70,7 @@
|
||||
}
|
||||
|
||||
page {
|
||||
background-color: #F6F6F6!important;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
text {
|
||||
|
||||
35
common/js/WXBizDataCrypt.js
Normal file
35
common/js/WXBizDataCrypt.js
Normal file
@@ -0,0 +1,35 @@
|
||||
var crypto = require('crypto')
|
||||
|
||||
function WXBizDataCrypt(appId, sessionKey) {
|
||||
this.appId = appId
|
||||
this.sessionKey = sessionKey
|
||||
}
|
||||
|
||||
WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
|
||||
// base64 decode
|
||||
var sessionKey = new Buffer(this.sessionKey, 'base64')
|
||||
encryptedData = new Buffer(encryptedData, 'base64')
|
||||
iv = new Buffer(iv, 'base64')
|
||||
|
||||
try {
|
||||
// 解密
|
||||
var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
|
||||
// 设置自动 padding 为 true,删除填充补位
|
||||
decipher.setAutoPadding(true)
|
||||
var decoded = decipher.update(encryptedData, 'binary', 'utf8')
|
||||
decoded += decipher.final('utf8')
|
||||
|
||||
decoded = JSON.parse(decoded)
|
||||
|
||||
} catch (err) {
|
||||
throw new Error('Illegal Buffer')
|
||||
}
|
||||
|
||||
if (decoded.watermark.appid !== this.appId) {
|
||||
throw new Error('Illegal Buffer')
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
|
||||
module.exports = WXBizDataCrypt
|
||||
391
common/js/api.js
391
common/js/api.js
@@ -1,397 +1,50 @@
|
||||
export default {
|
||||
userwxlogin(data) { //登录
|
||||
return uni.api.post("/login/auth/custom/login", data);
|
||||
return uni.api.post("/login/wx/custom/login", data);
|
||||
},
|
||||
loginwxuserInfo(data) { //获取用户详情
|
||||
return uni.api.get("/login/userInfo", data,false);
|
||||
productqueryProduct(data) { //获取商品信息
|
||||
return uni.api.post("/product/queryProduct", data);
|
||||
},
|
||||
userwxlogins(data) { // 获取手机号
|
||||
console.log(data)
|
||||
return uni.api.post("/login/getPhoneNumber", data);
|
||||
cartadd(data) { //添加到购物车
|
||||
return uni.api.post("/cart/add", data);
|
||||
},
|
||||
getShopExtend(data) { //获取图片 通过shopId和autokey
|
||||
return uni.api.post("/common/shopExtend", data,false);
|
||||
},
|
||||
// 获取弹窗广告列表
|
||||
getPopUpAd(data) {
|
||||
return uni.api.get("/tbShopAd/list", data,false);
|
||||
cartcartList(data) { //购物车
|
||||
return uni.api.get("/cart/cartList", data);
|
||||
},
|
||||
logincreateCardNo(data) { //获取会员码
|
||||
return uni.api.get("/login/createCardNo", data);
|
||||
},
|
||||
productqueryShop(data) { //通过桌码获取店铺信息
|
||||
return uni.api.get("/product/queryShop", data);
|
||||
cartupdateNumber(data) { //购物车更改数量
|
||||
return uni.api.get("/cart/updateNumber", data);
|
||||
},
|
||||
productChoseCount(data) { //就餐人数选择
|
||||
return uni.api.post("/product/choseCount", data,false);
|
||||
ordercreatOrder(data) { //下单
|
||||
return uni.api.post("/order/creatOrder", data);
|
||||
},
|
||||
productqueryProduct(data) { //获取商品信息
|
||||
return uni.api.post("/product/queryProduct", data, false);
|
||||
cartclear(data) { //清空购物车
|
||||
return uni.api.get("/cart/clear", data);
|
||||
},
|
||||
productquerySpec(data) { //获取已上架商品规格
|
||||
return uni.api.post("/product/querySpec", data, false);
|
||||
},
|
||||
cartAdd(data) { //添加到购物车
|
||||
return uni.api.post("/product/addCart", data);
|
||||
},
|
||||
cleanCart(data) { //清空购物车
|
||||
return uni.api.post("/product/cleanCart", data);
|
||||
},
|
||||
// 下单详情
|
||||
getproductorderConfirm(data) {
|
||||
return uni.api.get("/product/orderConfirm", data);
|
||||
},
|
||||
// 下单详情
|
||||
getproductorderConfirm(data) {
|
||||
return uni.api.get("/product/orderConfirm", data);
|
||||
},
|
||||
|
||||
choseEatModel(data) { //就餐模式选择
|
||||
return uni.api.post("/product/choseEatModel", data, false);
|
||||
},
|
||||
|
||||
// 支付
|
||||
payOrderPay(data) {
|
||||
return uni.api.post("/pay/groupOrderPay", data);
|
||||
},
|
||||
// 会员支付
|
||||
accountPay(data) {
|
||||
return uni.api.get("/pay/accountPay", data);
|
||||
},
|
||||
orderPay(data) { //订单支付
|
||||
payorderPay(data) { //订单支付
|
||||
return uni.api.post("/pay/orderPay", data);
|
||||
},
|
||||
cancelOrderPay(data) { //订单支付
|
||||
return uni.api.post("/notify/cancel", data);
|
||||
},
|
||||
|
||||
paymodfiyOrderInfo(data) { //查询订单支付状态
|
||||
return uni.api.post("/pay/modfiyOrderInfo", data);
|
||||
},
|
||||
paymemeberIn(data) { //充值
|
||||
return uni.api.post("/pay/memeberIn", data);
|
||||
},
|
||||
|
||||
|
||||
orderorderList(data) { //订单列表
|
||||
return uni.api.get("/order/orderList", data);
|
||||
},
|
||||
orderorderInfo(data) { //订单回显
|
||||
return uni.api.get("/order/orderInfo", data ,false);
|
||||
return uni.api.get("/order/orderInfo", data);
|
||||
},
|
||||
removeOrder(data) { //删除订单
|
||||
return uni.api.post("/order/rmOrder", data);
|
||||
loginwxuserInfo(data) { //微信用户详情
|
||||
return uni.api.get("/login/wx/userInfo", data);
|
||||
},
|
||||
creatOrder(data) { //创建订单
|
||||
return uni.api.post("/order/creatOrder", data);
|
||||
paymemeberIn(data) { //充值
|
||||
return uni.api.post("/pay/memeberIn", data);
|
||||
},
|
||||
useCoupon(data) { //订单选择优惠券
|
||||
return uni.api.post("/order/useCoupon", data);
|
||||
},
|
||||
|
||||
|
||||
// 团购订单列表
|
||||
groupOrderInfo(data) { //订单列表
|
||||
return uni.api.get("/groupOrderInfo/list", data);
|
||||
},
|
||||
|
||||
groupOrderInfoDetail(data) { //订单回显
|
||||
return uni.api.get("/groupOrderInfo/get", data);
|
||||
},
|
||||
// 下单
|
||||
creatGroupOrder(data) {
|
||||
return uni.api.post("/groupOrderInfo/creatGroupOrder", data);
|
||||
},
|
||||
|
||||
|
||||
|
||||
// 获取店铺会员信息
|
||||
shopUserInfo(data) {
|
||||
return uni.api.get("/user/shopUserInfo", data,false);
|
||||
},
|
||||
// 注册会员
|
||||
openMember(data) {
|
||||
return uni.api.post("/user/openMember", data);
|
||||
},
|
||||
// 会员填充手机号
|
||||
upVipPhont(data) {
|
||||
return uni.api.post("/user/upVipPhont", data);
|
||||
},
|
||||
|
||||
|
||||
// 优惠券数量
|
||||
userCoupon(data) {
|
||||
return uni.api.get("/user/userCoupon", data);
|
||||
},
|
||||
// 优惠加倍
|
||||
yhqDouble(data) { //查询订单支付状态
|
||||
return uni.api.post("/order/yhqDouble", data);
|
||||
},
|
||||
// 优惠卷详情
|
||||
getYhqDouble(data) { //通过选中的商品规格查询价格
|
||||
return uni.api.get("/order/getYhqDouble", data);
|
||||
paymodfiyOrderInfo(data) { //查询订单支付状态
|
||||
return uni.api.post("/pay/modfiyOrderInfo", data);
|
||||
},
|
||||
productqueryProductSku(data) { //通过选中的商品规格查询价格
|
||||
return uni.api.get("/product/queryProductSku", data, false);
|
||||
return uni.api.get("/product/queryProductSku", data);
|
||||
},
|
||||
logingetPhoneNumber(data) { //小程序获取手机号
|
||||
return uni.api.post("/login/getPhoneNumber", data);
|
||||
},
|
||||
cashierServiceloginregister(data) { //用户注册
|
||||
return uni.api.post("/cashierService/login/register", data);
|
||||
},
|
||||
cashierServiceloginregister(data) { //APP登录
|
||||
return uni.api.post("/login/app/login", data);
|
||||
},
|
||||
phoneValidateCode(data) { //验证码
|
||||
return uni.api.get("/phoneValidateCode", data);
|
||||
},
|
||||
homehomePageUp(data) { //首页上半部分
|
||||
return uni.api.post("/home/homePageUp", data);
|
||||
},
|
||||
home(data) { //首页上半部分
|
||||
return uni.api.post("/home", data, false);
|
||||
},
|
||||
locationdistrict(data) { //获取行政区域(区,街道)
|
||||
return uni.api.get("/location/district", data);
|
||||
},
|
||||
queryMemberAccount(data) { //获取余额明细
|
||||
return uni.api.get("/pay/queryMemberAccount", data);
|
||||
},
|
||||
queryMemberPointsLog(data) { //获取余额明细
|
||||
return uni.api.get("/api/points/member-points-log/page", data);
|
||||
},
|
||||
ordermineCoupons(data) { //我的优惠券
|
||||
return uni.api.get("/order/mineCoupons", data, false);
|
||||
},
|
||||
getUserConpons(data) { //我的优惠券
|
||||
return uni.api.post("/userConpons/find", data);
|
||||
},
|
||||
conponList(data) { //获取优惠券
|
||||
return uni.api.post("/coupon/find", data);
|
||||
},
|
||||
ordergetYhqPara(data) { //获取优惠券参数列表
|
||||
return uni.api.get("/order/getYhqPara", data);
|
||||
},
|
||||
orderfindCoupons(data) { //系统优惠券
|
||||
return uni.api.get("/order/findCoupons", data);
|
||||
},
|
||||
tbPlatformDict(data) { //获取菜单
|
||||
return uni.api.get("/tbPlatformDict", data);
|
||||
},
|
||||
distirictsubShopList(data) { //预约到店(店铺列表)
|
||||
return uni.api.get("/distirict/subShopList", data);
|
||||
},
|
||||
distiricttopCommon(data) { //获取top部分(店铺列表)
|
||||
return uni.api.get("/distirict/topCommon", data);
|
||||
},
|
||||
orderfindWiningUser(data) { //获取免单订单
|
||||
return uni.api.get("/order/findWiningUser", data);
|
||||
},
|
||||
// 获取自己的免单订单
|
||||
ordermineWinner(data) {
|
||||
return uni.api.get("/order/mineWinner", data);
|
||||
},
|
||||
indexlist(data) { //商品列表(今日上新/热榜/咖啡饮品)
|
||||
return uni.api.get("/distirict/productCate", data, false);
|
||||
},
|
||||
productproductInfo(data) { //商品详情
|
||||
return uni.api.get("/product/productInfo", data);
|
||||
},
|
||||
distirictcomShopList(data) { //通用门店列表
|
||||
return uni.api.get("/distirict/comShopList", data);
|
||||
},
|
||||
loginOut(data) { //退出登录
|
||||
return uni.api.post("/login/loginOut", data);
|
||||
},
|
||||
productqueryShopIdByTableCode(data) { //通过桌码获取shopId
|
||||
return uni.api.get("/product/queryShopIdByTableCode", data);
|
||||
},
|
||||
geocodelocation(data) { //根据经纬度获取信息
|
||||
return uni.api.get("/location/geocode", data, false);
|
||||
},
|
||||
// 修改头像和昵称
|
||||
upUserInfo(data) {
|
||||
return uni.api.post("/login/upUserInfo", data);
|
||||
},
|
||||
loginresetPwd(data) { // 重置资金密码
|
||||
return uni.api.post("/login/resetPwd", data);
|
||||
},
|
||||
paygetActive(data) { // 获取充值活动
|
||||
return uni.api.get("/pay/getActive", data);
|
||||
},
|
||||
paygetShopByMember(data) { // 获取会员店铺信息
|
||||
return uni.api.get("/pay/getShopByMember", data, false);
|
||||
},
|
||||
loginmpdifyPwd(data) { // 修改资金密码
|
||||
return uni.api.get("/login/mpdifyPwd", data);
|
||||
},
|
||||
cashierServicesong(data) { // 获取所有歌曲,支持搜索及分页
|
||||
return uni.api.get("/song", data, false);
|
||||
},
|
||||
cashierServicerecord(data) { // 点歌记录
|
||||
return uni.api.get("/song/record", data);
|
||||
},
|
||||
cashierServicesongpost(data) { // 点歌
|
||||
return uni.api.post("/song", data);
|
||||
},
|
||||
businessopenId(data) { // 获取openId
|
||||
return uni.api.get("/login/wx/business/openId", data);
|
||||
},
|
||||
songsinging(data) { // 获取正在演唱的歌曲
|
||||
return uni.api.get("/song/singing", data, false);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取排号信息
|
||||
* @param {Object} param
|
||||
*/
|
||||
getQueueUpList(param) {
|
||||
return uni.api.get("/callTable/queue", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取桌型列表
|
||||
* @param {Object} param
|
||||
*/
|
||||
getQueueUpTablList(param) {
|
||||
return uni.api.get("/callTable", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取排号状态
|
||||
* @param {Object} param
|
||||
*/
|
||||
getQueueUpState(param) {
|
||||
return uni.api.get("/callTable/state", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取订阅
|
||||
* @param {Object} data
|
||||
*/
|
||||
setSubMsg(data) {
|
||||
return uni.api.post("/callTable/subMsg", data,false);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取号
|
||||
* @param {Object} data
|
||||
*/
|
||||
getTakeNumber(data) {
|
||||
return uni.api.post("/callTable/takeNumber", data, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消排号
|
||||
* @param {Object} data
|
||||
*/
|
||||
cancelTakeNumber(data) {
|
||||
return uni.api.post("/callTable/cancel", data, false);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 积分-基本设置-获取店铺设置
|
||||
* @param {Object} param
|
||||
*/
|
||||
shopSettingInfo(shopId) {
|
||||
return uni.api.get(`/api/points/basic-setting/${shopId}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* 积分-兑换商品列表
|
||||
* @param {Object} param
|
||||
*/
|
||||
pointsGoodsList(param) {
|
||||
return uni.api.get("/api/points/goods-setting/page", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 积分-生成订单
|
||||
* @param {Object} data
|
||||
*/
|
||||
pointsCreateOrder(data) {
|
||||
return uni.api.post("/api/points/exchange-record/create", data);
|
||||
},
|
||||
/**
|
||||
* 积分-支付订单
|
||||
* @param {Object} data
|
||||
*/
|
||||
pointsPayOrder(data) {
|
||||
return uni.api.post("/api/points/exchange-record/pay", data);
|
||||
},
|
||||
/**
|
||||
* 积分-取消订单
|
||||
* @param {Object} data
|
||||
*/
|
||||
pointsCancelOrder(data) {
|
||||
return uni.api.post("/api/points/exchange-record/cancel", data);
|
||||
},
|
||||
/**
|
||||
* 积分-001-会员积分账户信息
|
||||
* @param {Object} param
|
||||
*/
|
||||
memberPointsInfo(memberId) {
|
||||
return uni.api.get(`/api/points/member-points/${memberId}`, );
|
||||
},
|
||||
|
||||
/**
|
||||
* 积分-明细列表
|
||||
* @param {Object} param
|
||||
*/
|
||||
memberPointsLogList(param) {
|
||||
return uni.api.get("/api/points/member-points-log/page", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 积分-兑换记录-列表
|
||||
* @param {Object} param
|
||||
*/
|
||||
exchangeRecordList(param) {
|
||||
return uni.api.get("/api/points/exchange-record/page", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 积分-获取订单可用积分及抵扣金额
|
||||
* @param {Object} param
|
||||
*/
|
||||
calcUsablePoints(param) {
|
||||
return uni.api.get("/api/points/member-points/calc-usable-points", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享-获取邀请页数据
|
||||
* @param {Object} param
|
||||
*/
|
||||
getByShopId(param) {
|
||||
return uni.api.get("/tbShopShare/getByShopId", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享-邀请记录
|
||||
* @param {Object} param
|
||||
*/
|
||||
shareRecord(param) {
|
||||
return uni.api.get("/tbShopShare/record", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享-被邀请人进入页面时使用
|
||||
* @param {Object} param
|
||||
*/
|
||||
shareHeOpen(param) {
|
||||
return uni.api.post("/tbShopShare/open", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享-被邀请人领取优惠券时使用
|
||||
* @param {Object} param
|
||||
*/
|
||||
shareReceive(param) {
|
||||
return uni.api.post("/tbShopShare/receive", param);
|
||||
},
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
export default {
|
||||
|
||||
/**
|
||||
* 获取排号信息
|
||||
* @param {Object} param
|
||||
*/
|
||||
getQueueUpList(param) {
|
||||
return uni.api.get("/callTable/queue", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取桌型列表
|
||||
* @param {Object} param
|
||||
*/
|
||||
getQueueUpTablList(param) {
|
||||
return uni.api.get("/callTable", param);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取号
|
||||
* @param {Object} data
|
||||
*/
|
||||
getTakeNumber(data) {
|
||||
return uni.api.post("/callTable/takeNumber", data, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消排号
|
||||
* @param {Object} data
|
||||
*/
|
||||
cancelTakeNumber(data) {
|
||||
return uni.api.post("/callTable", data, false);
|
||||
},
|
||||
}
|
||||
15879
common/js/city.json
15879
common/js/city.json
File diff suppressed because it is too large
Load Diff
74
common/js/lange.js
Normal file
74
common/js/lange.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const env = {
|
||||
aliyunServerURL: 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com',
|
||||
accessid: 'LTAI5tMLHwnM1zYYAFuRa1fK',
|
||||
AccessKeySecret: 'jS1h2STq1vcODczDNFQkjcU6ODyYAj',
|
||||
timeout: 100000
|
||||
}
|
||||
|
||||
const Base64 = require('./Base64.js');
|
||||
|
||||
require('./hmac.js');
|
||||
require('./sha1.js');
|
||||
const Crypto = require('./crypto.js');
|
||||
|
||||
|
||||
const uploadFile = function(filePath, key = new Date().getTime()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// const aliyunFileKey = `${new Date().getTime()}_${userId}`;
|
||||
const aliyunServerURL = env.aliyunServerURL;
|
||||
const accessid = env.accessid;
|
||||
const policyBase64 = getPolicyBase64();
|
||||
const signature = getSignature(policyBase64);
|
||||
|
||||
wx.uploadFile({
|
||||
url: aliyunServerURL, //仅为示例,非真实的接口地址
|
||||
filePath: filePath,
|
||||
name: 'file',
|
||||
formData: {
|
||||
'key': 'headportrait/' + key,
|
||||
'OSSAccessKeyId': accessid,
|
||||
'policy': policyBase64,
|
||||
'Signature': signature,
|
||||
'success_action_status': '200',
|
||||
},
|
||||
success: function(res) {
|
||||
if (res.statusCode != 200) {
|
||||
reject('上传错误:' + JSON.stringify(res))
|
||||
return;
|
||||
}
|
||||
resolve(`https://czh5.sxczgkj.cn/headportrait/${key}`)
|
||||
},
|
||||
fail: function(err) {
|
||||
reject('上传错误:' + JSON.stringify(err))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getPolicyBase64 = function() {
|
||||
let date = new Date();
|
||||
date.setHours(date.getHours() + env.timeout);
|
||||
let srcT = date.toISOString();
|
||||
const policyText = {
|
||||
"expiration": srcT, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了 指定了Post请求必须发生在2020年01月01日12点之前("2020-01-01T12:00:00.000Z")。
|
||||
"conditions": [
|
||||
["content-length-range", 0, 20 * 1024 * 1024] // 设置上传文件的大小限制,1048576000=1000mb
|
||||
]
|
||||
};
|
||||
|
||||
const policyBase64 = Base64.encode(JSON.stringify(policyText));
|
||||
return policyBase64;
|
||||
}
|
||||
|
||||
const getSignature = function(policyBase64) {
|
||||
const accesskey = env.AccessKeySecret;
|
||||
|
||||
const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
|
||||
asBytes: true
|
||||
});
|
||||
const signature = Crypto.util.bytesToBase64(bytes);
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
module.exports = uploadFile;
|
||||
5
common/js/shop.js
Normal file
5
common/js/shop.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
userwxlogin(data) { //登录
|
||||
return uni.api.post("/login/wx/custom/login", data, type = 2);
|
||||
},
|
||||
}
|
||||
@@ -1,231 +1,148 @@
|
||||
class webSocketUtils {
|
||||
constructor(url, time, params) {
|
||||
this.socketTask = null;
|
||||
this.is_open_socket = false; //避免重复连接
|
||||
this.url = url;
|
||||
this.params = params ? params : null; ////是否初始化请求
|
||||
this.connectNum = 1; // 重连次数
|
||||
//这个参数是防止重连失败之后onClose方法会重复执行reconnect方法,导致重连定时器出问题
|
||||
//连接并打开之后可重连,且只执行重连方法一次
|
||||
this.canReconnect = false; // 是否可以重连
|
||||
//心跳检测
|
||||
this.timeout = time ? time : 5000; //多少秒执行检测
|
||||
this.heartbeatInterval = null; //检测服务器端是否还活着
|
||||
this.reconnectTimeOut = null; //重连之后多久再次重连
|
||||
try {
|
||||
|
||||
return this.connectSocketInit({
|
||||
data: this.params,
|
||||
type: 'connectSocketInit',
|
||||
});
|
||||
} catch (e) {
|
||||
// console.log('catch');
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
|
||||
connectSocketInit(data) {
|
||||
let _this = this;
|
||||
this.data = data;
|
||||
// #ifdef MP-WEIXIN
|
||||
this.socketTask = uni.connectSocket({
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.connectSocket({
|
||||
// #endif
|
||||
url: this.url,
|
||||
success: (res) => {
|
||||
console.log('创建websocketc成功...');
|
||||
// uni.hideLoading();
|
||||
// 返回实例
|
||||
return this.socketTask;
|
||||
},
|
||||
fail: (res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
this.socketTask.onOpen((res) => {
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.onSocketOpen((res) => {
|
||||
// #endif
|
||||
uni.hideLoading()
|
||||
this.connectNum = 1;
|
||||
console.log('WebSocket连接正常!==',res);
|
||||
if (this.params) { //是否初始化请求
|
||||
this.send(this.params);
|
||||
}
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
clearInterval(this.heartbeatInterval);
|
||||
this.is_open_socket = true;
|
||||
this.canReconnect = true;
|
||||
this.start();
|
||||
// 注:只有连接正常打开中 ,才能正常收到消息
|
||||
// #ifdef MP-WEIXIN
|
||||
this.socketTask.onMessage((e) => {
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.onSocketMessage((e)=>{
|
||||
// #endif
|
||||
// 字符串转json
|
||||
let res = JSON.parse(e.data);
|
||||
uni.$emit('message', res)
|
||||
// 普通socket信息处理 TODO
|
||||
});
|
||||
});
|
||||
|
||||
// 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.onSocketError((res) => {
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.onSocketError((res) => {
|
||||
// #endif
|
||||
console.log('网络断开,请检查!');
|
||||
this.socketTask = null;
|
||||
this.is_open_socket = false;
|
||||
// this.Close()
|
||||
this.canReconnect = true;
|
||||
clearInterval(this.heartbeatInterval);
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
try {
|
||||
if (this.connectNum <= 10) {
|
||||
// uni.showLoading({
|
||||
// title: `网络连接失败,正尝试第${this.connectNum}次连接`,
|
||||
// mask: true
|
||||
// })
|
||||
uni.$emit('message', 1) //进行重连
|
||||
uni.showToast({
|
||||
title: `网络连接失败,正尝试第${this.connectNum}次连接`,
|
||||
icon: 'none',
|
||||
});
|
||||
this.reconnect();
|
||||
this.connectNum += 1;
|
||||
} else {
|
||||
// uni.$emit('connectError');
|
||||
uni.showToast({
|
||||
title: `网络连接失败,请检查网络!`,
|
||||
icon: 'none',
|
||||
});
|
||||
this.connectNum = 1;
|
||||
this.canReconnect = false;
|
||||
this.Close()
|
||||
setTimeout(res => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
uni.hideLoading()
|
||||
}, 1000)
|
||||
}
|
||||
} catch (e) {
|
||||
//TODO handle the exception
|
||||
}
|
||||
});
|
||||
// 这里仅是事件监听【如果socket关闭了会执行】
|
||||
// #ifdef MP-WEIXIN
|
||||
this.socketTask.onClose(() => {
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.onSocketClose((res) => {
|
||||
// #endif
|
||||
console.log("socket关闭了")
|
||||
this.socketTask = null;
|
||||
clearInterval(this.heartbeatInterval);
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
// #ifdef MP-ALIPAY
|
||||
// 支付宝小程序的ws连接问题,关闭连接时需关闭对于接受,防止关闭失败
|
||||
my.offSocketMessage();
|
||||
my.offSocketError();
|
||||
my.offSocketOpen();
|
||||
my.offSocketClose();
|
||||
// #endif
|
||||
this.is_open_socket = false;
|
||||
if (this.canReconnect) {
|
||||
this.reconnect();
|
||||
this.canReconnect = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 主动关闭socket连接
|
||||
Close() {
|
||||
this.is_open_socket = true;
|
||||
this.canReconnect = false;
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
if (this.socketTask) {
|
||||
this.socketTask.close({
|
||||
success(res) {
|
||||
console.log('手动关闭成功');
|
||||
},
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.closeSocket({
|
||||
success(res) {
|
||||
console.log('手动关闭成功');
|
||||
// #ifdef MP-ALIPAY
|
||||
// 支付宝小程序的ws连接问题,关闭连接时需关闭对于接受,防止关闭失败
|
||||
my.offSocketMessage();
|
||||
my.offSocketError();
|
||||
my.offSocketOpen();
|
||||
my.offSocketClose();
|
||||
// #endif
|
||||
|
||||
},
|
||||
fail: (res) => {
|
||||
console.log('手动关闭失败==',res);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
//发送消息
|
||||
send(data) {
|
||||
// console.log("发送消息---------->", data);
|
||||
// 注:只有连接正常打开中 ,才能正常成功发送消息
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
if (this.socketTask) {
|
||||
this.socketTask.send({
|
||||
data: JSON.stringify(data),
|
||||
async success() {
|
||||
// console.log("消息发送成功");
|
||||
},
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
my.sendSocketMessage({
|
||||
data: JSON.stringify(data),
|
||||
success(res) {
|
||||
// console.log("消息发送成功");
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
//开启心跳检测
|
||||
start(data) {
|
||||
// console.log('开启心跳检测', data)
|
||||
this.heartbeatInterval = setInterval(() => {
|
||||
this.send({
|
||||
data: '心跳检测',
|
||||
type: 'heartbeat',
|
||||
});
|
||||
}, this.timeout);
|
||||
}
|
||||
//重新连接
|
||||
reconnect() {
|
||||
//停止发送心跳
|
||||
clearInterval(this.heartbeatInterval);
|
||||
//如果不是人为关闭的话,进行重连
|
||||
if (!this.is_open_socket) {
|
||||
console.log('进行重连');
|
||||
this.canReconnect = true;
|
||||
this.reconnectTimeOut = setInterval(() => {
|
||||
this.connectSocketInit(this.data);
|
||||
}, this.timeout);
|
||||
}
|
||||
}
|
||||
constructor(url, time, params) {
|
||||
this.socketTask = null;
|
||||
this.is_open_socket = false; //避免重复连接
|
||||
this.url = url;
|
||||
this.params = params ? params : null;////是否初始化请求
|
||||
this.connectNum = 1; // 重连次数
|
||||
//这个参数是防止重连失败之后onClose方法会重复执行reconnect方法,导致重连定时器出问题
|
||||
//连接并打开之后可重连,且只执行重连方法一次
|
||||
this.canReconnect = false; // 是否可以重连
|
||||
//心跳检测
|
||||
this.timeout = time ? time : 5000; //多少秒执行检测
|
||||
this.heartbeatInterval = null; //检测服务器端是否还活着
|
||||
this.reconnectTimeOut = null; //重连之后多久再次重连
|
||||
try {
|
||||
return this.connectSocketInit({
|
||||
data: this.params,
|
||||
type: 'connectSocketInit',
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('catch');
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
|
||||
connectSocketInit (data) {
|
||||
console.log(data,"初始化")
|
||||
this.data = data;
|
||||
// console.log('this.url==', this.url);
|
||||
// console.log('this.params==', this.params);
|
||||
this.socketTask = uni.connectSocket({
|
||||
url: this.url,
|
||||
success: () => {
|
||||
console.log('正准备建立websocket中...');
|
||||
uni.hideLoading();
|
||||
// 返回实例
|
||||
return this.socketTask;
|
||||
},
|
||||
});
|
||||
this.socketTask.onOpen((res) => {
|
||||
this.connectNum = 1;
|
||||
console.log('WebSocket连接正常!');
|
||||
if(this.params){//是否初始化请求
|
||||
this.send(this.params);
|
||||
}
|
||||
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
clearInterval(this.heartbeatInterval);
|
||||
this.is_open_socket = true;
|
||||
this.canReconnect = true;
|
||||
this.start();
|
||||
// 注:只有连接正常打开中 ,才能正常收到消息
|
||||
this.socketTask.onMessage((e) => {
|
||||
// 字符串转json
|
||||
let res = JSON.parse(e.data);
|
||||
uni.$emit('message', res)
|
||||
// 普通socket信息处理 TODO
|
||||
|
||||
});
|
||||
});
|
||||
// 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
|
||||
uni.onSocketError((res) => {
|
||||
console.log('网络断开,请检查!');
|
||||
this.socketTask = null;
|
||||
this.is_open_socket = false;
|
||||
this.canReconnect = true;
|
||||
clearInterval(this.heartbeatInterval);
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
if (this.connectNum <= 10) {
|
||||
uni.showToast({
|
||||
title: `网络连接失败,正尝试第${this.connectNum}次连接`,
|
||||
icon: 'none',
|
||||
});
|
||||
this.reconnect();
|
||||
this.connectNum += 1;
|
||||
} else {
|
||||
// uni.$emit('connectError');
|
||||
uni.showToast({
|
||||
title: `网络连接失败,请检查网络!`,
|
||||
icon: 'none',
|
||||
});
|
||||
this.connectNum = 1;
|
||||
this.canReconnect = false;
|
||||
}
|
||||
});
|
||||
// 这里仅是事件监听【如果socket关闭了会执行】
|
||||
this.socketTask.onClose(() => {
|
||||
this.socketTask = null;
|
||||
clearInterval(this.heartbeatInterval);
|
||||
clearInterval(this.reconnectTimeOut);
|
||||
|
||||
this.is_open_socket = false;
|
||||
if (this.canReconnect) {
|
||||
this.reconnect();
|
||||
this.canReconnect = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 主动关闭socket连接
|
||||
Close () {
|
||||
this.is_open_socket = true;
|
||||
this.canReconnect = false;
|
||||
if(this.socketTask){
|
||||
this.socketTask.close({
|
||||
success(res) {
|
||||
console.log('手动关闭成功');
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
//发送消息
|
||||
send(data) {
|
||||
console.log("发送消息---------->", data);
|
||||
// 注:只有连接正常打开中 ,才能正常成功发送消息
|
||||
if (this.socketTask) {
|
||||
this.socketTask.send({
|
||||
data: JSON.stringify(data),
|
||||
async success() {
|
||||
console.log("消息发送成功");
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
//开启心跳检测
|
||||
start(data) {
|
||||
console.log('开启心跳检测',data)
|
||||
// this.heartbeatInterval = setInterval(() => {
|
||||
// this.send({
|
||||
// data: '心跳检测',
|
||||
// type: 'jc',
|
||||
// });
|
||||
// }, this.timeout);
|
||||
}
|
||||
//重新连接
|
||||
reconnect() {
|
||||
//停止发送心跳
|
||||
clearInterval(this.heartbeatInterval);
|
||||
//如果不是人为关闭的话,进行重连
|
||||
if (!this.is_open_socket) {
|
||||
console.log('进行重连');
|
||||
// this.canReconnect = true;
|
||||
this.reconnectTimeOut = setInterval(() => {
|
||||
this.connectSocketInit(this.data);
|
||||
}, this.timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = webSocketUtils;
|
||||
@@ -1,155 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="swiperPanel" @touchstart="startMove" @touchend="endMove">
|
||||
<view class="swiperItem" v-for="(item, index) in swiperList" :key="index"
|
||||
:style="{transform: itemStyle[index].transform, zIndex: itemStyle[index].zIndex, opacity: itemStyle[index].opacity}">
|
||||
<view class="children">
|
||||
<image class="pic" :src="item.logo"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <swiper class="swiperItem" circular v-for="(item, index) in swiperList" :key="index"
|
||||
:style="{transform: itemStyle[index].transform, zIndex: itemStyle[index].zIndex, opacity: itemStyle[index].opacity}">
|
||||
<swiper-item class="children">
|
||||
<image class="pic" :src="item.logo"></image>
|
||||
</swiper-item>
|
||||
</swiper> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
swiperList: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
timersetnteritem: {
|
||||
type: String,
|
||||
default: '0'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timersetInterval: null,
|
||||
slideNote: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
screenWidth: 0,
|
||||
itemStyle: [
|
||||
{
|
||||
transform:''
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
timersetnteritem(newVal,oldVal) {
|
||||
if (newVal == 1) {
|
||||
clearTimeout(this.timersetInterval);
|
||||
this.timersetInterval = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
var macInfo = uni.getSystemInfoSync();
|
||||
this.screenWidth = macInfo.screenWidth;
|
||||
// 计算swiper样式
|
||||
this.swiperList.forEach((item, index) => {
|
||||
this.itemStyle.push(this.getStyle(index))
|
||||
})
|
||||
// this.timersetInterval = setInterval(() => {
|
||||
// this.endMove()
|
||||
// }, 2000);
|
||||
},
|
||||
methods: {
|
||||
getStyle(e) {
|
||||
if (e > this.swiperList.length / 2) {
|
||||
var right = this.swiperList.length - e
|
||||
return {
|
||||
transform: 'scale(' + (1) + ') translate(-' + (right * 20) + '%,0px)',
|
||||
zIndex: 9999 - right,
|
||||
opacity: 1
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
transform: 'scale(' + (1) + ') translate(' + (e * 20) + '%,0px)',
|
||||
zIndex: 9999 - e,
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
// if (e > this.swiperList.length / 2) {
|
||||
// var right = this.swiperList.length - e
|
||||
// return {
|
||||
// transform: 'scale(' + (1 - right / 10) + ') translate(-' + (right * 9) + '%,0px)',
|
||||
// zIndex: 9999 - right,
|
||||
// opacity: 0.8 / right
|
||||
// }
|
||||
// } else {
|
||||
// return {
|
||||
// transform: 'scale(' + (1 - e / 10) + ') translate(' + (e * 9) + '%,0px)',
|
||||
// zIndex: 9999 - e,
|
||||
// opacity: 0.8 / e
|
||||
// }
|
||||
// }
|
||||
},
|
||||
startMove(e) {
|
||||
this.slideNote.x = e.changedTouches[0] ? e.changedTouches[0].pageX : 0;
|
||||
this.slideNote.y = e.changedTouches[0] ? e.changedTouches[0].pageY : 0;
|
||||
},
|
||||
endMove(e) {
|
||||
var newList = JSON.parse(JSON.stringify(this.itemStyle))
|
||||
// if ((e.changedTouches[0].pageX - this.slideNote.x) < 0) {
|
||||
// 向左滑动
|
||||
var last = [newList.pop()]
|
||||
newList = last.concat(newList)
|
||||
// } else {
|
||||
// 向右滑动
|
||||
// newList.push(newList[0])
|
||||
// newList.splice(0, 1)
|
||||
// }
|
||||
this.itemStyle = newList
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.swiperPanel {
|
||||
height: 28rpx;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.swiperItem {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: all .5s;
|
||||
|
||||
/* 定义一个动画关键帧 */
|
||||
|
||||
|
||||
.children {
|
||||
height: 100%;
|
||||
width: 25%;
|
||||
// margin: 2rpx auto;
|
||||
|
||||
|
||||
/* 应用动画,设置动画时长、循环次数和速度曲线 */
|
||||
.pic {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 50%;
|
||||
// box-shadow: 0 0 10px #333;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<u-image :src="src" :radius="radius" :width="width" :height="height" :fade="false" :lazy-load="true" slot="loading"></u-image>
|
||||
<u-image :src="src" :radius="radius" :width="width" :height="height" :fade="false"></u-image>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
<template>
|
||||
<view class="uni-countdown">
|
||||
<text v-if="showDay" class="uni-countdown__number">{{ d }}</text>
|
||||
<text v-if="showDay" class="uni-countdown__splitor">天</text>
|
||||
<text class="uni-countdown__number">{{ h }}</text>
|
||||
<text class="uni-countdown__splitor">{{ showColon ? ':' : '时' }}</text>
|
||||
<text class="uni-countdown__number">{{ i }}</text>
|
||||
<text class="uni-countdown__splitor">{{ showColon ? ':' : '分' }}</text>
|
||||
<text class="uni-countdown__number">{{ s }}</text>
|
||||
<text v-if="!showColon" class="uni-countdown__splitor">秒</text>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
/**
|
||||
* Countdown 倒计时
|
||||
* @description 倒计时组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=25
|
||||
* @property {String} backgroundColor 背景色
|
||||
* @property {String} color 文字颜色
|
||||
* @property {Number} day 天数
|
||||
* @property {Number} hour 小时
|
||||
* @property {Number} minute 分钟
|
||||
* @property {Number} second 秒
|
||||
* @property {Boolean} showDay = [true|false] 是否显示天数
|
||||
* @property {Boolean} showColon = [true|false] 是否以冒号为分隔符
|
||||
* @property {String} splitorColor 分割符号颜色
|
||||
* @event {Function} timeup 倒计时时间到触发事件
|
||||
* @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
|
||||
*/
|
||||
export default {
|
||||
name: 'UniCountdown',
|
||||
props: {
|
||||
showDay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showColon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: '#FFFFFF'
|
||||
},
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
splitorColor: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
indexs: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
day: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
hour: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
minute: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
second: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
syncFlag: false,
|
||||
d: '00',
|
||||
h: '00',
|
||||
i: '00',
|
||||
s: '00',
|
||||
leftTime: 0,
|
||||
seconds: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
day(val) {
|
||||
this.changeFlag()
|
||||
},
|
||||
hour(val) {
|
||||
this.changeFlag()
|
||||
},
|
||||
minute(val) {
|
||||
this.changeFlag()
|
||||
},
|
||||
second(val) {
|
||||
this.changeFlag()
|
||||
}
|
||||
},
|
||||
created: function(e) {
|
||||
this.startData();
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
toSeconds(day, hours, minutes, seconds) {
|
||||
return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
|
||||
},
|
||||
timeUp() {
|
||||
console.log(1)
|
||||
clearInterval(this.timer)
|
||||
this.$emit('timeup',this.indexs)
|
||||
},
|
||||
countDown() {
|
||||
let seconds = this.seconds
|
||||
let [day, hour, minute, second] = [0, 0, 0, 0]
|
||||
if (seconds > 0) {
|
||||
day = Math.floor(seconds / (60 * 60 * 24))
|
||||
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
|
||||
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
|
||||
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
|
||||
} else {
|
||||
this.timeUp()
|
||||
}
|
||||
if (day < 10) {
|
||||
day = '0' + day
|
||||
}
|
||||
if (hour < 10) {
|
||||
hour = '0' + hour
|
||||
}
|
||||
if (minute < 10) {
|
||||
minute = '0' + minute
|
||||
}
|
||||
if (second < 10) {
|
||||
second = '0' + second
|
||||
}
|
||||
this.d = day
|
||||
this.h = hour
|
||||
this.i = minute
|
||||
this.s = second
|
||||
},
|
||||
startData() {
|
||||
this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
|
||||
if (this.seconds <= 0) {
|
||||
return
|
||||
}
|
||||
this.countDown()
|
||||
this.timer = setInterval(() => {
|
||||
this.seconds--
|
||||
if (this.seconds < 0) {
|
||||
this.timeUp()
|
||||
return
|
||||
}
|
||||
this.countDown()
|
||||
}, 1000)
|
||||
},
|
||||
changeFlag() {
|
||||
console.log(this.syncFlag,111111)
|
||||
if (!this.syncFlag) {
|
||||
this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
|
||||
this.startData();
|
||||
this.syncFlag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.uni-countdown {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.uni-countdown__splitor {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.uni-countdown__number {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,267 +0,0 @@
|
||||
<template>
|
||||
<view class='keyboard' @click.stop='_handleKeyPress'>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='7'>7</view>
|
||||
<view class='key-cell cell_b' data-num='8'>8</view>
|
||||
<view class='key-cell cell_b' data-num='9'>9</view>
|
||||
<view class='key-cell cell_b' data-num='-1'></view>
|
||||
</view>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='4'>4</view>
|
||||
<view class='key-cell cell_b' data-num='5'>5</view>
|
||||
<view class='key-cell cell_b' data-num='6'>6</view>
|
||||
<view class='key-cell cell_b' data-num='-1'></view>
|
||||
</view>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='1'>1</view>
|
||||
<view class='key-cell cell_b' data-num='2'>2</view>
|
||||
<view class='key-cell cell_b' data-num='3'>3</view>
|
||||
<view class='key-cell cell_b' data-num='-1'></view>
|
||||
</view>
|
||||
<view class="key-zero-and-point">
|
||||
<view class="a cell_b zero" data-num='0'>0</view>
|
||||
<view class="a cell_b point" data-num='.'>.</view>
|
||||
</view>
|
||||
|
||||
<view @touchstart="touchstart" @touchend="touchend" data-num='D' class="key-confirm2">
|
||||
<text data-num='D'>C</text>
|
||||
</view>
|
||||
|
||||
<view class='key-confirm' :style="{'background':btnColor}" data-num='S'>
|
||||
<view data-num='S' class="">
|
||||
<view data-num='S' class="title">{{title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
name:"keyBoard",
|
||||
props:{
|
||||
title:{
|
||||
default:'确认',
|
||||
type:String
|
||||
},
|
||||
btnColor:{
|
||||
default:'green',
|
||||
}
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
money:'',
|
||||
Cdel:'',
|
||||
Time:''
|
||||
}
|
||||
},
|
||||
|
||||
watch:{
|
||||
money(val){
|
||||
this.$emit('update:money',val);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
methods : {
|
||||
touchstart(){
|
||||
this.Time=setInterval(()=>{
|
||||
console.log(this.money);
|
||||
if(this.money==''){
|
||||
clearInterval();
|
||||
}
|
||||
this.money = this.money.substring(0,this.money.length - 1);
|
||||
},200)
|
||||
},
|
||||
touchend(){
|
||||
clearInterval(this.Time);
|
||||
},
|
||||
//处理按键
|
||||
_handleKeyPress(e) {
|
||||
console.log('点击传e',e.target.dataset.num);
|
||||
let num = e.target.dataset.num;
|
||||
//不同按键处理逻辑
|
||||
// -1 代表无效按键,直接返回
|
||||
if (num == -1) return false;
|
||||
switch (String(num)) {
|
||||
//小数点
|
||||
case '.':
|
||||
this._handleDecimalPoint();
|
||||
break;
|
||||
//删除键
|
||||
case 'D':
|
||||
this._handleDeleteKey();
|
||||
break;
|
||||
//清空键
|
||||
case 'C':
|
||||
this._handleClearKey();
|
||||
break;
|
||||
//确认键
|
||||
case 'S':
|
||||
this._handleConfirmKey();
|
||||
break;
|
||||
default:
|
||||
this._handleNumberKey(num);
|
||||
break;
|
||||
}
|
||||
},
|
||||
//处理小数点函数
|
||||
_handleDecimalPoint() {
|
||||
//如果包含小数点,直接返回
|
||||
if (this.money.indexOf('.') > -1) return false;
|
||||
//如果小数点是第一位,补0
|
||||
if (!this.money.length)
|
||||
this.money = '0.';
|
||||
//如果不是,添加一个小数点
|
||||
else
|
||||
this.money = this.money + '.';
|
||||
},
|
||||
//处理删除键
|
||||
_handleDeleteKey() {
|
||||
let S = this.money;
|
||||
//如果没有输入,直接返回
|
||||
if (!S.length) return false;
|
||||
//否则删除最后一个
|
||||
this.money = S.substring(0, S.length - 1);
|
||||
},
|
||||
|
||||
//处理清空键
|
||||
_handleClearKey() {
|
||||
this.money = '';
|
||||
},
|
||||
|
||||
//处理数字
|
||||
_handleNumberKey(num) {
|
||||
if(this.money.length==10){
|
||||
return
|
||||
}
|
||||
let S = this.money;
|
||||
//如果有小数点且小数点位数不小于2
|
||||
if ( S.indexOf('.') > -1 && S.substring(S.indexOf('.') + 1).length < 2)
|
||||
this.money = S + num;
|
||||
//没有小数点
|
||||
if (!(S.indexOf('.') > -1)) {
|
||||
//如果第一位是0,只能输入小数点
|
||||
if (num == 0 && S.length == 0)
|
||||
this.money = '0.';
|
||||
else {
|
||||
if (S.length && Number(S.charAt(0)) === 0) return;
|
||||
this.money = S + num;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//提交
|
||||
_handleConfirmKey() {
|
||||
let S = this.money;
|
||||
//未输入
|
||||
if (!S.length||S==0){
|
||||
uni.showToast({
|
||||
title: '请输入正确的数值',
|
||||
icon:'none',
|
||||
duration: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
//将 8. 这种转换成 8.00
|
||||
if (S.indexOf('.') > -1 && S.indexOf('.') == (S.length - 1))
|
||||
S = Number(S.substring(0, S.length - 1)).toFixed(2);
|
||||
//保留两位
|
||||
S = Number(S).toFixed(2);
|
||||
this.$emit('confirmEvent',S); //提交参数
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.cell_b{
|
||||
border-right: 1px solid #d5d5d6;
|
||||
border-bottom: 1px solid #d5d5d6;
|
||||
}
|
||||
|
||||
.key-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.keyboard {
|
||||
flex: 1;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 40vh;
|
||||
width: 100%;
|
||||
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.keyboard .key-row {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
position: relative;
|
||||
height: 10vh;
|
||||
line-height: 10vh;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.keyboard .key-cell {
|
||||
flex: 1;
|
||||
-webkit-box-flex: 1;
|
||||
font-size: 60upx;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keyboard .key-confirm {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
height: 30vh;
|
||||
width: 25%;
|
||||
line-height: 30vh;
|
||||
color: #FFFFFF;
|
||||
z-index: 5;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keyboard .key-confirm2 {
|
||||
position: absolute;
|
||||
height: 10vh;
|
||||
width: 25%;
|
||||
line-height: 10vh;
|
||||
z-index: 9999;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.key-zero-and-point{
|
||||
display: flex;height: 10vh;justify-content: center;align-items: center;width:75%;font-size: 60upx;
|
||||
.zero{
|
||||
display: flex;justify-content: center;align-items: center;width: 66.66%;font-size: 60upx;text-align: center;height: 100%;
|
||||
}
|
||||
.point{
|
||||
display: flex;justify-content: center;align-items: center;width: 33.33%;font-size: 60upx;text-align: center;height: 100%;
|
||||
}
|
||||
}
|
||||
.key-cell:active{
|
||||
color: white;
|
||||
background: black; //黑色
|
||||
opacity: 0.1; //这里重要,就是通过这个透明度来设置
|
||||
}
|
||||
.a:active,.key-confirm2:active{
|
||||
color: white;
|
||||
background: black; //黑色
|
||||
opacity: 0.1; //这里重要,就是通过这个透明度来设置
|
||||
}
|
||||
</style>
|
||||
@@ -1,312 +0,0 @@
|
||||
<template>
|
||||
<view class='keyboard' :style="{position: pos}" @click.stop='_handleKeyPress'>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='1'>1</view>
|
||||
<view class='key-cell cell_b' data-num='2'>2</view>
|
||||
<view class='key-cell cell_b' data-num='3'>3</view>
|
||||
</view>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='4'>4</view>
|
||||
<view class='key-cell cell_b' data-num='5'>5</view>
|
||||
<view class='key-cell cell_b' data-num='6'>6</view>
|
||||
</view>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='7'>7</view>
|
||||
<view class='key-cell cell_b' data-num='8'>8</view>
|
||||
<view class='key-cell cell_b' data-num='9'>9</view>
|
||||
</view>
|
||||
<view class='key-row'>
|
||||
<view class='key-cell cell_b' data-num='.'></view>
|
||||
<view class='key-cell cell_b' data-num='0'>0</view>
|
||||
<view class='key-cell cell_b' data-num='D' style="background: #F9F9F9;" @touchstart="touchstart"
|
||||
@touchend="touchend">
|
||||
<image data-num='D' style="width: 47.49rpx; height: 25.59rpx;"
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/user/x.png" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="key-zero-and-point">
|
||||
<view class="a cell_b zero" data-num='0'>0</view>
|
||||
<view class="a cell_b point" data-num='.'>.</view>
|
||||
</view> -->
|
||||
<!-- <view class='key-confirm' :style="{'background':btnColor}" data-num='S'>
|
||||
<view data-num='S' class="">
|
||||
<view data-num='S' class="title">{{title}}</view>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "keyBoard",
|
||||
props: {
|
||||
title: {
|
||||
default: '确认',
|
||||
type: String
|
||||
},
|
||||
btnColor: {
|
||||
default: 'green',
|
||||
},
|
||||
pos: {
|
||||
default: 'fixed',
|
||||
type: String
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
money: '',
|
||||
Cdel: '',
|
||||
Time: ''
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
money(val) {
|
||||
this.$emit('update:money', val);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
touchstart() {
|
||||
this.Time = setInterval(() => {
|
||||
if (this.money == '') {
|
||||
clearInterval();
|
||||
}
|
||||
this.money = this.money.substring(0, this.money.length - 1);
|
||||
}, 200)
|
||||
},
|
||||
touchend() {
|
||||
clearInterval(this.Time);
|
||||
},
|
||||
//处理按键
|
||||
_handleKeyPress(e) {
|
||||
// console.log('点击传e', e.target.dataset.num);
|
||||
// #ifdef MP-WEIXIN
|
||||
let num = e.target.dataset.num;
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
let num = e.target.targetDataset.num;
|
||||
// #endif
|
||||
//不同按键处理逻辑
|
||||
// -1 代表无效按键,直接返回
|
||||
if (num == -1) return false;
|
||||
|
||||
switch (String(num)) {
|
||||
//小数点
|
||||
case '.':
|
||||
// uni.showToast({
|
||||
// title: '不可以设置.!',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// this._handleDecimalPoint();
|
||||
break;
|
||||
//删除键
|
||||
case 'D':
|
||||
this._handleDeleteKey();
|
||||
break;
|
||||
//清空键
|
||||
case 'C':
|
||||
this._handleClearKey();
|
||||
break;
|
||||
//确认键
|
||||
case 'S':
|
||||
this._handleConfirmKey();
|
||||
break;
|
||||
default:
|
||||
this._handleNumberKey(num);
|
||||
break;
|
||||
}
|
||||
},
|
||||
//处理小数点函数
|
||||
_handleDecimalPoint() {
|
||||
//如果包含小数点,直接返回
|
||||
if (this.money.indexOf('.') > -1) return false;
|
||||
//如果小数点是第一位,补0
|
||||
if (!this.money.length)
|
||||
this.money = '0.';
|
||||
//如果不是,添加一个小数点
|
||||
else
|
||||
this.money = this.money + '.';
|
||||
},
|
||||
//处理删除键
|
||||
_handleDeleteKey() {
|
||||
let S = this.money;
|
||||
//如果没有输入,直接返回
|
||||
if (!S.length) return false;
|
||||
//否则删除最后一个
|
||||
this.money = S.substring(0, S.length - 1);
|
||||
},
|
||||
|
||||
//处理清空键
|
||||
_handleClearKey() {
|
||||
this.money = '';
|
||||
},
|
||||
|
||||
//处理数字
|
||||
_handleNumberKey(num) {
|
||||
let S = this.money;
|
||||
//如果有小数点且小数点位数不小于2
|
||||
// if (S.indexOf('.') > -1 && S.substring(S.indexOf('.') + 1).length < 2)
|
||||
this.money = S + num;
|
||||
//没有小数点
|
||||
// if (!(S.indexOf('.') > -1)) {
|
||||
// //如果第一位是0,只能输入小数点
|
||||
// if (num == 0 && S.length == 0)
|
||||
// this.money = '0';
|
||||
// else {
|
||||
// if (S.length && Number(S.charAt(0)) === 0) return;
|
||||
// this.money = S + num;
|
||||
// }
|
||||
// }
|
||||
console.log(num)
|
||||
if (this.money.length == 6) {
|
||||
this.$emit('confirmEvent', this.money); //提交参数
|
||||
return
|
||||
}
|
||||
},
|
||||
|
||||
//提交
|
||||
_handleConfirmKey() {
|
||||
let S = this.money;
|
||||
//未输入
|
||||
if (!S.length || S == 0) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的数值',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
});
|
||||
return false;
|
||||
}
|
||||
//将 8. 这种转换成 8.00
|
||||
if (S.indexOf('.') > -1 && S.indexOf('.') == (S.length - 1))
|
||||
S = Number(S.substring(0, S.length - 1)).toFixed(2);
|
||||
//保留两位
|
||||
S = Number(S).toFixed(2);
|
||||
this.$emit('confirmEvent', S); //提交参数
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cell_b {
|
||||
border-right: 1px solid #DBDBDB;
|
||||
border-bottom: 1px solid #DBDBDB;
|
||||
}
|
||||
|
||||
.key-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.keyboard {
|
||||
flex: 1;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 32vh;
|
||||
width: 100%;
|
||||
z-index: 999;
|
||||
border-top: 1rpx solid #DBDBDB;
|
||||
padding-bottom: calc(24rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
.keyboard .key-row {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
position: relative;
|
||||
height: 8vh;
|
||||
line-height: 8vh;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.keyboard .key-cell {
|
||||
flex: 1;
|
||||
-webkit-box-flex: 1;
|
||||
font-family: Roboto, Roboto;
|
||||
font-weight: 400;
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keyboard .key-confirm {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
height: 30vh;
|
||||
width: 25%;
|
||||
line-height: 30vh;
|
||||
color: #FFFFFF;
|
||||
z-index: 5;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.keyboard .key-confirm2 {
|
||||
position: absolute;
|
||||
height: 8vh;
|
||||
width: 25%;
|
||||
line-height: 8vh;
|
||||
z-index: 9999;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.key-zero-and-point {
|
||||
display: flex;
|
||||
height: 8vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 75%;
|
||||
font-size: 60upx;
|
||||
|
||||
.zero {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 66.66%;
|
||||
font-size: 60upx;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.point {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 33.33%;
|
||||
font-size: 60upx;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.key-cell:active {
|
||||
color: white;
|
||||
background: black; //黑色
|
||||
opacity: 0.1; //这里重要,就是通过这个透明度来设置
|
||||
}
|
||||
|
||||
.a:active,
|
||||
.key-confirm2:active {
|
||||
color: white;
|
||||
background: black; //黑色
|
||||
opacity: 0.1; //这里重要,就是通过这个透明度来设置
|
||||
}
|
||||
</style>
|
||||
@@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<view class="l-barrage">
|
||||
<block v-for="(item,index) in items" :key="index">
|
||||
<!-- #ifdef H5 -->
|
||||
<text v-if="item.display" class="aon" :style="{top: `${item.top}%`,color: item.color}">
|
||||
{{item.text}}
|
||||
</text>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef H5 -->
|
||||
<!-- <text v-if="item.display" class="aon"
|
||||
:style="{top: `${item.top}%`,color: item.color,
|
||||
animation: `mymove ${Number(item.time)}s linear forwards`
|
||||
}"
|
||||
>
|
||||
{{item.text}}
|
||||
</text> -->
|
||||
<view v-if="item.display" class="aon"
|
||||
style=" display: flex;justify-content: center;align-items: center; background-color: #000; padding:10rpx; border-radius: 10rpx;"
|
||||
:style="{top: `${item.top}%`,
|
||||
animation: `mymove ${Number(item.time)}s linear forwards`
|
||||
}">
|
||||
<image style="width: 50rpx; height: 50rpx;border-radius: 50%;" :src="avatar"
|
||||
mode="aspectFill"></image>
|
||||
<text style="color: #fff;">
|
||||
{{item.text}}
|
||||
</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let cycle;
|
||||
|
||||
// 弹幕字体颜色
|
||||
function getRandomColor() {
|
||||
let rgb = []
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
let color = Math.floor(Math.random() * 256).toString(16)
|
||||
color = color.length == 1 ? '0' + color : color
|
||||
rgb.push(color)
|
||||
}
|
||||
return '#' + rgb.join('')
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'l-barrage',
|
||||
props: {
|
||||
minTime: {
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
maxTime: {
|
||||
type: Number,
|
||||
default: 9
|
||||
},
|
||||
minTop: {
|
||||
type: Number,
|
||||
default: 8
|
||||
},
|
||||
maxTop: {
|
||||
type: Number,
|
||||
default: 16
|
||||
},
|
||||
avatar:{
|
||||
type:String,
|
||||
default:'@/static/1.gif'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: [],
|
||||
userInfo: uni.cache.get('userInfo'), //个人信息
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add(text = '', time = Math.ceil(Math.floor(Math.random() * (this.maxTime - this.minTime + 1) + this
|
||||
.minTime))) {
|
||||
this.items.push({
|
||||
text,
|
||||
time,
|
||||
top: Math.ceil(Math.random() * (this.maxTop - this.minTop + 1) + this.minTop),
|
||||
color: getRandomColor(),
|
||||
display: 1,
|
||||
});
|
||||
},
|
||||
start(items = []) {
|
||||
this.items = [];
|
||||
cycle && (clearInterval(cycle));
|
||||
let i = 0,
|
||||
len = items.length;
|
||||
|
||||
cycle = setInterval(() => {
|
||||
let time = 5;
|
||||
// #ifndef H5
|
||||
time = Math.ceil(Math.floor(Math.random() * (this.maxTime - this.minTime + 1) + this.minTime));
|
||||
// #endif
|
||||
|
||||
if (i < len) {
|
||||
this.add(items[i], time);
|
||||
i++;
|
||||
} else {
|
||||
clearInterval(cycle);
|
||||
setTimeout(() => {
|
||||
this.$emit("end", {});
|
||||
}, time * 1000)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.aon {
|
||||
position: fixed;
|
||||
white-space: nowrap;
|
||||
|
||||
animation: mymove 5s linear forwards;
|
||||
animation-timing-function: linear;
|
||||
-webkit-animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.l-barrage {
|
||||
z-index: 99;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
@keyframes mymove {
|
||||
from {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
left: -200%;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes mymove
|
||||
|
||||
/* Firefox */
|
||||
{
|
||||
from {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
left: -200%;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes mymove
|
||||
|
||||
/* Safari and Chrome */
|
||||
{
|
||||
from {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
left: -200%;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes mymove
|
||||
|
||||
/* Opera */
|
||||
{
|
||||
from {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
to {
|
||||
left: -200%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="contentone flex-center">
|
||||
<image class="contentoneimage" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/drder/ewm.png" mode="aspectFill"></image>
|
||||
<text class="contentonetext">精选推荐</text>
|
||||
</view>
|
||||
<view class="contenttow flex-between">
|
||||
<view class="contenttowitem" v-for="(item,index) in list" :key="index" @click="clickproduct(item)">
|
||||
<image class="contenttowitemimage" :src="item.image" mode="aspectFill"></image>
|
||||
<view class="contenttowitemtiter">
|
||||
{{item.shopName}}|{{item.productName}}
|
||||
</view>
|
||||
<view class="contenttowitemone flex-between">
|
||||
<view class="contenttowitemone_dingwei flex-start">
|
||||
<image class="contenttowitemone_dingweiimage"
|
||||
:src="item.image" mode="aspectFill"></image>
|
||||
<view class="contenttowitemone_dingweinumer">
|
||||
{{item.distances}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="contenttowitemone_text">
|
||||
已售{{item.realSalesNumber}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="contenttowitemtow flex-start">
|
||||
<view class="contenttowitemtow_one">
|
||||
券后¥{{item.salePrice}}
|
||||
</view>
|
||||
<view class="contenttowitemtow_tow">
|
||||
{{item.discount}}折
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
opacity: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
titleshow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
HeighT() { //手机类型的尺寸
|
||||
return this.$store.getters.is_BarHeight
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clickproduct(item) {
|
||||
uni.pro.navigateTo('product/index', {
|
||||
id:item.id
|
||||
})
|
||||
},
|
||||
clicknavigateBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
background: #F9F9F9;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 32rpx;
|
||||
|
||||
.contentone {
|
||||
.contentoneimage {
|
||||
width: 32.12rpx;
|
||||
height: 36.13rpx;
|
||||
}
|
||||
|
||||
.contentonetext {
|
||||
margin-left: 12rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
.contenttow {
|
||||
width: 100%;
|
||||
|
||||
.contenttowitem {
|
||||
margin-top: 32rpx;
|
||||
width: 316rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||||
|
||||
.contenttowitemimage {
|
||||
width: 100%;
|
||||
height: 220rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
||||
}
|
||||
|
||||
.contenttowitemtiter {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 8rpx;
|
||||
width: 100%;
|
||||
height: 72rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.contenttowitemone {
|
||||
padding: 0 20rpx;
|
||||
.contenttowitemone_dingwei {
|
||||
margin-top: 6rpx;
|
||||
.contenttowitemone_dingweiimage {
|
||||
width: 17.9rpx;
|
||||
height: 21.65rpx;
|
||||
}
|
||||
|
||||
.contenttowitemone_dingweinumer {
|
||||
margin-left: 12rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 20rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.contenttowitemone_text {
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 20rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.contenttowitemtow {
|
||||
padding: 0 20rpx 8rpx 20rpx;
|
||||
|
||||
.contenttowitemtow_one {
|
||||
margin-top: 6rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #FF4C11;
|
||||
}
|
||||
|
||||
.contenttowitemtow_tow {
|
||||
margin-top: 6rpx;
|
||||
margin-left: 6rpx;
|
||||
padding: 2rpx 14rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||||
border: 2rpx solid #FF4C11;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 20rpx;
|
||||
color: #FF4C11;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,187 +0,0 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<!-- 导航栏 -->
|
||||
<view class="navbar" :class="{active:opacity}">
|
||||
<!-- #ifndef APP-PLUS || MP-WEIXIN || MP-ALIPAY -->
|
||||
<view class="status-bar"></view>
|
||||
<view class="navbar_tow 1 flex-between"
|
||||
:style="{'height':HeighT.customBar+'px','padding-right':HeighT.custwidth + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="status-bar"></view>
|
||||
<view class="navbar_tow 2 flex-between">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="navbar_tow 3 flex-between"
|
||||
:style="{'height':HeighT.customBar+'px','marginTop':HeighT.heightBar+'px','padding-right':HeighT.custwidth + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="navbar_tow 4 flex-between"
|
||||
:style="{'height':HeighT.customBar+'px','marginTop':HeighT.statusBar+'px','padding-right':menuButtonInfo.width+50 + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- 标题搜索框 -->
|
||||
<view class="flex-between">
|
||||
<view class="navbar_tow_one flex-start">
|
||||
<u-icon style="margin-left: 8rpx;" name="arrow-down-fill" color="#333333"
|
||||
size="16"></u-icon>
|
||||
</view>
|
||||
<view class="navbar_tow_tow flex-start">
|
||||
<input type="text" class="navbar_tow_towinput" v-model="keyword" placeholder="请输入关键字" />
|
||||
<view class="navbar_tow_towview">搜索</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
|
||||
console.log("menuButtonInfo==",menuButtonInfo)
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
opacity: false,
|
||||
};
|
||||
},
|
||||
onPageScroll(e) {
|
||||
if (e.scrollTop <= 44) { //搜索导航栏
|
||||
this.opacity = false
|
||||
} else {
|
||||
this.opacity = true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
HeighT() { //手机类型的尺寸
|
||||
console.log("navHeighT==",this.$store.getters.is_BarHeight)
|
||||
return this.$store.getters.is_BarHeight
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log(1)
|
||||
console.log(uni.getMenuButtonBoundingClientRect())
|
||||
},
|
||||
methods: {}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
background: #F9F9F9;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
|
||||
.active {
|
||||
background: rgba(249, 249, 249, 1);
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
// #ifdef APP-PLUS
|
||||
height: calc(var(--status-bar-height) / 2);
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
height: var(--status-bar-height);
|
||||
// #endif
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
.statusbarmargin {
|
||||
margin-top: var(--status-bar-height);
|
||||
}
|
||||
|
||||
// #endif
|
||||
.navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 99;
|
||||
|
||||
.navbar_tow {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
font-size: 36rpx;
|
||||
|
||||
.flex-between {
|
||||
// #ifdef APP-PLUS || H5
|
||||
margin: 28rpx;
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
margin-left: 28rpx;
|
||||
// #endif
|
||||
width: 100%;
|
||||
flex-wrap: nowrap;
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
|
||||
.navbar_tow_one {
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
|
||||
text:nth-child(1) {
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
text:nth-child(2) {
|
||||
margin-left: 16rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar_tow_tow {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
flex: 1;
|
||||
margin-left: 10rpx;
|
||||
|
||||
.navbar_tow_towview {
|
||||
position: absolute;
|
||||
right: 4rpx;
|
||||
top: 50%;
|
||||
transform: translate(0, -50%);
|
||||
text-align: center;
|
||||
background: #FEE06A;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
width: 116rpx;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
border-radius: 34rpx 34rpx 34rpx 34rpx;
|
||||
}
|
||||
|
||||
.navbar_tow_towinput {
|
||||
height: 64rpx;
|
||||
padding-left: 32rpx;
|
||||
padding-right: 116rpx;
|
||||
flex: auto;
|
||||
background: #FFFFFF;
|
||||
border-radius: 34rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
overflow: hidden; //超出的文本隐藏
|
||||
text-overflow: ellipsis; //溢出用省略号显示
|
||||
white-space: nowrap; //溢出不换行
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,295 +0,0 @@
|
||||
<template>
|
||||
<view class="navbarcontent">
|
||||
<!-- 导航栏 -->
|
||||
<view class="navbar" :class="{active:opacity}">
|
||||
<!-- #ifndef APP-PLUS || MP-WEIXIN || MP-ALIPAY -->
|
||||
<view class="status-bar"></view>
|
||||
<view class="navbar_tow flex-between"
|
||||
:style="{'height':HeighT.customBar+'px','padding-right':HeighT.custwidth + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="navbar_tow flex-between" :style="{'marginTop':HeighT.heightBar /2+'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="navbar_tow flex-between"
|
||||
:style="{'height':HeighT.customBar + ( (HeighT.heightBar - systemInfo.statusBarHeight)*2 )+'px','marginTop': ( HeighT.heightBar - (HeighT.heightBar - systemInfo.statusBarHeight))+'px','padding-right':HeighT.custwidth + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="navbar_tow flex-between"
|
||||
:style="{'height':systemInfo.titleBarHeight+'px','marginTop':systemInfo.statusBarHeight+'px','padding-right':menuButtonInfo.width+50 + 'px'}">
|
||||
<!-- #endif -->
|
||||
<!-- 标题搜索框 -->
|
||||
<view class="flex-between" v-if="opacity&&inputshow">
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<view class="navbar_tow_one flex-start" v-if="iconshow" @click="clicknavigateBack">
|
||||
<u-icon name="arrow-left" :color="iconcolor" size="40"></u-icon>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="navbar_tow_tow " @click="inputFocus" style="position: relative">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="navbar_tow_tow " @click="inputFocus" style="position: relative;padding-left: 60rpx;">
|
||||
<!-- #endif -->
|
||||
<u--input
|
||||
placeholder="请输入内容"
|
||||
class="custom-input"
|
||||
border="surround"
|
||||
:focus="focus"
|
||||
@confirm="confirmSearch"
|
||||
v-model="searchVal"
|
||||
:readonly="readonly"
|
||||
prefixIcon="search"
|
||||
prefixIconStyle="font-size: 18px;color: #909399"
|
||||
placeholderStyle="font-size: 14px;color: #999"
|
||||
fontSize="14px"
|
||||
:customStyle="{padding: '3rpx 10rpx ',width: '400rpx',borderRadius: '30rpx',backgroundColor: '#eee'}"
|
||||
|
||||
>
|
||||
</u--input>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 正常导航栏 -->
|
||||
<view class="flex-between" @click="clicknavigateBack" v-else>
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<view class="navbar_tow_one flex-start" v-if="iconshow">
|
||||
<u-icon name="arrow-left" :color="iconcolor" size="40"></u-icon>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN || MP-ALIPAY -->
|
||||
<view class="navbar_tow_tow" v-if="opacity || titleshow" :style="{color: namecolor}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="navbar_tow_tow" v-if="opacity || titleshow"
|
||||
:style="{'padding-left':HeighT.custwidth-14 + 'px',color: namecolor}">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="navbar_tow_tow" v-if="opacity || titleshow"
|
||||
:style="{'padding-left': 60 + 'rpx','textAlign': 'left',color: namecolor}">
|
||||
<!-- #endif -->
|
||||
{{title}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="" v-if="heightshow" :style="{height:Topdistance +'px'}">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
Topdistance: '',
|
||||
searchVal: "",
|
||||
systemInfo: '',
|
||||
// keyword
|
||||
};
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
namecolor: {
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
search: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
opacity: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
titleshow: { //标题是否显示
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
heightshow: { //是否要占位高度
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
iconshow: { //返回键是否显示
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
iconcolor: { //返回键颜色
|
||||
type: String,
|
||||
default: '#000'
|
||||
},
|
||||
navigateBacknavtitle: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
inputshow:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
focus:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
HeighT() { //手机类型的尺寸
|
||||
return this.$store.getters.is_BarHeight
|
||||
},
|
||||
menuButtonInfo() { //手机类型的尺寸
|
||||
return uni.getMenuButtonBoundingClientRect()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.GetTop()
|
||||
wx.getSystemInfo({
|
||||
success: res => {
|
||||
this.systemInfo = res;
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
// 当组件挂载完成后获取距离
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
GetTop() {
|
||||
this.$u.getRect('.navbar').then(res => {
|
||||
this.Topdistance = res.height //滚动距离
|
||||
this.$emit('Topdistance', res.height)
|
||||
})
|
||||
},
|
||||
clicknavigateBack() {
|
||||
if (this.navigateBacknavtitle) {
|
||||
this.$emit('navigateBacknav')
|
||||
} else {
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 搜索点击处理
|
||||
*/
|
||||
inputFocus() {
|
||||
console.log(123)
|
||||
this.$emit('searchStatus', 'searchClick')
|
||||
},
|
||||
confirmSearch () {
|
||||
this.$emit('searchVal', this.searchVal)
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
page {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.navbarcontent {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 9999;
|
||||
|
||||
.active {
|
||||
background: rgba(249, 249, 249, 1);
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
// #ifdef APP-PLUS
|
||||
height: calc(var(--status-bar-height) / 2);
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
height: var(--status-bar-height);
|
||||
// #endif
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
.statusbarmargin {
|
||||
margin-top: var(--status-bar-height);
|
||||
}
|
||||
|
||||
// #endif
|
||||
.navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 99;
|
||||
|
||||
.navbar_tow {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
font-size: 36rpx;
|
||||
|
||||
.flex-between {
|
||||
// #ifdef APP-PLUS || H5
|
||||
margin: 28rpx;
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
margin-left: 28rpx;
|
||||
// #endif
|
||||
width: 100%;
|
||||
flex-wrap: nowrap;
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
|
||||
.navbar_tow_one {
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
|
||||
text:nth-child(1) {
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
text:nth-child(2) {
|
||||
margin-left: 16rpx;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar_tow_tow {
|
||||
width: 200rpx;
|
||||
text-align: center;
|
||||
flex: auto;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
.u--input {
|
||||
width: 200rpx;
|
||||
input{
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,191 +0,0 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view>
|
||||
<view class="pay-title">
|
||||
<text>请输入6位支付密码</text>
|
||||
</view>
|
||||
<view class="pay-password" @click="onPayUp">
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 1">●</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 2">●</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 3">●</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 4">●</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 5">●</text>
|
||||
</view>
|
||||
<view class="list">
|
||||
<text v-if="passwordArr.length >= 6">●</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="hint" @click="gopaypassword">
|
||||
<text>忘记支付密码?</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- ref:唯一ref passwrdType:密码样式pay keyInfo:密码输入返回事件 -->
|
||||
<cc-defineKeyboard ref="CodeKeyboard" passwrdType="pay" @KeyInfo="KeyInfo"></cc-defineKeyboard>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// AffirmStatus: 1,
|
||||
passwordArr: [],
|
||||
oldPasswordArr: [],
|
||||
newPasswordArr: [],
|
||||
afPasswordArr: [],
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
// 忘记支付密码
|
||||
gopaypassword() {
|
||||
uni.pro.navigateTo('/pages/user/repairpassword')
|
||||
},
|
||||
/**
|
||||
* 唤起键盘
|
||||
*/
|
||||
onPayUp() {
|
||||
this.$refs.CodeKeyboard.show();
|
||||
},
|
||||
/**
|
||||
* 支付键盘回调
|
||||
* @param {Object} val
|
||||
*/
|
||||
KeyInfo(val) {
|
||||
console.log(val)
|
||||
if (val.index&&val.index >= 6) {
|
||||
return;
|
||||
}
|
||||
// 判断是否输入的是删除键
|
||||
if (val.keyCode === 8) {
|
||||
// 删除最后一位
|
||||
this.passwordArr.splice(val.index + 1, 1)
|
||||
}
|
||||
// 判断是否输入的是.
|
||||
else if (val.keyCode == 190) {
|
||||
// 输入.无效
|
||||
} else {
|
||||
this.passwordArr.push(val.key);
|
||||
}
|
||||
|
||||
// uni.showModal({
|
||||
// title: '温馨提示',
|
||||
// content: '输入密码是 = ' + JSON.stringify(this.passwordArr)
|
||||
// })
|
||||
|
||||
// 判断是否等于6
|
||||
if (this.passwordArr.length === 6) {
|
||||
// this.AffirmStatus = this.AffirmStatus + 1;
|
||||
let str = ''
|
||||
this.passwordArr.forEach(res => {
|
||||
str += res
|
||||
})
|
||||
this.$emit('accountPayevent', str)
|
||||
this.passwordArr = [];
|
||||
}
|
||||
// 判断到哪一步了
|
||||
// if (this.AffirmStatus === 1) {
|
||||
// this.oldPasswordArr = this.passwordArr;
|
||||
// } else if (this.AffirmStatus === 2) {
|
||||
// this.newPasswordArr = this.passwordArr;
|
||||
// } else if (this.AffirmStatus === 3) {
|
||||
// this.afPasswordArr = this.passwordArr;
|
||||
// } else if (this.AffirmStatus === 4) {
|
||||
// console.log(this.oldPasswordArr.join(''));
|
||||
// console.log(this.newPasswordArr.join(''));
|
||||
// console.log(this.afPasswordArr.join(''));
|
||||
// uni.showToast({
|
||||
// title: '修改成功',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// uni.navigateBack();
|
||||
// }, 2000)
|
||||
// }
|
||||
this.$forceUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$base: #555; // 基础颜色
|
||||
|
||||
.page {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #FFFFFF;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.pay-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #555555;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-password {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 90%;
|
||||
height: 80rpx;
|
||||
margin: 20rpx auto;
|
||||
border: 2rpx solid $base;
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 16.666%;
|
||||
height: 100%;
|
||||
border-right: 2rpx solid #EEEEEE;
|
||||
|
||||
text {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list:nth-child(6) {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: $base;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view style="margin-bottom: 128rpx;">
|
||||
<view class="contenttext flex-center">
|
||||
<text>¥</text>
|
||||
<text>{{payAmount}}</text>
|
||||
</view>
|
||||
<view class="contentbox flex-between">
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 1">●</text>
|
||||
</view>
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 2">●</text>
|
||||
</view>
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 3">●</text>
|
||||
</view>
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 4">●</text>
|
||||
</view>
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 5">●</text>
|
||||
</view>
|
||||
<view class="contentboxitem flex-colum">
|
||||
<text v-if="consumeFee.length >= 6">●</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<cwx-keyboard ref="keyboard" :pos="'inherit'" @confirmEvent="confirmEvent"
|
||||
:money.sync="consumeFee"></cwx-keyboard>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import cwxKeyboard from '@/components/cwx-keyboard/cwx-keyboard';
|
||||
export default {
|
||||
components: {
|
||||
cwxKeyboard
|
||||
},
|
||||
props: {
|
||||
payAmount: {
|
||||
default: 0,
|
||||
type: Number
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isPwd: uni.cache.get('userInfo').isPwd,
|
||||
consumeFee: '', //第一遍
|
||||
money: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
console.log(uni.cache.get('userInfo').isPwd)
|
||||
|
||||
},
|
||||
watch: {
|
||||
consumeFee(newVal, oldVal) {
|
||||
console.log(this.consumeFee)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
confirmEvent(val) {
|
||||
|
||||
// uni.showModal({
|
||||
// title: '温馨提示',
|
||||
// content: '输入密码是 = ' + JSON.stringify(this.passwordArr)
|
||||
// })
|
||||
|
||||
// 判断是否等于6
|
||||
if (val.length === 6) {
|
||||
this.$emit('accountPayevent', val)
|
||||
this.money = "";
|
||||
}
|
||||
this.$forceUpdate();
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.content {
|
||||
height: 100%;
|
||||
background: #FFFFFF;
|
||||
|
||||
.contenttext {
|
||||
padding: 48rpx 0;
|
||||
font-family: Source Han Sans CN, Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
font-size: 40rpx;
|
||||
color: #333333;
|
||||
text:nth-child(1){
|
||||
font-weight: bold;
|
||||
font-size: 48rpx;
|
||||
color: #333333;
|
||||
}
|
||||
text:nth-child(2){
|
||||
font-weight: bold;
|
||||
font-size: 60rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.contentbox {
|
||||
margin-top: 48rpx;
|
||||
padding: 0 56rpx;
|
||||
|
||||
.contentboxitem {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||||
border: 2rpx solid #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<picker mode="multiSelector"
|
||||
:value="multiIndex"
|
||||
:range="multiArray"
|
||||
@change="handleValueChange"
|
||||
@columnchange="handleColumnChange">
|
||||
<slot></slot>
|
||||
</picker>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const CHINA_REGIONS = require('./regions.json')
|
||||
export default {
|
||||
props:{
|
||||
defaultRegions:{
|
||||
type:Array,
|
||||
default(){
|
||||
return []
|
||||
}
|
||||
},
|
||||
defaultRegionCode:{
|
||||
type:String
|
||||
},
|
||||
defaultRegion:[String,Array]
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cityArr:CHINA_REGIONS[0].childs,
|
||||
districtArr:CHINA_REGIONS[0].childs[0].childs,
|
||||
multiIndex: [0, 0, 0],
|
||||
isInitMultiArray:true,
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
defaultRegion:{
|
||||
handler(region,oldRegion){
|
||||
if(Array.isArray(region)){
|
||||
// 避免传的是字面量的时候重复触发
|
||||
oldRegion = oldRegion || []
|
||||
if(region.join('')!==oldRegion.join('')){
|
||||
this.handleDefaultRegion(region)
|
||||
}
|
||||
}else if(region&®ion.length == 6){
|
||||
this.handleDefaultRegion(region)
|
||||
}else{
|
||||
console.warn('defaultRegion非有效格式')
|
||||
}
|
||||
},
|
||||
immediate:true,
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
multiArray(){
|
||||
return this.pickedArr.map(arr=>arr.map(item=>item.name))
|
||||
},
|
||||
pickedArr(){
|
||||
// 进行初始化
|
||||
if(this.isInitMultiArray){
|
||||
return [
|
||||
CHINA_REGIONS,
|
||||
CHINA_REGIONS[0].childs,
|
||||
CHINA_REGIONS[0].childs[0].childs
|
||||
]
|
||||
}
|
||||
return [CHINA_REGIONS,this.cityArr,this.districtArr];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleColumnChange(e){
|
||||
// console.log(e);
|
||||
this.isInitMultiArray = false;
|
||||
const that = this;
|
||||
let col = e.detail.column;
|
||||
let row = e.detail.value;
|
||||
that.multiIndex[col] = row;
|
||||
try{
|
||||
switch(col){
|
||||
case 0:
|
||||
if(CHINA_REGIONS[that.multiIndex[0]].childs.length==0){
|
||||
that.cityArr = that.districtArr = [CHINA_REGIONS[that.multiIndex[0]]]
|
||||
break;
|
||||
}
|
||||
that.cityArr = CHINA_REGIONS[that.multiIndex[0]].childs
|
||||
that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[that.multiIndex[1]].childs
|
||||
break;
|
||||
case 1:
|
||||
that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[that.multiIndex[1]].childs
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
}catch(e){
|
||||
// console.log(e);
|
||||
that.districtArr = CHINA_REGIONS[that.multiIndex[0]].childs[0].childs
|
||||
}
|
||||
|
||||
},
|
||||
handleValueChange(e){
|
||||
// 结构赋值
|
||||
let [index0,index1,index2] = e.detail.value;
|
||||
let [arr0,arr1,arr2] = this.pickedArr;
|
||||
let address = [arr0[index0],arr1[index1],arr2[index2]];
|
||||
// console.log(address);
|
||||
this.$emit('getRegion',address)
|
||||
},
|
||||
handleDefaultRegion(region){
|
||||
const isCode = !Array.isArray(region)
|
||||
this.isInitMultiArray = false;
|
||||
let children = CHINA_REGIONS
|
||||
for(let i=0;i<3;i++){
|
||||
for(let j=0;j<children.length;j++){
|
||||
let condition = isCode?children[j].code==region.slice(0,(i+1)*2):children[j].name.includes(region[i]);
|
||||
if(condition){
|
||||
// 匹配成功进行赋值
|
||||
// console.log(i,j,children.length-1);
|
||||
children = children[j].childs;
|
||||
if(i==0){
|
||||
this.cityArr = children
|
||||
}else if(i==1){
|
||||
this.districtArr = children
|
||||
}
|
||||
this.$set(this.multiIndex,i,j)
|
||||
// console.log(this.multiIndex);
|
||||
break;
|
||||
}else{
|
||||
// 首次匹配失败就用默认的初始化
|
||||
// console.log(i,j,children.length-1);
|
||||
if(i==0 && j==(children.length-1)){
|
||||
this.isInitMultiArray = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
File diff suppressed because one or more lines are too long
@@ -1,255 +0,0 @@
|
||||
<template>
|
||||
<view class="viewswiper" v-if="viewswiperShow">
|
||||
<view class="swiperBox">
|
||||
<u-swiper
|
||||
:list="popupadList"
|
||||
previousMargin="30"
|
||||
nextMargin="30"
|
||||
circular
|
||||
:autoplay="true"
|
||||
:indicator="false"
|
||||
keyName="imgUrl"
|
||||
radius='10'
|
||||
@change="e => current = e.current"
|
||||
@click="swiperClick"
|
||||
bgColor="transparent" height="920"
|
||||
>
|
||||
<!-- <view slot="indicator" class="indicator"> -->
|
||||
<!-- <view class="indicator__dot" v-for="(item, index) in carousel" :key="index"
|
||||
:class="[index === current && 'indicator__dot--active']"
|
||||
:style="[index === current && {'width':16+'px'}]">
|
||||
</view> -->
|
||||
<!-- </view> -->
|
||||
|
||||
</u-swiper>
|
||||
</view>
|
||||
|
||||
<u-icon name="close-circle" color="#fff" size="70" @click="closeClick"></u-icon>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
// import dayjs from "dayjs";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
current: 0,
|
||||
popupadList: [],
|
||||
viewswiperShow: false,
|
||||
time: false,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
showPosition: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
forceUpdate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
},
|
||||
watch: {
|
||||
forceUpdate(val,oldval) {
|
||||
// 在 forceUpdate 改变时执行更新操作
|
||||
let time = uni.cache.get('popUpTime') ? new Date().getTime() - uni.cache.get('popUpTime') : 1000;
|
||||
if ( time >= 1000 ) {
|
||||
uni.cache.set('popUpTime', new Date().getTime())
|
||||
this.getPopUpAd(); // 重新加载数据
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// if (uni.cache.get('shopId') && uni.cache.get('token')) {
|
||||
// }
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 轮播图点击
|
||||
*/
|
||||
swiperClick (e) {
|
||||
let item = this.popupadList[e];
|
||||
if ( item.linkPath ) {
|
||||
uni.pro.navigateTo(item.linkPath, {
|
||||
shopId: uni.cache.get('shopId'),
|
||||
is_type: "me",
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭广告
|
||||
*/
|
||||
closeClick () {
|
||||
this.viewswiperShow = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取弹窗广告
|
||||
*/
|
||||
async getPopUpAd () {
|
||||
let res = await this.api.getPopUpAd({
|
||||
shopId: uni.cache.get('shopId')
|
||||
})
|
||||
if (res.code == 0) {
|
||||
this.popupadList = [];
|
||||
// console.log(this.showPosition)
|
||||
// console.log(this.showPosition)
|
||||
// console.log(!uni.cache.get('popUpData'))
|
||||
if (!uni.cache.get('popUpData')) {
|
||||
res.data.forEach((item,index)=>{
|
||||
if ( item.showPosition == this.showPosition) {
|
||||
item["popUpTime"] = dayjs().format('YYYY-MM-DD');
|
||||
this.popupadList.push(item);
|
||||
}
|
||||
})
|
||||
uni.cache.set('popUpData', this.popupadList)
|
||||
} else {
|
||||
let popUpData = uni.cache.get('popUpData');
|
||||
res.data.forEach((item1,index1)=>{
|
||||
if ( popUpData.filter(obj => obj.id == item1.id).length > 0 ) {
|
||||
let obj = popUpData.filter(obj => obj.id == item1.id)[0];
|
||||
// console.log(this.showPosition)
|
||||
// console.log(item1.updateTime, obj.updateTime)
|
||||
// console.log(item1.showPosition == this.showPosition,this.isFrequency(item1.frequency,item1.popUpTime),item1.updateTime != obj.updateTime)
|
||||
if ( (item1.showPosition == this.showPosition && this.isFrequency(item1.frequency,item1.popUpTime)) || ( item1.showPosition == this.showPosition && item1.updateTime != obj.updateTime) ) {
|
||||
item1["popUpTime"] = dayjs().format('YYYY-MM-DD');
|
||||
this.popupadList.push(item1)
|
||||
}
|
||||
popUpData.forEach((item,index)=>{
|
||||
if ( item.id == item1.id && JSON.stringify(item1) != JSON.stringify(item) ) {
|
||||
popUpData[index]= item1;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if ( item1.showPosition == this.showPosition) {
|
||||
item1["popUpTime"] = dayjs().format('YYYY-MM-DD');
|
||||
this.popupadList.push(item1);
|
||||
popUpData.push(item1);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
// console.log(popUpData)
|
||||
uni.cache.set('popUpData', popUpData)
|
||||
// console.log(this.popupadList)
|
||||
// updateTime
|
||||
|
||||
}
|
||||
this.viewswiperShow = false;
|
||||
if ( this.popupadList.length > 0 ) {
|
||||
this.viewswiperShow = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isFrequency (frequency,popUpTime) {
|
||||
switch (frequency) {
|
||||
case "only_one": //仅首次展示
|
||||
return false;
|
||||
break;
|
||||
case 'every_show': //每次打开都展示
|
||||
return true;
|
||||
break;
|
||||
case 'every_day': //每天展示一次
|
||||
// return this.isTime("2024-08-22",1);
|
||||
return this.isTime(frequency,1);
|
||||
break;
|
||||
case 'three_day': //3天展示一次
|
||||
// return this.isTime("2024-08-20",1);
|
||||
return this.isTime(frequency,3);
|
||||
break;
|
||||
case 'seven_day': //7天展示一次
|
||||
// return this.isTime("2024-08-16",1);
|
||||
return this.isTime(frequency,7);
|
||||
break;
|
||||
case 'thirty_day': //30天展示一次
|
||||
// return this.isTime("2024-07-24",1);
|
||||
return this.isTime(frequency,30);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
isTime (popUpTime,num) {
|
||||
// 获取当前日期
|
||||
let date1 = dayjs();
|
||||
let date2 = dayjs(popUpTime).format('YYYY-MM-DD');
|
||||
// console.log(date1.diff(date2, "day"))
|
||||
if ( date1.diff(date2, "day") >= num ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
page{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.viewswiper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.swiperBox{
|
||||
width: 85%;
|
||||
margin-top: 50rpx;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
.swiper__wrapper__item__wrapper__image{
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.indicator {
|
||||
margin-bottom: 46rpx;
|
||||
@include flex(row);
|
||||
justify-content: center;
|
||||
|
||||
&__dot {
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 100px;
|
||||
background-color: rgba(255, 255, 255, 0.35);
|
||||
margin: 0 5px;
|
||||
transition: background-color 0.3s;
|
||||
|
||||
&--active {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
.indicator_img{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.indicator-num {
|
||||
padding: 2px 0;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
border-radius: 100px;
|
||||
width: 35px;
|
||||
@include flex;
|
||||
justify-content: center;
|
||||
|
||||
&__text {
|
||||
color: #FFFFFF;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,210 +0,0 @@
|
||||
<template>
|
||||
<view class="nav">
|
||||
<view class="nav-left">
|
||||
<scroll-view scroll-y>
|
||||
<view class="nav-left-item" v-for="(item, index) in categoryList"
|
||||
@click="categoryClickMain(item, index)" :key="index"
|
||||
:style="index == categoryActive ? 'color:' + activeTextColor + ';background-color:' + activeBackgroundColor : ''">
|
||||
{{ item[label] }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="nav-right" v-if="!subCategoryList.length == 0">
|
||||
<scroll-view scroll-y :scroll-top="scrollTop" @scroll="scroll" @scrolltolower="loadMore"
|
||||
scroll-with-animation>
|
||||
<view class="nav-right-item" v-for="(item, index2) in subCategoryList" :key="index2"
|
||||
@click="categoryClickSub(item)">
|
||||
<view>{{ item[label] }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'category',
|
||||
data() {
|
||||
return {
|
||||
h: null,
|
||||
namelang: '',
|
||||
keyword: '请输入相关行业',
|
||||
height: 0,
|
||||
scrollTop: 0,
|
||||
scrollHeight: 0,
|
||||
categoryActive: 0,
|
||||
activeStyle: {
|
||||
color: this.activeTextColor,
|
||||
backgroundColor: this.activeBackgroundColor
|
||||
}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
//主分类激活索引
|
||||
merchant: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
defaultActive: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
//主分类List
|
||||
categoryList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
//侧边分类List
|
||||
subCategoryList: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
activeTextColor: {
|
||||
type: String,
|
||||
default: '#FF981E'
|
||||
},
|
||||
activeBackgroundColor: {
|
||||
type: String,
|
||||
default: 'rgba(0,0,0,0)'
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: 'name'
|
||||
},
|
||||
imgSrc: {
|
||||
type: String,
|
||||
default: 'logo'
|
||||
},
|
||||
//主分类点击事件
|
||||
categoryMainClick: {},
|
||||
//子分类点击事件
|
||||
categorySubClick: {}
|
||||
},
|
||||
methods: {
|
||||
async computed_h() {
|
||||
//获取div宽度
|
||||
let content_Icon = await uni.utils.info_distance('Box_top');
|
||||
let content_top_box = await uni.utils.info_distance('Box_text');
|
||||
let system_info = await uni.getSystemInfo();
|
||||
var h_ = system_info.windowHeight + 'px';
|
||||
this.h = {
|
||||
height: h_
|
||||
};
|
||||
},
|
||||
scroll(e) {
|
||||
this.scrollHeight = e.detail.scrollHeight;
|
||||
},
|
||||
categoryClickMain(category, index) {
|
||||
this.namelang = category.name
|
||||
this.$emit('categoryMainClick', {
|
||||
'category': category,
|
||||
'index': index
|
||||
});
|
||||
this.categoryActive = index;
|
||||
this.scrollTop = -this.scrollHeight * index;
|
||||
},
|
||||
loadMore(e) {
|
||||
console.log(e)
|
||||
this.$emit('loadMores');
|
||||
},
|
||||
categoryClickSub(category) {
|
||||
this.$emit('categorySubClick', category);
|
||||
},
|
||||
searchkeyword() {
|
||||
this.$emit('searchkeyword', this.keyword)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.categoryActive = this.defaultActive;
|
||||
this.computed_h();
|
||||
// uni.getSystemInfo({
|
||||
// success: res => {
|
||||
// console.log(res);
|
||||
// this.height = res.windowHeight;
|
||||
// }
|
||||
// });
|
||||
},
|
||||
watch: {
|
||||
subCategoryList(newValue, oldValue) {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.Box_top {
|
||||
padding: 32rpx 28rpx;
|
||||
}
|
||||
|
||||
.Box_text {
|
||||
background: #f1f0f5;
|
||||
padding: 10rpx 28rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: Source Han Sans CN-Regular, Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.Box_texttext {
|
||||
margin-left: 16rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: Source Han Sans CN-Medium, Source Han Sans CN;
|
||||
font-weight: 500;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
max-height: 600rpx;
|
||||
width: 30%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.nav-left-item {
|
||||
padding: 10rpx 0;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.nav-right {
|
||||
width: 70%;
|
||||
max-height: 600rpx;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.nav-right-item {
|
||||
width: 100%;
|
||||
border-left: solid 1px #e0e0e0;
|
||||
/* height: 100px; */
|
||||
text-align: left;
|
||||
padding: 24rpx 32rpx;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.nav-right-item image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #f24544;
|
||||
}
|
||||
|
||||
.padding {
|
||||
height: var(--status-bar-height);
|
||||
width: 100%;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
background-color: #f24544;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,11 @@
|
||||
<template xlang="wxml" minapp="mpvue">
|
||||
<view class="tki-barcode">
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<canvas class="tki-barcode-canvas 1" :canvas-id="cid"
|
||||
<canvas class="tki-barcode-canvas" :canvas-id="cid"
|
||||
:style="{width:canvasWidth+'px',height:canvasHeight+'px'}" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<canvas :id="cid" :width="canvasWidth" :height="canvasHeight" class="tki-barcode-canvas 2" />
|
||||
<canvas :id="cid" :width="canvasWidth" :height="canvasHeight" class="tki-barcode-canvas" />
|
||||
<!-- #endif -->
|
||||
<image v-show="show" :src="result" :style="{width:canvasWidth+'px',height:canvasHeight+'px'}" />
|
||||
</view>
|
||||
@@ -167,7 +167,6 @@
|
||||
watch: {
|
||||
val(n, o) {
|
||||
if (this.onval) {
|
||||
console.log(!this._empty(n))
|
||||
if (n != o && !this._empty(n)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,219 +0,0 @@
|
||||
<template xlang="wxml" minapp="mpvue">
|
||||
<view class="tki-qrcode">
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<canvas class="tki-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<canvas :id="cid" :width="cpSize" :height="cpSize" class="tki-qrcode-canvas" />
|
||||
<!-- #endif -->
|
||||
<image v-show="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QRCode from "./qrcode.js"
|
||||
let qrcode
|
||||
export default {
|
||||
name: "tki-qrcode",
|
||||
props: {
|
||||
cid: {
|
||||
type: String,
|
||||
default: 'tki-qrcode-canvas'
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
unit: {
|
||||
type: String,
|
||||
default: 'upx'
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
val: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
default: '#ffffff'
|
||||
},
|
||||
foreground: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
pdground: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconSize: {
|
||||
type: Number,
|
||||
default: 40
|
||||
},
|
||||
lv: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
onval: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loadMake: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
usingComponents: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showLoading: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
loadingText: {
|
||||
type: String,
|
||||
default: '二维码生成中'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setval(n) {
|
||||
console.log("setval==",n)
|
||||
this.val = n
|
||||
if (!this._empty(n)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
_makeCode() {
|
||||
let that = this
|
||||
if (!this._empty(this.val)) {
|
||||
qrcode = new QRCode({
|
||||
context: that, // 上下文环境
|
||||
canvasId:that.cid, // canvas-id
|
||||
usingComponents: that.usingComponents, // 是否是自定义组件
|
||||
showLoading: that.showLoading, // 是否显示loading
|
||||
loadingText: that.loadingText, // loading文字
|
||||
text: that.val, // 生成内容
|
||||
size: that.cpSize, // 二维码大小
|
||||
background: that.background, // 背景色
|
||||
foreground: that.foreground, // 前景色
|
||||
pdground: that.pdground, // 定位角点颜色
|
||||
correctLevel: that.lv, // 容错级别
|
||||
image: that.icon, // 二维码图标
|
||||
imageSize: that.iconSize,// 二维码图标大小
|
||||
cbResult: function (res) { // 生成二维码的回调
|
||||
that._result(res)
|
||||
},
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '二维码内容不能为空',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
_clearCode() {
|
||||
this._result('')
|
||||
qrcode.clear()
|
||||
},
|
||||
_saveCode() {
|
||||
let that = this;
|
||||
if (this.result != "") {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: that.result,
|
||||
success: function () {
|
||||
uni.showToast({
|
||||
title: '二维码保存成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
_result(res) {
|
||||
this.result = res;
|
||||
this.$emit('result', res)
|
||||
},
|
||||
_empty(v) {
|
||||
let tp = typeof v,
|
||||
rt = false;
|
||||
if (tp == "number" && String(v) == "") {
|
||||
rt = true
|
||||
} else if (tp == "undefined") {
|
||||
rt = true
|
||||
} else if (tp == "object") {
|
||||
if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
|
||||
} else if (tp == "string") {
|
||||
if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
|
||||
} else if (tp == "function") {
|
||||
rt = false
|
||||
}
|
||||
return rt
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
size: function (n, o) {
|
||||
if (n != o && !this._empty(n)) {
|
||||
this.cSize = n
|
||||
if (!this._empty(this.val)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
},
|
||||
val: function (n, o) {
|
||||
if (this.onval) {
|
||||
if (n != o && !this._empty(n)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cpSize() {
|
||||
if(this.unit == "upx"){
|
||||
return uni.upx2px(this.size)
|
||||
}else{
|
||||
return this.size
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
if (this.loadMake) {
|
||||
if (!this._empty(this.val)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.tki-qrcode {
|
||||
position: relative;
|
||||
}
|
||||
.tki-qrcode-canvas {
|
||||
position: fixed;
|
||||
top: -99999upx;
|
||||
left: -99999upx;
|
||||
z-index: -99999;
|
||||
}
|
||||
</style>
|
||||
@@ -1,86 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="scroll_box">
|
||||
<swiper class="swiper" circular="true" vertical="true" display-multiple-items="4" :autoplay="autoplay"
|
||||
:interval="interval" :duration="duration">
|
||||
<swiper-item v-for="(item,index) in list" :key="index">
|
||||
<view class="swiper-item">
|
||||
<view class="line1">{{item.nickName}}</view>
|
||||
<view class="line2">
|
||||
<text>抽到</text>
|
||||
<text class="line2-amount">{{item.value}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: '',
|
||||
props: {
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
interval: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
datalist: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
datalist: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
this.list = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.scroll_box {
|
||||
background: #FFFFFF;
|
||||
border-radius: 10rpx;
|
||||
|
||||
.swiper {
|
||||
height: 400rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper-item::after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.swiper-item {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.swiper-item .line1 {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.swiper-item .line2 {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.swiper-item .line2 .line2-amount {
|
||||
color: #EF4A4A;
|
||||
}
|
||||
</style>
|
||||
@@ -1,37 +1,22 @@
|
||||
const debug = process.env.NODE_ENV == 'development' ? true : false;
|
||||
const debug = true;
|
||||
// #ifdef H5
|
||||
const proxyApi = "/api"
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || APP || MP-ALIPAY
|
||||
// const proxyApi = 'http://192.168.1.15:9888/cashierService' // 王伟
|
||||
// const proxyApi = 'http://192.168.1.27:9888/cashierService' // 帆哥
|
||||
// const proxyApiwws = 'ws://192.168.1.15:9888/netty' // 测试
|
||||
const proxyApi = 'https://wxcashiertest.sxczgkj.cn/cashierService' // 测试
|
||||
const proxyApiwws = 'wss://wxcashiertest.sxczgkj.cn/netty' // 测试
|
||||
// const proxyApi = 'https://pre-cashier.sxczgkj.cn/cashierService' // 预发布
|
||||
// const proxyApiwws = 'wss://pre-cashier.sxczgkj.cn/netty' // 预发布
|
||||
// const proxyApi = 'https://cashier.sxczgkj.cn/cashierService' // 线上
|
||||
// const proxyApiwws = 'wss://cashier.sxczgkj.cn/netty' // 线上
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY
|
||||
const baseUrl = 'https://cashier.sxczgkj.cn/cashierService' // 线上
|
||||
const baseUrlwws = 'wss://cashier.sxczgkj.cn/cashierService' // 线上
|
||||
// const baseUrl = "https://wxcashiertest.sxczgkj.cn/cashierService" //测试
|
||||
// const baseUrlwws = 'wss://wxcashiertest.sxczgkj.cn/cashierService' // 测试
|
||||
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
const baseUrl = debug ? proxyApi + '/cashierService' : "https://cashier.sxczgkj.cn/cashierService"
|
||||
const baseUrlwws = 'ws://cashier.sxczgkj.cn/cashierService'
|
||||
const baseUrl = debug ? proxyApi : 'http://192.168.2.161:9889/cashierService/' // 线上
|
||||
// #endif
|
||||
|
||||
// #ifdef APP || MP-WEIXIN || MP-ALIPAY
|
||||
const baseUrl = debug ? proxyApi : 'https://cashier.sxczgkj.cn/cashierService' // 线上
|
||||
const baseUrlwws = debug ? proxyApiwws : 'wss://cashier.sxczgkj.cn/netty' // 线上
|
||||
|
||||
// const baseUrl = 'https://wxcashiertest.sxczgkj.cn/cashierService' // 测试
|
||||
// const baseUrlwws = 'wss://wxcashiertest.sxczgkj.cn/netty' // 测试
|
||||
// #endif
|
||||
|
||||
// import VConsole from "./vConsole.js"
|
||||
// if (debug) {
|
||||
// new VConsole()
|
||||
// // new VConsole()
|
||||
// }
|
||||
const version = '100'
|
||||
const version = '109'
|
||||
const autoRemoveCache = {
|
||||
count: 100000,
|
||||
size: 100000
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import md5 from './md5'
|
||||
import Api from "@/common/js/api.js"
|
||||
|
||||
/**
|
||||
* 转换对象为x-www-form-urlencoded
|
||||
@@ -11,26 +10,26 @@ let transformRequest = obj => {
|
||||
let query = ''
|
||||
let name, value, fullSubName, subName, subValue, innerObj, i
|
||||
|
||||
for (name in obj) {
|
||||
for(name in obj) {
|
||||
value = obj[name]
|
||||
|
||||
if (value instanceof Array) {
|
||||
for (i = 0; i < value.length; ++i) {
|
||||
if(value instanceof Array) {
|
||||
for(i = 0; i < value.length; ++i) {
|
||||
subValue = value[i]
|
||||
fullSubName = name + '[' + i + ']'
|
||||
innerObj = {}
|
||||
innerObj[fullSubName] = subValue
|
||||
query += transformRequest(innerObj) + '&'
|
||||
}
|
||||
} else if (value instanceof Object) {
|
||||
for (subName in value) {
|
||||
} else if(value instanceof Object) {
|
||||
for(subName in value) {
|
||||
subValue = value[subName]
|
||||
fullSubName = name + '[' + subName + ']'
|
||||
innerObj = {}
|
||||
innerObj[fullSubName] = subValue
|
||||
query += transformRequest(innerObj) + '&'
|
||||
}
|
||||
} else if (value !== undefined && value !== null) {
|
||||
} else if(value !== undefined && value !== null) {
|
||||
query += encodeURIComponent(name) + '=' +
|
||||
encodeURIComponent(value) + '&'
|
||||
}
|
||||
@@ -45,7 +44,7 @@ let timestamp = function() {
|
||||
|
||||
let isNavigating = false
|
||||
let isNavigate = () => {
|
||||
if (isNavigating) {
|
||||
if(isNavigating) {
|
||||
return true
|
||||
} else {
|
||||
isNavigating = true
|
||||
@@ -63,11 +62,11 @@ let guid = (function() {
|
||||
let guid = new Date().getTime().toString(32),
|
||||
i
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
for(i = 0; i < 5; i++) {
|
||||
guid += Math.floor(Math.random() * 65535).toString(32)
|
||||
}
|
||||
|
||||
return (prefix || '') + guid + (counter++).toString(32)
|
||||
return(prefix || '') + guid + (counter++).toString(32)
|
||||
}
|
||||
}())
|
||||
|
||||
@@ -76,7 +75,7 @@ let sortTransform = (obj) => {
|
||||
objKeys = objKeys.sort()
|
||||
|
||||
var ret = {}
|
||||
for (var i = 0; i < objKeys.length; i++) {
|
||||
for(var i = 0; i < objKeys.length; i++) {
|
||||
let objVal = obj[objKeys[i]]
|
||||
ret[objKeys[i]] = objVal
|
||||
}
|
||||
@@ -96,8 +95,8 @@ function isEmptyObject(v) {
|
||||
return Object.keys(v).length == 0
|
||||
}
|
||||
|
||||
function sleep(time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time))
|
||||
function sleep (time) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time))
|
||||
}
|
||||
|
||||
const throttle = function(func, wait = 200, options) {
|
||||
@@ -111,7 +110,7 @@ const throttle = function(func, wait = 200, options) {
|
||||
var context, args, result
|
||||
var timeout = null
|
||||
var previous = 0
|
||||
if (!options) options = {
|
||||
if(!options) options = {
|
||||
leading: true,
|
||||
trailing: false
|
||||
}
|
||||
@@ -119,26 +118,26 @@ const throttle = function(func, wait = 200, options) {
|
||||
previous = options.leading === false ? 0 : new Date().getTime()
|
||||
timeout = null
|
||||
result = func.apply(context, args)
|
||||
if (!timeout) context = args = null
|
||||
if(!timeout) context = args = null
|
||||
}
|
||||
return function() {
|
||||
var now = new Date().getTime()
|
||||
if (!previous && options.leading === false) previous = now
|
||||
if(!previous && options.leading === false) previous = now
|
||||
// 计算剩余时间
|
||||
var remaining = wait - (now - previous)
|
||||
context = this
|
||||
args = arguments
|
||||
// 当到达wait指定的时间间隔,则调用func函数
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if(remaining <= 0 || remaining > wait) {
|
||||
// 由于setTimeout存在最小时间精度问题,因此会存在到达wait的时间间隔,但之前设置的setTimeout操作还没被执行,因此为保险起见,这里先清理setTimeout操作
|
||||
if (timeout) {
|
||||
if(timeout) {
|
||||
clearTimeout(timeout)
|
||||
timeout = null
|
||||
}
|
||||
previous = now
|
||||
result = func.apply(context, args)
|
||||
if (!timeout) context = args = null
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
if(!timeout) context = args = null
|
||||
} else if(!timeout && options.trailing !== false) {
|
||||
// options.trailing=true时,延时执行func函数
|
||||
timeout = setTimeout(later, remaining)
|
||||
}
|
||||
@@ -154,13 +153,13 @@ const debounce = function(func, wait, immediate) {
|
||||
// 当wait指定的时间间隔期间多次调用_.debounce返回的函数,则会不断更新timestamp的值,导致last < wait && last >= 0一直为true,从而不断启动新的计时器延时执行func
|
||||
var last = new Date().getTime() - timestamp
|
||||
|
||||
if (last < wait && last >= 0) {
|
||||
if(last < wait && last >= 0) {
|
||||
timeout = setTimeout(later, wait - last)
|
||||
} else {
|
||||
timeout = null
|
||||
if (!immediate) {
|
||||
if(!immediate) {
|
||||
result = func.apply(context, args)
|
||||
if (!timeout) context = args = null
|
||||
if(!timeout) context = args = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,8 +171,8 @@ const debounce = function(func, wait, immediate) {
|
||||
// 第一次调用该方法时,且immediate为true,则调用func函数
|
||||
var callNow = immediate && !timeout
|
||||
// 在wait指定的时间间隔内首次调用该方法,则启动计时器定时调用func函数
|
||||
if (!timeout) timeout = setTimeout(later, wait)
|
||||
if (callNow) {
|
||||
if(!timeout) timeout = setTimeout(later, wait)
|
||||
if(callNow) {
|
||||
result = func.apply(context, args)
|
||||
context = args = null
|
||||
}
|
||||
@@ -182,14 +181,12 @@ const debounce = function(func, wait, immediate) {
|
||||
}
|
||||
}
|
||||
|
||||
Promise.prototype.finally = function(callback) {
|
||||
let P = this.constructor
|
||||
return this.then(
|
||||
value => P.resolve(callback()).then(() => value),
|
||||
reason => P.resolve(callback()).then(() => {
|
||||
throw reason
|
||||
})
|
||||
)
|
||||
Promise.prototype.finally = function (callback) {
|
||||
let P = this.constructor
|
||||
return this.then(
|
||||
value => P.resolve(callback()).then(() => value),
|
||||
reason => P.resolve(callback()).then(() => { throw reason })
|
||||
)
|
||||
}
|
||||
const info_distance = function(e) { //获取元素位置
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -207,97 +204,6 @@ const getCurrentRoute = function() {
|
||||
return '/' + getCurrentPage().route
|
||||
}
|
||||
|
||||
const pluschooseImage = function() {
|
||||
// #ifdef APP
|
||||
if (plus.os.name == 'Android' && plus.navigator.checkPermission('android.permission.CAMERA') ===
|
||||
'undetermined') {
|
||||
//未授权
|
||||
uni.showModal({
|
||||
title: '权限说明',
|
||||
content: '便于您使用该功能上传您的照片/图片等,请您确认授权相机与相册,否则无法使用该功能',
|
||||
confirmText: "去设置",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openAppAuthorizeSetting({
|
||||
success(res) {
|
||||
console.log(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY
|
||||
return true
|
||||
// #endif
|
||||
}
|
||||
|
||||
const getUserInfo = function (successCallback, failCallback) {
|
||||
// #ifdef MP-WEIXIN
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: (data) => {
|
||||
console.log(data)
|
||||
// 微信小程序环境
|
||||
uni.getUserInfo({
|
||||
provider: 'weixin',
|
||||
success: async (infoRes) => {
|
||||
let res = await Api.userwxlogin({
|
||||
code: data.code, //临时登录凭证
|
||||
rawData: infoRes.rawData,
|
||||
source: 'wechat'
|
||||
})
|
||||
if (res.code == 0) {
|
||||
resolve(res)
|
||||
}
|
||||
},
|
||||
fail: (err) => {}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
return new Promise((resolve, reject) => {
|
||||
my.getAuthCode({
|
||||
scopes: 'auth_base',
|
||||
success: async (data) => {
|
||||
console.log(data)
|
||||
// 支付宝小程序环境
|
||||
// my.getAuthUserInfo({
|
||||
// success: async (infoRes) => {
|
||||
let res = await Api.userwxlogin({
|
||||
code: data.authCode, //临时登录凭证
|
||||
// rawData: JSON.stringify(infoRes),
|
||||
source: 'alipay'
|
||||
})
|
||||
if (res.code == 0) {
|
||||
resolve(res)
|
||||
}
|
||||
// },
|
||||
// fail: (err) => {}
|
||||
// });
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// #endif
|
||||
}
|
||||
|
||||
const payment = function () {
|
||||
|
||||
}
|
||||
|
||||
uni.utils = {
|
||||
md5,
|
||||
transformRequest,
|
||||
@@ -313,8 +219,5 @@ uni.utils = {
|
||||
throttle,
|
||||
debounce,
|
||||
getCurrentPage,
|
||||
getCurrentRoute,
|
||||
pluschooseImage,
|
||||
getUserInfo,
|
||||
payment
|
||||
}
|
||||
getCurrentRoute
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
fill
|
||||
} from "lodash"
|
||||
import store from "../store"
|
||||
|
||||
const preCacheKeyClearFetch = 'storage:clear:fetch:'
|
||||
|
||||
uni.pro.interceptor('request', {
|
||||
@@ -44,22 +44,9 @@ function requestrequest(options) {
|
||||
}
|
||||
|
||||
async function request(options) {
|
||||
let networkType = ''
|
||||
uni.getNetworkType({
|
||||
success: (res) => {
|
||||
networkType = res.networkType
|
||||
}
|
||||
});
|
||||
if (networkType == 'none') {
|
||||
uni.showToast({
|
||||
title: '网络异常,请检查网络',
|
||||
icon: 'none'
|
||||
})
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (options.toast) {
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY || APP-PLUS
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY
|
||||
uni.showLoading({
|
||||
title: '加载中',
|
||||
mask: true
|
||||
@@ -74,31 +61,14 @@ async function request(options) {
|
||||
}
|
||||
if (options.type == 1) {
|
||||
options.header = {
|
||||
version: uni.conf.version,
|
||||
type: uni.getSystemInfoSync().platform,
|
||||
// #ifdef APP-PLUS
|
||||
environment: 'app',
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
environment: 'h5',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
environment: 'wx',
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
environment: 'alipay',
|
||||
// environment: 'alipay',
|
||||
// #endif
|
||||
token: uni.cache.get('token'),
|
||||
openId: uni.cache.get('miniAppOpenId'),
|
||||
openId: uni.cache.get('userInfo').miniAppOpenId,
|
||||
id: uni.cache.get('userInfo').id,
|
||||
loginName: "",
|
||||
clientType: ''
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY || APP-PLUS
|
||||
// #ifdef MP-WEIXIN || MP-ALIPAY
|
||||
options.url = uni.conf.baseUrl + options.url
|
||||
let res = await requestrequest(options);
|
||||
// #endif
|
||||
@@ -106,39 +76,41 @@ async function request(options) {
|
||||
let res = await uni.pro.request(options);
|
||||
// #endif
|
||||
if (res.code != 0) {
|
||||
if (res.code == -4) {
|
||||
// uni.showToast({
|
||||
// title: res.message || res.msg,
|
||||
// icon: "none",
|
||||
// success: () => {
|
||||
// // setTimeout(res => {
|
||||
// // store.dispatch("loginEvent"); //获取shapid
|
||||
// // }, 1000)
|
||||
// }
|
||||
// })
|
||||
|
||||
uni.$u.throttle(store.dispatch("loginEvent"), 1000); //获取shapid
|
||||
|
||||
if (res.code == 401) {
|
||||
uni.showToast({
|
||||
title: res.message || res.msg,
|
||||
icon: "none",
|
||||
success: () => {
|
||||
uni.cache.clear();
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/login'
|
||||
});
|
||||
}
|
||||
})
|
||||
} else if (res.code == 482) {
|
||||
let nowTime = new Date() / 1000 | 0
|
||||
let offset = parseInt(res.data.message) - parseInt(nowTime);
|
||||
uni.cache.set('storage:offset-time', offset, -1)
|
||||
return await request(options)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.message || res.msg || res.error,
|
||||
icon: "none",
|
||||
success: () => {
|
||||
setTimeout(res => {
|
||||
if (options.toast) {
|
||||
// #ifndef MP-WEIXIN || MP-ALIPAY
|
||||
uni.pro.hideLoading()
|
||||
// #endif
|
||||
}
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
return res
|
||||
if (options.toast) {
|
||||
uni.showToast({
|
||||
title: res.message || res.msg || res.error,
|
||||
icon: "none",
|
||||
success: () => {
|
||||
setTimeout(res => {
|
||||
if (options.toast) {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.hideLoading()
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.pro.hideLoading()
|
||||
// #endif
|
||||
}
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
|
||||
@@ -13,11 +13,9 @@ uni.pro.uploadFile = (obj) => {
|
||||
|
||||
uni.pro.navigateTo = (pageName, extras = {}) => {
|
||||
let url = uni.url.getUrl(pageName, extras)
|
||||
return uni.navigateTo({
|
||||
url
|
||||
})
|
||||
|
||||
|
||||
return uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
uni.pro.redirectTo = (pageName, extras = {}) => {
|
||||
let url = uni.url.getUrl(pageName, extras)
|
||||
|
||||
@@ -11,14 +11,14 @@ function get(key) {
|
||||
if (!res) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// res = JSON.parse(res)
|
||||
|
||||
if (res.expire > 0 && res.expire < uni.utils.timestamp()) {
|
||||
console.log(res)
|
||||
|
||||
if (res.__expiretime && res.__expiretime < uni.utils.timestamp()) {
|
||||
remove(key)
|
||||
return ''
|
||||
} else {
|
||||
return res.data
|
||||
return res
|
||||
}
|
||||
} catch (e) {
|
||||
return ''
|
||||
@@ -56,13 +56,15 @@ function getStorageData(key) {
|
||||
* @param {Number} expire 指定秒数后过期
|
||||
* @return void
|
||||
*/
|
||||
function set(key, value, expire = 0) {
|
||||
let obj = {
|
||||
data: value, //存储的数据
|
||||
time: Date.now() / 1000, //记录存储的时间戳
|
||||
expire: expire //记录过期时间,单位秒
|
||||
function set(key, value, expire = uni.conf.default_expire) {
|
||||
let cacheItem = {}
|
||||
cacheItem = value
|
||||
// console.log(cacheItem)
|
||||
if (expire > 0) {
|
||||
cacheItem.__expiretime = uni.utils.timestamp() + expire
|
||||
}
|
||||
uni.setStorageSync(key, obj)
|
||||
// uni.setStorageSync(key,JSON.stringify(cacheItem))
|
||||
uni.setStorageSync(key,cacheItem)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
9
main.js
9
main.js
@@ -3,15 +3,13 @@ import uView from '@/uni_modules/uview-ui'
|
||||
import useStorage from '@/utils/useStroage.js'
|
||||
import './framework/bootstrap'
|
||||
import Api from "./common/js/api.js"
|
||||
import store from './store'
|
||||
import Shop from "./common/js/shop.js"
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
store,
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
@@ -21,10 +19,7 @@ Vue.use(uView)
|
||||
uni.$u.config.unit = 'rpx'
|
||||
Vue.prototype.useStorage = useStorage
|
||||
Vue.prototype.api = Api;
|
||||
Vue.prototype.$onLaunched = new Promise(resolve => {
|
||||
Vue.prototype.$isResolve = resolve
|
||||
})
|
||||
|
||||
Vue.prototype.shop = Shop;
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
|
||||
214
manifest.json
214
manifest.json
@@ -1,118 +1,98 @@
|
||||
{
|
||||
"name" : "cashier_weapp",
|
||||
"appid" : "__UNI__8092421",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {
|
||||
"Barcode" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {
|
||||
"dSYMs" : false
|
||||
},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {
|
||||
"ad" : {}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wxd88fffa983758a30",
|
||||
"setting" : {
|
||||
"urlCheck" : false,
|
||||
"minified" : true,
|
||||
"es6" : true,
|
||||
"postcss" : true
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"libVersion" : "latest",
|
||||
"permission" : {
|
||||
"scope.userLocation" : {
|
||||
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
|
||||
}
|
||||
},
|
||||
"requiredPrivateInfos" : [ "getLocation", "onLocationChange", "chooseLocation", "chooseAddress" ]
|
||||
},
|
||||
"h5" : {
|
||||
"devServer" : {
|
||||
"https" : false,
|
||||
"disableHostCheck" : false,
|
||||
"proxy" : {
|
||||
"/api" : {
|
||||
"target" : "https://wxcashiertest.sxczgkj.cn",
|
||||
// "target" : "https://ky.sxczgkj.cn",
|
||||
"ws" : false,
|
||||
"changeOrigin" : true, //是否跨域
|
||||
"secure" : false, // 设置支持https协议的代理
|
||||
"pathRewrite" : {
|
||||
"^/api" : "" //需要rewrite重写的,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"template" : "template.h5.html",
|
||||
"router" : {
|
||||
"mode" : "history",
|
||||
"base" : "/h5/"
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true,
|
||||
"appid" : "2021004145625815",
|
||||
"devServer" : {
|
||||
"autoOpen" : true // 设置为true自动打开支付宝小程序
|
||||
},
|
||||
"unipush" : {
|
||||
"enable" : false
|
||||
}
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "2"
|
||||
}
|
||||
"name": "cashier_weapp",
|
||||
"appid": "__UNI__8092421",
|
||||
"description": "",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"splashscreen": {
|
||||
"alwaysShowBeforeRender": true,
|
||||
"waiting": true,
|
||||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules": {
|
||||
"Barcode": {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute": {
|
||||
/* android打包配置 */
|
||||
"android": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios": {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs": {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp": {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin": {
|
||||
"appid": "wxd88fffa983758a30",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true,
|
||||
"libVersion": "latest"
|
||||
},
|
||||
"h5": {
|
||||
"devServer": {
|
||||
"https": false,
|
||||
"disableHostCheck": false,
|
||||
"proxy": {
|
||||
"/api": {
|
||||
"target": "https://p40312246f.goho.co/cashierService/",
|
||||
// "target" : "https://ky.sxczgkj.cn",
|
||||
"ws": false,
|
||||
"changeOrigin": true, //是否跨域
|
||||
"secure": false, // 设置支持https协议的代理
|
||||
"pathRewrite": {
|
||||
"^/api": "" //需要rewrite重写的,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"template": "template.h5.html",
|
||||
"router": {
|
||||
"mode": "history",
|
||||
"base": "/h5/"
|
||||
}
|
||||
},
|
||||
"mp-alipay": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-baidu": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion": "2"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"format": 2
|
||||
}
|
||||
17
node_modules/.bin/sass
generated
vendored
Normal file
17
node_modules/.bin/sass
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -z "$NODE_PATH" ]; then
|
||||
export NODE_PATH="$basedir/C:/Users/Administrator/Documents/HBuilderProjects/cashier_weapp/node_modules/.store/sass@1.69.5/node_modules"
|
||||
else
|
||||
export NODE_PATH="$NODE_PATH:$basedir/C:/Users/Administrator/Documents/HBuilderProjects/cashier_weapp/node_modules/.store/sass@1.69.5/node_modules"
|
||||
fi
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" "$@"
|
||||
fi
|
||||
12
node_modules/.bin/sass.CMD
generated
vendored
Normal file
12
node_modules/.bin/sass.CMD
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
@SETLOCAL
|
||||
@IF NOT DEFINED NODE_PATH (
|
||||
@SET "NODE_PATH=%~dp0\C:\Users\Administrator\Documents\HBuilderProjects\cashier_weapp\node_modules\.store\sass@1.69.5\node_modules"
|
||||
) ELSE (
|
||||
@SET "NODE_PATH=%NODE_PATH%;%~dp0\C:\Users\Administrator\Documents\HBuilderProjects\cashier_weapp\node_modules\.store\sass@1.69.5\node_modules"
|
||||
)
|
||||
@IF EXIST "%~dp0\node.exe" (
|
||||
"%~dp0\node.exe" "%~dp0\..\.store\sass@1.69.5\node_modules\sass\sass.js" %*
|
||||
) ELSE (
|
||||
@SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
node "%~dp0\..\.store\sass@1.69.5\node_modules\sass\sass.js" %*
|
||||
)
|
||||
41
node_modules/.bin/sass.ps1
generated
vendored
Normal file
41
node_modules/.bin/sass.ps1
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
$pathsep=":"
|
||||
$env_node_path=$env:NODE_PATH
|
||||
$new_node_path="$basedir\C:\Users\Administrator\Documents\HBuilderProjects\cashier_weapp\node_modules\.store\sass@1.69.5\node_modules"
|
||||
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"
|
||||
$pathsep=";"
|
||||
} else {
|
||||
$new_node_path="$basedir/C:/Users/Administrator/Documents/HBuilderProjects/cashier_weapp/node_modules/.store/sass@1.69.5/node_modules"
|
||||
}
|
||||
if ([string]::IsNullOrEmpty($env_node_path)) {
|
||||
$env:NODE_PATH=$new_node_path
|
||||
} else {
|
||||
$env:NODE_PATH="$env_node_path$pathsep$new_node_path"
|
||||
}
|
||||
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../.store/sass@1.69.5/node_modules/sass/sass.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
$env:NODE_PATH=$env_node_path
|
||||
exit $ret
|
||||
15
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/LICENSE
generated
vendored
Normal file
15
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com)
|
||||
|
||||
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.
|
||||
87
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/README.md
generated
vendored
Normal file
87
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
anymatch [](https://travis-ci.org/micromatch/anymatch) [](https://coveralls.io/r/micromatch/anymatch?branch=master)
|
||||
======
|
||||
Javascript module to match a string against a regular expression, glob, string,
|
||||
or function that takes the string as an argument and returns a truthy or falsy
|
||||
value. The matcher can also be an array of any or all of these. Useful for
|
||||
allowing a very flexible user-defined config to define things like file paths.
|
||||
|
||||
__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
```sh
|
||||
npm install anymatch
|
||||
```
|
||||
|
||||
#### anymatch(matchers, testString, [returnIndex], [options])
|
||||
* __matchers__: (_Array|String|RegExp|Function_)
|
||||
String to be directly matched, string with glob patterns, regular expression
|
||||
test, function that takes the testString as an argument and returns a truthy
|
||||
value if it should be matched, or an array of any number and mix of these types.
|
||||
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||
passed as an array, the first element of the array will be used as the
|
||||
`testString` for non-function matchers, while the entire array will be applied
|
||||
as the arguments for function matchers.
|
||||
* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options.
|
||||
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||
boolean result.
|
||||
|
||||
```js
|
||||
const anymatch = require('anymatch');
|
||||
|
||||
const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ;
|
||||
|
||||
anymatch(matchers, 'path/to/file.js'); // true
|
||||
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||
anymatch(matchers, 'path/to/foo.js'); // true
|
||||
anymatch(matchers, 'path/to/bar.js'); // true
|
||||
anymatch(matchers, 'bar.js'); // false
|
||||
|
||||
// returnIndex = true
|
||||
anymatch(matchers, 'foo.js', {returnIndex: true}); // 2
|
||||
anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1
|
||||
|
||||
// any picomatc
|
||||
|
||||
// using globs to match directories and their children
|
||||
anymatch('node_modules', 'node_modules'); // true
|
||||
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
|
||||
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
|
||||
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
|
||||
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
|
||||
|
||||
const matcher = anymatch(matchers);
|
||||
['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ]
|
||||
anymatch master* ❯
|
||||
|
||||
```
|
||||
|
||||
#### anymatch(matchers)
|
||||
You can also pass in only your matcher(s) to get a curried function that has
|
||||
already been bound to the provided matching criteria. This can be used as an
|
||||
`Array#filter` callback.
|
||||
|
||||
```js
|
||||
var matcher = anymatch(matchers);
|
||||
|
||||
matcher('path/to/file.js'); // true
|
||||
matcher('path/anyjs/baz.js', true); // 1
|
||||
|
||||
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||
```
|
||||
|
||||
Changelog
|
||||
----------
|
||||
[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases)
|
||||
|
||||
- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only.
|
||||
- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information).
|
||||
- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||
for glob pattern matching. Issues with glob pattern matching should be
|
||||
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||
|
||||
License
|
||||
-------
|
||||
[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE)
|
||||
20
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
20
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
type AnymatchFn = (testString: string) => boolean;
|
||||
type AnymatchPattern = string|RegExp|AnymatchFn;
|
||||
type AnymatchMatcher = AnymatchPattern|AnymatchPattern[]
|
||||
type AnymatchTester = {
|
||||
(testString: string|any[], returnIndex: true): number;
|
||||
(testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
type PicomatchOptions = {dot: boolean};
|
||||
|
||||
declare const anymatch: {
|
||||
(matchers: AnymatchMatcher): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number;
|
||||
(matchers: AnymatchMatcher, testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
export {AnymatchMatcher as Matcher}
|
||||
export {AnymatchTester as Tester}
|
||||
export default anymatch
|
||||
104
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/index.js
generated
vendored
Normal file
104
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const picomatch = require('picomatch');
|
||||
const normalizePath = require('normalize-path');
|
||||
|
||||
/**
|
||||
* @typedef {(testString: string) => boolean} AnymatchFn
|
||||
* @typedef {string|RegExp|AnymatchFn} AnymatchPattern
|
||||
* @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
|
||||
*/
|
||||
const BANG = '!';
|
||||
const DEFAULT_OPTIONS = {returnIndex: false};
|
||||
const arrify = (item) => Array.isArray(item) ? item : [item];
|
||||
|
||||
/**
|
||||
* @param {AnymatchPattern} matcher
|
||||
* @param {object} options
|
||||
* @returns {AnymatchFn}
|
||||
*/
|
||||
const createPattern = (matcher, options) => {
|
||||
if (typeof matcher === 'function') {
|
||||
return matcher;
|
||||
}
|
||||
if (typeof matcher === 'string') {
|
||||
const glob = picomatch(matcher, options);
|
||||
return (string) => matcher === string || glob(string);
|
||||
}
|
||||
if (matcher instanceof RegExp) {
|
||||
return (string) => matcher.test(string);
|
||||
}
|
||||
return (string) => false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<Function>} patterns
|
||||
* @param {Array<Function>} negPatterns
|
||||
* @param {String|Array} args
|
||||
* @param {Boolean} returnIndex
|
||||
* @returns {boolean|number}
|
||||
*/
|
||||
const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
|
||||
const isList = Array.isArray(args);
|
||||
const _path = isList ? args[0] : args;
|
||||
if (!isList && typeof _path !== 'string') {
|
||||
throw new TypeError('anymatch: second argument must be a string: got ' +
|
||||
Object.prototype.toString.call(_path))
|
||||
}
|
||||
const path = normalizePath(_path, false);
|
||||
|
||||
for (let index = 0; index < negPatterns.length; index++) {
|
||||
const nglob = negPatterns[index];
|
||||
if (nglob(path)) {
|
||||
return returnIndex ? -1 : false;
|
||||
}
|
||||
}
|
||||
|
||||
const applied = isList && [path].concat(args.slice(1));
|
||||
for (let index = 0; index < patterns.length; index++) {
|
||||
const pattern = patterns[index];
|
||||
if (isList ? pattern(...applied) : pattern(path)) {
|
||||
return returnIndex ? index : true;
|
||||
}
|
||||
}
|
||||
|
||||
return returnIndex ? -1 : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {AnymatchMatcher} matchers
|
||||
* @param {Array|string} testString
|
||||
* @param {object} options
|
||||
* @returns {boolean|number|Function}
|
||||
*/
|
||||
const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
|
||||
if (matchers == null) {
|
||||
throw new TypeError('anymatch: specify first argument');
|
||||
}
|
||||
const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
|
||||
const returnIndex = opts.returnIndex || false;
|
||||
|
||||
// Early cache for matchers.
|
||||
const mtchers = arrify(matchers);
|
||||
const negatedGlobs = mtchers
|
||||
.filter(item => typeof item === 'string' && item.charAt(0) === BANG)
|
||||
.map(item => item.slice(1))
|
||||
.map(item => picomatch(item, opts));
|
||||
const patterns = mtchers
|
||||
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
|
||||
.map(matcher => createPattern(matcher, opts));
|
||||
|
||||
if (testString == null) {
|
||||
return (testString, ri = false) => {
|
||||
const returnIndex = typeof ri === 'boolean' ? ri : false;
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
};
|
||||
|
||||
anymatch.default = anymatch;
|
||||
module.exports = anymatch;
|
||||
51
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/package.json
generated
vendored
Normal file
51
node_modules/.store/anymatch@3.1.3/node_modules/anymatch/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "anymatch",
|
||||
"version": "3.1.3",
|
||||
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Elan Shanker",
|
||||
"url": "https://github.com/es128"
|
||||
},
|
||||
"license": "ISC",
|
||||
"homepage": "https://github.com/micromatch/anymatch",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/micromatch/anymatch"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"any",
|
||||
"string",
|
||||
"file",
|
||||
"fs",
|
||||
"list",
|
||||
"glob",
|
||||
"regex",
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"function"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "nyc mocha",
|
||||
"mocha": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^6.1.3",
|
||||
"nyc": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "anymatch@3.1.3",
|
||||
"_resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz"
|
||||
}
|
||||
21
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/LICENSE
generated
vendored
Normal file
21
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2018, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
127
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/README.md
generated
vendored
Normal file
127
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/README.md
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
# normalize-path [](https://www.npmjs.com/package/normalize-path) [](https://npmjs.org/package/normalize-path) [](https://npmjs.org/package/normalize-path) [](https://travis-ci.org/jonschlinkert/normalize-path)
|
||||
|
||||
> Normalize slashes in a file path to be posix/unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes, unless disabled.
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save normalize-path
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const normalize = require('normalize-path');
|
||||
|
||||
console.log(normalize('\\foo\\bar\\baz\\'));
|
||||
//=> '/foo/bar/baz'
|
||||
```
|
||||
|
||||
**win32 namespaces**
|
||||
|
||||
```js
|
||||
console.log(normalize('\\\\?\\UNC\\Server01\\user\\docs\\Letter.txt'));
|
||||
//=> '//?/UNC/Server01/user/docs/Letter.txt'
|
||||
|
||||
console.log(normalize('\\\\.\\CdRomX'));
|
||||
//=> '//./CdRomX'
|
||||
```
|
||||
|
||||
**Consecutive slashes**
|
||||
|
||||
Condenses multiple consecutive forward slashes (except for leading slashes in win32 namespaces) to a single slash.
|
||||
|
||||
```js
|
||||
console.log(normalize('.//foo//bar///////baz/'));
|
||||
//=> './foo/bar/baz'
|
||||
```
|
||||
|
||||
### Trailing slashes
|
||||
|
||||
By default trailing slashes are removed. Pass `false` as the last argument to disable this behavior and _**keep** trailing slashes_:
|
||||
|
||||
```js
|
||||
console.log(normalize('foo\\bar\\baz\\', false)); //=> 'foo/bar/baz/'
|
||||
console.log(normalize('./foo/bar/baz/', false)); //=> './foo/bar/baz/'
|
||||
```
|
||||
|
||||
## Release history
|
||||
|
||||
### v3.0
|
||||
|
||||
No breaking changes in this release.
|
||||
|
||||
* a check was added to ensure that [win32 namespaces](https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces) are handled properly by win32 `path.parse()` after a path has been normalized by this library.
|
||||
* a minor optimization was made to simplify how the trailing separator was handled
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Related projects
|
||||
|
||||
Other useful path-related libraries:
|
||||
|
||||
* [contains-path](https://www.npmjs.com/package/contains-path): Return true if a file path contains the given path. | [homepage](https://github.com/jonschlinkert/contains-path "Return true if a file path contains the given path.")
|
||||
* [is-absolute](https://www.npmjs.com/package/is-absolute): Returns true if a file path is absolute. Does not rely on the path module… [more](https://github.com/jonschlinkert/is-absolute) | [homepage](https://github.com/jonschlinkert/is-absolute "Returns true if a file path is absolute. Does not rely on the path module and can be used as a polyfill for node.js native `path.isAbolute`.")
|
||||
* [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative "Returns `true` if the path appears to be relative.")
|
||||
* [parse-filepath](https://www.npmjs.com/package/parse-filepath): Pollyfill for node.js `path.parse`, parses a filepath into an object. | [homepage](https://github.com/jonschlinkert/parse-filepath "Pollyfill for node.js `path.parse`, parses a filepath into an object.")
|
||||
* [path-ends-with](https://www.npmjs.com/package/path-ends-with): Return `true` if a file path ends with the given string/suffix. | [homepage](https://github.com/jonschlinkert/path-ends-with "Return `true` if a file path ends with the given string/suffix.")
|
||||
* [unixify](https://www.npmjs.com/package/unixify): Convert Windows file paths to unix paths. | [homepage](https://github.com/jonschlinkert/unixify "Convert Windows file paths to unix paths.")
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 35 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 1 | [phated](https://github.com/phated) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on April 19, 2018._
|
||||
35
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/index.js
generated
vendored
Normal file
35
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/index.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* normalize-path <https://github.com/jonschlinkert/normalize-path>
|
||||
*
|
||||
* Copyright (c) 2014-2018, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
module.exports = function(path, stripTrailing) {
|
||||
if (typeof path !== 'string') {
|
||||
throw new TypeError('expected path to be a string');
|
||||
}
|
||||
|
||||
if (path === '\\' || path === '/') return '/';
|
||||
|
||||
var len = path.length;
|
||||
if (len <= 1) return path;
|
||||
|
||||
// ensure that win32 namespaces has two leading slashes, so that the path is
|
||||
// handled properly by the win32 version of path.parse() after being normalized
|
||||
// https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
|
||||
var prefix = '';
|
||||
if (len > 4 && path[3] === '\\') {
|
||||
var ch = path[2];
|
||||
if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
|
||||
path = path.slice(2);
|
||||
prefix = '//';
|
||||
}
|
||||
}
|
||||
|
||||
var segs = path.split(/[/\\]+/);
|
||||
if (stripTrailing !== false && segs[segs.length - 1] === '') {
|
||||
segs.pop();
|
||||
}
|
||||
return prefix + segs.join('/');
|
||||
};
|
||||
80
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/package.json
generated
vendored
Normal file
80
node_modules/.store/anymatch@3.1.3/node_modules/normalize-path/package.json
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "normalize-path",
|
||||
"description": "Normalize slashes in a file path to be posix/unix-like forward slashes. Also condenses repeat slashes to a single slash and removes and trailing slashes, unless disabled.",
|
||||
"version": "3.0.0",
|
||||
"homepage": "https://github.com/jonschlinkert/normalize-path",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"contributors": [
|
||||
"Blaine Bublitz (https://twitter.com/BlaineBublitz)",
|
||||
"Jon Schlinkert (http://twitter.com/jonschlinkert)"
|
||||
],
|
||||
"repository": "jonschlinkert/normalize-path",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/normalize-path/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp-format-md": "^1.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"mocha": "^3.5.3"
|
||||
},
|
||||
"keywords": [
|
||||
"absolute",
|
||||
"backslash",
|
||||
"delimiter",
|
||||
"file",
|
||||
"file-path",
|
||||
"filepath",
|
||||
"fix",
|
||||
"forward",
|
||||
"fp",
|
||||
"fs",
|
||||
"normalize",
|
||||
"path",
|
||||
"relative",
|
||||
"separator",
|
||||
"slash",
|
||||
"slashes",
|
||||
"trailing",
|
||||
"unix",
|
||||
"urix"
|
||||
],
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"related": {
|
||||
"description": "Other useful path-related libraries:",
|
||||
"list": [
|
||||
"contains-path",
|
||||
"is-absolute",
|
||||
"is-relative",
|
||||
"parse-filepath",
|
||||
"path-ends-with",
|
||||
"path-ends-with",
|
||||
"unixify"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "normalize-path@3.0.0",
|
||||
"_resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz"
|
||||
}
|
||||
136
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/CHANGELOG.md
generated
vendored
Normal file
136
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
# Release history
|
||||
|
||||
**All notable changes to this project will be documented in this file.**
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<details>
|
||||
<summary><strong>Guiding Principles</strong></summary>
|
||||
|
||||
- Changelogs are for humans, not machines.
|
||||
- There should be an entry for every single version.
|
||||
- The same types of changes should be grouped.
|
||||
- Versions and sections should be linkable.
|
||||
- The latest version comes first.
|
||||
- The release date of each versions is displayed.
|
||||
- Mention whether you follow Semantic Versioning.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Types of changes</strong></summary>
|
||||
|
||||
Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_):
|
||||
|
||||
- `Added` for new features.
|
||||
- `Changed` for changes in existing functionality.
|
||||
- `Deprecated` for soon-to-be removed features.
|
||||
- `Removed` for now removed features.
|
||||
- `Fixed` for any bug fixes.
|
||||
- `Security` in case of vulnerabilities.
|
||||
|
||||
</details>
|
||||
|
||||
## 2.3.1 (2022-01-02)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixes bug when a pattern containing an expression after the closing parenthesis (`/!(*.d).{ts,tsx}`) was incorrectly converted to regexp ([9f241ef](https://github.com/micromatch/picomatch/commit/9f241ef)).
|
||||
|
||||
### Changed
|
||||
|
||||
* Some documentation improvements ([f81d236](https://github.com/micromatch/picomatch/commit/f81d236), [421e0e7](https://github.com/micromatch/picomatch/commit/421e0e7)).
|
||||
|
||||
## 2.3.0 (2021-05-21)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixes bug where file names with two dots were not being matched consistently with negation extglobs containing a star ([56083ef](https://github.com/micromatch/picomatch/commit/56083ef))
|
||||
|
||||
## 2.2.3 (2021-04-10)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Do not skip pattern seperator for square brackets ([fb08a30](https://github.com/micromatch/picomatch/commit/fb08a30)).
|
||||
* Set negatedExtGlob also if it does not span the whole pattern ([032e3f5](https://github.com/micromatch/picomatch/commit/032e3f5)).
|
||||
|
||||
## 2.2.2 (2020-03-21)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Correctly handle parts of the pattern after parentheses in the `scan` method ([e15b920](https://github.com/micromatch/picomatch/commit/e15b920)).
|
||||
|
||||
## 2.2.1 (2020-01-04)
|
||||
|
||||
* Fixes [#49](https://github.com/micromatch/picomatch/issues/49), so that braces with no sets or ranges are now propertly treated as literals.
|
||||
|
||||
## 2.2.0 (2020-01-04)
|
||||
|
||||
* Disable fastpaths mode for the parse method ([5b8d33f](https://github.com/micromatch/picomatch/commit/5b8d33f))
|
||||
* Add `tokens`, `slashes`, and `parts` to the object returned by `picomatch.scan()`.
|
||||
|
||||
## 2.1.0 (2019-10-31)
|
||||
|
||||
* add benchmarks for scan ([4793b92](https://github.com/micromatch/picomatch/commit/4793b92))
|
||||
* Add eslint object-curly-spacing rule ([707c650](https://github.com/micromatch/picomatch/commit/707c650))
|
||||
* Add prefer-const eslint rule ([5c7501c](https://github.com/micromatch/picomatch/commit/5c7501c))
|
||||
* Add support for nonegate in scan API ([275c9b9](https://github.com/micromatch/picomatch/commit/275c9b9))
|
||||
* Change lets to consts. Move root import up. ([4840625](https://github.com/micromatch/picomatch/commit/4840625))
|
||||
* closes https://github.com/micromatch/picomatch/issues/21 ([766bcb0](https://github.com/micromatch/picomatch/commit/766bcb0))
|
||||
* Fix "Extglobs" table in readme ([eb19da8](https://github.com/micromatch/picomatch/commit/eb19da8))
|
||||
* fixes https://github.com/micromatch/picomatch/issues/20 ([9caca07](https://github.com/micromatch/picomatch/commit/9caca07))
|
||||
* fixes https://github.com/micromatch/picomatch/issues/26 ([fa58f45](https://github.com/micromatch/picomatch/commit/fa58f45))
|
||||
* Lint test ([d433a34](https://github.com/micromatch/picomatch/commit/d433a34))
|
||||
* lint unit tests ([0159b55](https://github.com/micromatch/picomatch/commit/0159b55))
|
||||
* Make scan work with noext ([6c02e03](https://github.com/micromatch/picomatch/commit/6c02e03))
|
||||
* minor linting ([c2a2b87](https://github.com/micromatch/picomatch/commit/c2a2b87))
|
||||
* minor parser improvements ([197671d](https://github.com/micromatch/picomatch/commit/197671d))
|
||||
* remove eslint since it... ([07876fa](https://github.com/micromatch/picomatch/commit/07876fa))
|
||||
* remove funding file ([8ebe96d](https://github.com/micromatch/picomatch/commit/8ebe96d))
|
||||
* Remove unused funks ([cbc6d54](https://github.com/micromatch/picomatch/commit/cbc6d54))
|
||||
* Run eslint during pretest, fix existing eslint findings ([0682367](https://github.com/micromatch/picomatch/commit/0682367))
|
||||
* support `noparen` in scan ([3d37569](https://github.com/micromatch/picomatch/commit/3d37569))
|
||||
* update changelog ([7b34e77](https://github.com/micromatch/picomatch/commit/7b34e77))
|
||||
* update travis ([777f038](https://github.com/micromatch/picomatch/commit/777f038))
|
||||
* Use eslint-disable-next-line instead of eslint-disable ([4e7c1fd](https://github.com/micromatch/picomatch/commit/4e7c1fd))
|
||||
|
||||
## 2.0.7 (2019-05-14)
|
||||
|
||||
* 2.0.7 ([9eb9a71](https://github.com/micromatch/picomatch/commit/9eb9a71))
|
||||
* supports lookbehinds ([1f63f7e](https://github.com/micromatch/picomatch/commit/1f63f7e))
|
||||
* update .verb.md file with typo change ([2741279](https://github.com/micromatch/picomatch/commit/2741279))
|
||||
* fix: typo in README ([0753e44](https://github.com/micromatch/picomatch/commit/0753e44))
|
||||
|
||||
## 2.0.4 (2019-04-10)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Readme link [fixed](https://github.com/micromatch/picomatch/pull/13/commits/a96ab3aa2b11b6861c23289964613d85563b05df) by @danez.
|
||||
- `options.capture` now works as expected when fastpaths are enabled. See https://github.com/micromatch/picomatch/pull/12/commits/26aefd71f1cfaf95c37f1c1fcab68a693b037304. Thanks to @DrPizza.
|
||||
|
||||
## 2.0.0 (2019-04-10)
|
||||
|
||||
### Added
|
||||
|
||||
- Adds support for `options.onIgnore`. See the readme for details
|
||||
- Adds support for `options.onResult`. See the readme for details
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- The unixify option was renamed to `windows`
|
||||
- caching and all related options and methods have been removed
|
||||
|
||||
## 1.0.0 (2018-11-05)
|
||||
|
||||
- adds `.onMatch` option
|
||||
- improvements to `.scan` method
|
||||
- numerous improvements and optimizations for matching and parsing
|
||||
- better windows path handling
|
||||
|
||||
## 0.1.0 - 2017-04-13
|
||||
|
||||
First release.
|
||||
|
||||
|
||||
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog
|
||||
21
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/LICENSE
generated
vendored
Normal file
21
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-present, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
708
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/README.md
generated
vendored
Normal file
708
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,708 @@
|
||||
<h1 align="center">Picomatch</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://npmjs.org/package/picomatch">
|
||||
<img src="https://img.shields.io/npm/v/picomatch.svg" alt="version">
|
||||
</a>
|
||||
<a href="https://github.com/micromatch/picomatch/actions?workflow=Tests">
|
||||
<img src="https://github.com/micromatch/picomatch/workflows/Tests/badge.svg" alt="test status">
|
||||
</a>
|
||||
<a href="https://coveralls.io/github/micromatch/picomatch">
|
||||
<img src="https://img.shields.io/coveralls/github/micromatch/picomatch/master.svg" alt="coverage status">
|
||||
</a>
|
||||
<a href="https://npmjs.org/package/picomatch">
|
||||
<img src="https://img.shields.io/npm/dm/picomatch.svg" alt="downloads">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<strong>Blazing fast and accurate glob matcher written in JavaScript.</strong></br>
|
||||
<em>No dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.</em>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Why picomatch?
|
||||
|
||||
* **Lightweight** - No dependencies
|
||||
* **Minimal** - Tiny API surface. Main export is a function that takes a glob pattern and returns a matcher function.
|
||||
* **Fast** - Loads in about 2ms (that's several times faster than a [single frame of a HD movie](http://www.endmemo.com/sconvert/framespersecondframespermillisecond.php) at 60fps)
|
||||
* **Performant** - Use the returned matcher function to speed up repeat matching (like when watching files)
|
||||
* **Accurate matching** - Using wildcards (`*` and `?`), globstars (`**`) for nested directories, [advanced globbing](#advanced-globbing) with extglobs, braces, and POSIX brackets, and support for escaping special characters with `\` or quotes.
|
||||
* **Well tested** - Thousands of unit tests
|
||||
|
||||
See the [library comparison](#library-comparisons) to other libraries.
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<details><summary> Click to expand </summary>
|
||||
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
* [picomatch](#picomatch)
|
||||
* [.test](#test)
|
||||
* [.matchBase](#matchbase)
|
||||
* [.isMatch](#ismatch)
|
||||
* [.parse](#parse)
|
||||
* [.scan](#scan)
|
||||
* [.compileRe](#compilere)
|
||||
* [.makeRe](#makere)
|
||||
* [.toRegex](#toregex)
|
||||
- [Options](#options)
|
||||
* [Picomatch options](#picomatch-options)
|
||||
* [Scan Options](#scan-options)
|
||||
* [Options Examples](#options-examples)
|
||||
- [Globbing features](#globbing-features)
|
||||
* [Basic globbing](#basic-globbing)
|
||||
* [Advanced globbing](#advanced-globbing)
|
||||
* [Braces](#braces)
|
||||
* [Matching special characters as literals](#matching-special-characters-as-literals)
|
||||
- [Library Comparisons](#library-comparisons)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Philosophies](#philosophies)
|
||||
- [About](#about)
|
||||
* [Author](#author)
|
||||
* [License](#license)
|
||||
|
||||
_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
|
||||
|
||||
</details>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
npm install --save picomatch
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Usage
|
||||
|
||||
The main export is a function that takes a glob pattern and an options object and returns a function for matching strings.
|
||||
|
||||
```js
|
||||
const pm = require('picomatch');
|
||||
const isMatch = pm('*.js');
|
||||
|
||||
console.log(isMatch('abcd')); //=> false
|
||||
console.log(isMatch('a.js')); //=> true
|
||||
console.log(isMatch('a.md')); //=> false
|
||||
console.log(isMatch('a/b.js')); //=> false
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## API
|
||||
|
||||
### [picomatch](lib/picomatch.js#L32)
|
||||
|
||||
Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information.
|
||||
|
||||
**Params**
|
||||
|
||||
* `globs` **{String|Array}**: One or more glob patterns.
|
||||
* `options` **{Object=}**
|
||||
* `returns` **{Function=}**: Returns a matcher function.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch(glob[, options]);
|
||||
|
||||
const isMatch = picomatch('*.!(*a)');
|
||||
console.log(isMatch('a.a')); //=> false
|
||||
console.log(isMatch('a.b')); //=> true
|
||||
```
|
||||
|
||||
### [.test](lib/picomatch.js#L117)
|
||||
|
||||
Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string.
|
||||
|
||||
**Params**
|
||||
|
||||
* `input` **{String}**: String to test.
|
||||
* `regex` **{RegExp}**
|
||||
* `returns` **{Object}**: Returns an object with matching info.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch.test(input, regex[, options]);
|
||||
|
||||
console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
|
||||
// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
|
||||
```
|
||||
|
||||
### [.matchBase](lib/picomatch.js#L161)
|
||||
|
||||
Match the basename of a filepath.
|
||||
|
||||
**Params**
|
||||
|
||||
* `input` **{String}**: String to test.
|
||||
* `glob` **{RegExp|String}**: Glob pattern or regex created by [.makeRe](#makeRe).
|
||||
* `returns` **{Boolean}**
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch.matchBase(input, glob[, options]);
|
||||
console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
|
||||
```
|
||||
|
||||
### [.isMatch](lib/picomatch.js#L183)
|
||||
|
||||
Returns true if **any** of the given glob `patterns` match the specified `string`.
|
||||
|
||||
**Params**
|
||||
|
||||
* **{String|Array}**: str The string to test.
|
||||
* **{String|Array}**: patterns One or more glob patterns to use for matching.
|
||||
* **{Object}**: See available [options](#options).
|
||||
* `returns` **{Boolean}**: Returns true if any patterns match `str`
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch.isMatch(string, patterns[, options]);
|
||||
|
||||
console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
|
||||
console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
|
||||
```
|
||||
|
||||
### [.parse](lib/picomatch.js#L199)
|
||||
|
||||
Parse a glob pattern to create the source string for a regular expression.
|
||||
|
||||
**Params**
|
||||
|
||||
* `pattern` **{String}**
|
||||
* `options` **{Object}**
|
||||
* `returns` **{Object}**: Returns an object with useful properties and output to be used as a regex source string.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
const result = picomatch.parse(pattern[, options]);
|
||||
```
|
||||
|
||||
### [.scan](lib/picomatch.js#L231)
|
||||
|
||||
Scan a glob pattern to separate the pattern into segments.
|
||||
|
||||
**Params**
|
||||
|
||||
* `input` **{String}**: Glob pattern to scan.
|
||||
* `options` **{Object}**
|
||||
* `returns` **{Object}**: Returns an object with
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch.scan(input[, options]);
|
||||
|
||||
const result = picomatch.scan('!./foo/*.js');
|
||||
console.log(result);
|
||||
{ prefix: '!./',
|
||||
input: '!./foo/*.js',
|
||||
start: 3,
|
||||
base: 'foo',
|
||||
glob: '*.js',
|
||||
isBrace: false,
|
||||
isBracket: false,
|
||||
isGlob: true,
|
||||
isExtglob: false,
|
||||
isGlobstar: false,
|
||||
negated: true }
|
||||
```
|
||||
|
||||
### [.compileRe](lib/picomatch.js#L245)
|
||||
|
||||
Compile a regular expression from the `state` object returned by the
|
||||
[parse()](#parse) method.
|
||||
|
||||
**Params**
|
||||
|
||||
* `state` **{Object}**
|
||||
* `options` **{Object}**
|
||||
* `returnOutput` **{Boolean}**: Intended for implementors, this argument allows you to return the raw output from the parser.
|
||||
* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
|
||||
* `returns` **{RegExp}**
|
||||
|
||||
### [.makeRe](lib/picomatch.js#L286)
|
||||
|
||||
Create a regular expression from a parsed glob pattern.
|
||||
|
||||
**Params**
|
||||
|
||||
* `state` **{String}**: The object returned from the `.parse` method.
|
||||
* `options` **{Object}**
|
||||
* `returnOutput` **{Boolean}**: Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
|
||||
* `returnState` **{Boolean}**: Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
|
||||
* `returns` **{RegExp}**: Returns a regex created from the given pattern.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
const state = picomatch.parse('*.js');
|
||||
// picomatch.compileRe(state[, options]);
|
||||
|
||||
console.log(picomatch.compileRe(state));
|
||||
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
||||
```
|
||||
|
||||
### [.toRegex](lib/picomatch.js#L321)
|
||||
|
||||
Create a regular expression from the given regex source string.
|
||||
|
||||
**Params**
|
||||
|
||||
* `source` **{String}**: Regular expression source string.
|
||||
* `options` **{Object}**
|
||||
* `returns` **{RegExp}**
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
// picomatch.toRegex(source[, options]);
|
||||
|
||||
const { output } = picomatch.parse('*.js');
|
||||
console.log(picomatch.toRegex(output));
|
||||
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Options
|
||||
|
||||
### Picomatch options
|
||||
|
||||
The following options may be used with the main `picomatch()` function or any of the methods on the picomatch API.
|
||||
|
||||
| **Option** | **Type** | **Default value** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| `basename` | `boolean` | `false` | If set, then patterns without slashes will be matched against the basename of the path if it contains slashes. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. |
|
||||
| `bash` | `boolean` | `false` | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). |
|
||||
| `capture` | `boolean` | `undefined` | Return regex matches in supporting methods. |
|
||||
| `contains` | `boolean` | `undefined` | Allows glob to match any part of the given string(s). |
|
||||
| `cwd` | `string` | `process.cwd()` | Current working directory. Used by `picomatch.split()` |
|
||||
| `debug` | `boolean` | `undefined` | Debug regular expressions when an error is thrown. |
|
||||
| `dot` | `boolean` | `false` | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true |
|
||||
| `expandRange` | `function` | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. |
|
||||
| `failglob` | `boolean` | `false` | Throws an error if no matches are found. Based on the bash option of the same name. |
|
||||
| `fastpaths` | `boolean` | `true` | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. |
|
||||
| `flags` | `string` | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. |
|
||||
| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. |
|
||||
| `ignore` | `array\|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. |
|
||||
| `keepQuotes` | `boolean` | `false` | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes. |
|
||||
| `literalBrackets` | `boolean` | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. |
|
||||
| `matchBase` | `boolean` | `false` | Alias for `basename` |
|
||||
| `maxLength` | `boolean` | `65536` | Limit the max length of the input string. An error is thrown if the input string is longer than this value. |
|
||||
| `nobrace` | `boolean` | `false` | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. |
|
||||
| `nobracket` | `boolean` | `undefined` | Disable matching with regex brackets. |
|
||||
| `nocase` | `boolean` | `false` | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. |
|
||||
| `nodupes` | `boolean` | `true` | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. |
|
||||
| `noext` | `boolean` | `false` | Alias for `noextglob` |
|
||||
| `noextglob` | `boolean` | `false` | Disable support for matching with extglobs (like `+(a\|b)`) |
|
||||
| `noglobstar` | `boolean` | `false` | Disable support for matching nested directories with globstars (`**`) |
|
||||
| `nonegate` | `boolean` | `false` | Disable support for negating with leading `!` |
|
||||
| `noquantifiers` | `boolean` | `false` | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. |
|
||||
| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. |
|
||||
| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. |
|
||||
| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. |
|
||||
| `posix` | `boolean` | `false` | Support POSIX character classes ("posix brackets"). |
|
||||
| `posixSlashes` | `boolean` | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself |
|
||||
| `prepend` | `boolean` | `undefined` | String to prepend to the generated regex used for matching. |
|
||||
| `regex` | `boolean` | `false` | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). |
|
||||
| `strictBrackets` | `boolean` | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. |
|
||||
| `strictSlashes` | `boolean` | `undefined` | When true, picomatch won't match trailing slashes with single stars. |
|
||||
| `unescape` | `boolean` | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. |
|
||||
| `unixify` | `boolean` | `undefined` | Alias for `posixSlashes`, for backwards compatibility. |
|
||||
|
||||
picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error.
|
||||
|
||||
### Scan Options
|
||||
|
||||
In addition to the main [picomatch options](#picomatch-options), the following options may also be used with the [.scan](#scan) method.
|
||||
|
||||
| **Option** | **Type** | **Default value** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| `tokens` | `boolean` | `false` | When `true`, the returned object will include an array of tokens (objects), representing each path "segment" in the scanned glob pattern |
|
||||
| `parts` | `boolean` | `false` | When `true`, the returned object will include an array of strings representing each path "segment" in the scanned glob pattern. This is automatically enabled when `options.tokens` is true |
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const picomatch = require('picomatch');
|
||||
const result = picomatch.scan('!./foo/*.js', { tokens: true });
|
||||
console.log(result);
|
||||
// {
|
||||
// prefix: '!./',
|
||||
// input: '!./foo/*.js',
|
||||
// start: 3,
|
||||
// base: 'foo',
|
||||
// glob: '*.js',
|
||||
// isBrace: false,
|
||||
// isBracket: false,
|
||||
// isGlob: true,
|
||||
// isExtglob: false,
|
||||
// isGlobstar: false,
|
||||
// negated: true,
|
||||
// maxDepth: 2,
|
||||
// tokens: [
|
||||
// { value: '!./', depth: 0, isGlob: false, negated: true, isPrefix: true },
|
||||
// { value: 'foo', depth: 1, isGlob: false },
|
||||
// { value: '*.js', depth: 1, isGlob: true }
|
||||
// ],
|
||||
// slashes: [ 2, 6 ],
|
||||
// parts: [ 'foo', '*.js' ]
|
||||
// }
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### Options Examples
|
||||
|
||||
#### options.expandRange
|
||||
|
||||
**Type**: `function`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
Custom function for expanding ranges in brace patterns. The [fill-range](https://github.com/jonschlinkert/fill-range) library is ideal for this purpose, or you can use custom code to do whatever you need.
|
||||
|
||||
**Example**
|
||||
|
||||
The following example shows how to create a glob that matches a folder
|
||||
|
||||
```js
|
||||
const fill = require('fill-range');
|
||||
const regex = pm.makeRe('foo/{01..25}/bar', {
|
||||
expandRange(a, b) {
|
||||
return `(${fill(a, b, { toRegex: true })})`;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(regex);
|
||||
//=> /^(?:foo\/((?:0[1-9]|1[0-9]|2[0-5]))\/bar)$/
|
||||
|
||||
console.log(regex.test('foo/00/bar')) // false
|
||||
console.log(regex.test('foo/01/bar')) // true
|
||||
console.log(regex.test('foo/10/bar')) // true
|
||||
console.log(regex.test('foo/22/bar')) // true
|
||||
console.log(regex.test('foo/25/bar')) // true
|
||||
console.log(regex.test('foo/26/bar')) // false
|
||||
```
|
||||
|
||||
#### options.format
|
||||
|
||||
**Type**: `function`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
Custom function for formatting strings before they're matched.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
// strip leading './' from strings
|
||||
const format = str => str.replace(/^\.\//, '');
|
||||
const isMatch = picomatch('foo/*.js', { format });
|
||||
console.log(isMatch('./foo/bar.js')); //=> true
|
||||
```
|
||||
|
||||
#### options.onMatch
|
||||
|
||||
```js
|
||||
const onMatch = ({ glob, regex, input, output }) => {
|
||||
console.log({ glob, regex, input, output });
|
||||
};
|
||||
|
||||
const isMatch = picomatch('*', { onMatch });
|
||||
isMatch('foo');
|
||||
isMatch('bar');
|
||||
isMatch('baz');
|
||||
```
|
||||
|
||||
#### options.onIgnore
|
||||
|
||||
```js
|
||||
const onIgnore = ({ glob, regex, input, output }) => {
|
||||
console.log({ glob, regex, input, output });
|
||||
};
|
||||
|
||||
const isMatch = picomatch('*', { onIgnore, ignore: 'f*' });
|
||||
isMatch('foo');
|
||||
isMatch('bar');
|
||||
isMatch('baz');
|
||||
```
|
||||
|
||||
#### options.onResult
|
||||
|
||||
```js
|
||||
const onResult = ({ glob, regex, input, output }) => {
|
||||
console.log({ glob, regex, input, output });
|
||||
};
|
||||
|
||||
const isMatch = picomatch('*', { onResult, ignore: 'f*' });
|
||||
isMatch('foo');
|
||||
isMatch('bar');
|
||||
isMatch('baz');
|
||||
```
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Globbing features
|
||||
|
||||
* [Basic globbing](#basic-globbing) (Wildcard matching)
|
||||
* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching)
|
||||
|
||||
### Basic globbing
|
||||
|
||||
| **Character** | **Description** |
|
||||
| --- | --- |
|
||||
| `*` | Matches any character zero or more times, excluding path separators. Does _not match_ path separators or hidden files or directories ("dotfiles"), unless explicitly enabled by setting the `dot` option to `true`. |
|
||||
| `**` | Matches any character zero or more times, including path separators. Note that `**` will only match path separators (`/`, and `\\` on Windows) when they are the only characters in a path segment. Thus, `foo**/bar` is equivalent to `foo*/bar`, and `foo/a**b/bar` is equivalent to `foo/a*b/bar`, and _more than two_ consecutive stars in a glob path segment are regarded as _a single star_. Thus, `foo/***/bar` is equivalent to `foo/*/bar`. |
|
||||
| `?` | Matches any character excluding path separators one time. Does _not match_ path separators or leading dots. |
|
||||
| `[abc]` | Matches any characters inside the brackets. For example, `[abc]` would match the characters `a`, `b` or `c`, and nothing else. |
|
||||
|
||||
#### Matching behavior vs. Bash
|
||||
|
||||
Picomatch's matching features and expected results in unit tests are based on Bash's unit tests and the Bash 4.3 specification, with the following exceptions:
|
||||
|
||||
* Bash will match `foo/bar/baz` with `*`. Picomatch only matches nested directories with `**`.
|
||||
* Bash greedily matches with negated extglobs. For example, Bash 4.3 says that `!(foo)*` should match `foo` and `foobar`, since the trailing `*` bracktracks to match the preceding pattern. This is very memory-inefficient, and IMHO, also incorrect. Picomatch would return `false` for both `foo` and `foobar`.
|
||||
|
||||
<br>
|
||||
|
||||
### Advanced globbing
|
||||
|
||||
* [extglobs](#extglobs)
|
||||
* [POSIX brackets](#posix-brackets)
|
||||
* [Braces](#brace-expansion)
|
||||
|
||||
#### Extglobs
|
||||
|
||||
| **Pattern** | **Description** |
|
||||
| --- | --- |
|
||||
| `@(pattern)` | Match _only one_ consecutive occurrence of `pattern` |
|
||||
| `*(pattern)` | Match _zero or more_ consecutive occurrences of `pattern` |
|
||||
| `+(pattern)` | Match _one or more_ consecutive occurrences of `pattern` |
|
||||
| `?(pattern)` | Match _zero or **one**_ consecutive occurrences of `pattern` |
|
||||
| `!(pattern)` | Match _anything but_ `pattern` |
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
const pm = require('picomatch');
|
||||
|
||||
// *(pattern) matches ZERO or more of "pattern"
|
||||
console.log(pm.isMatch('a', 'a*(z)')); // true
|
||||
console.log(pm.isMatch('az', 'a*(z)')); // true
|
||||
console.log(pm.isMatch('azzz', 'a*(z)')); // true
|
||||
|
||||
// +(pattern) matches ONE or more of "pattern"
|
||||
console.log(pm.isMatch('a', 'a*(z)')); // true
|
||||
console.log(pm.isMatch('az', 'a*(z)')); // true
|
||||
console.log(pm.isMatch('azzz', 'a*(z)')); // true
|
||||
|
||||
// supports multiple extglobs
|
||||
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false
|
||||
|
||||
// supports nested extglobs
|
||||
console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true
|
||||
```
|
||||
|
||||
#### POSIX brackets
|
||||
|
||||
POSIX classes are disabled by default. Enable this feature by setting the `posix` option to true.
|
||||
|
||||
**Enable POSIX bracket support**
|
||||
|
||||
```js
|
||||
console.log(pm.makeRe('[[:word:]]+', { posix: true }));
|
||||
//=> /^(?:(?=.)[A-Za-z0-9_]+\/?)$/
|
||||
```
|
||||
|
||||
**Supported POSIX classes**
|
||||
|
||||
The following named POSIX bracket expressions are supported:
|
||||
|
||||
* `[:alnum:]` - Alphanumeric characters, equ `[a-zA-Z0-9]`
|
||||
* `[:alpha:]` - Alphabetical characters, equivalent to `[a-zA-Z]`.
|
||||
* `[:ascii:]` - ASCII characters, equivalent to `[\\x00-\\x7F]`.
|
||||
* `[:blank:]` - Space and tab characters, equivalent to `[ \\t]`.
|
||||
* `[:cntrl:]` - Control characters, equivalent to `[\\x00-\\x1F\\x7F]`.
|
||||
* `[:digit:]` - Numerical digits, equivalent to `[0-9]`.
|
||||
* `[:graph:]` - Graph characters, equivalent to `[\\x21-\\x7E]`.
|
||||
* `[:lower:]` - Lowercase letters, equivalent to `[a-z]`.
|
||||
* `[:print:]` - Print characters, equivalent to `[\\x20-\\x7E ]`.
|
||||
* `[:punct:]` - Punctuation and symbols, equivalent to `[\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~]`.
|
||||
* `[:space:]` - Extended space characters, equivalent to `[ \\t\\r\\n\\v\\f]`.
|
||||
* `[:upper:]` - Uppercase letters, equivalent to `[A-Z]`.
|
||||
* `[:word:]` - Word characters (letters, numbers and underscores), equivalent to `[A-Za-z0-9_]`.
|
||||
* `[:xdigit:]` - Hexadecimal digits, equivalent to `[A-Fa-f0-9]`.
|
||||
|
||||
See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) for more information.
|
||||
|
||||
### Braces
|
||||
|
||||
Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces.
|
||||
|
||||
### Matching special characters as literals
|
||||
|
||||
If you wish to match the following special characters in a filepath, and you want to use these characters in your glob pattern, they must be escaped with backslashes or quotes:
|
||||
|
||||
**Special Characters**
|
||||
|
||||
Some characters that are used for matching in regular expressions are also regarded as valid file path characters on some platforms.
|
||||
|
||||
To match any of the following characters as literals: `$^*+?()[]
|
||||
|
||||
Examples:
|
||||
|
||||
```js
|
||||
console.log(pm.makeRe('foo/bar \\(1\\)'));
|
||||
console.log(pm.makeRe('foo/bar \\(1\\)'));
|
||||
```
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Library Comparisons
|
||||
|
||||
The following table shows which features are supported by [minimatch](https://github.com/isaacs/minimatch), [micromatch](https://github.com/micromatch/micromatch), [picomatch](https://github.com/micromatch/picomatch), [nanomatch](https://github.com/micromatch/nanomatch), [extglob](https://github.com/micromatch/extglob), [braces](https://github.com/micromatch/braces), and [expand-brackets](https://github.com/micromatch/expand-brackets).
|
||||
|
||||
| **Feature** | `minimatch` | `micromatch` | `picomatch` | `nanomatch` | `extglob` | `braces` | `expand-brackets` |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Wildcard matching (`*?+`) | ✔ | ✔ | ✔ | ✔ | - | - | - |
|
||||
| Advancing globbing | ✔ | ✔ | ✔ | - | - | - | - |
|
||||
| Brace _matching_ | ✔ | ✔ | ✔ | - | - | ✔ | - |
|
||||
| Brace _expansion_ | ✔ | ✔ | - | - | - | ✔ | - |
|
||||
| Extglobs | partial | ✔ | ✔ | - | ✔ | - | - |
|
||||
| Posix brackets | - | ✔ | ✔ | - | - | - | ✔ |
|
||||
| Regular expression syntax | - | ✔ | ✔ | ✔ | ✔ | - | ✔ |
|
||||
| File system operations | - | - | - | - | - | - | - |
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Performance comparison of picomatch and minimatch.
|
||||
|
||||
```
|
||||
# .makeRe star
|
||||
picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled)
|
||||
minimatch x 627,206 ops/sec ±1.96% (87 runs sampled))
|
||||
|
||||
# .makeRe star; dot=true
|
||||
picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled)
|
||||
minimatch x 525,876 ops/sec ±0.60% (88 runs sampled)
|
||||
|
||||
# .makeRe globstar
|
||||
picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled)
|
||||
minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d)
|
||||
|
||||
# .makeRe globstars
|
||||
picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled)
|
||||
minimatch x 477,179 ops/sec ±1.33% (91 runs sampled)
|
||||
|
||||
# .makeRe with leading star
|
||||
picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled)
|
||||
minimatch x 453,564 ops/sec ±1.43% (94 runs sampled)
|
||||
|
||||
# .makeRe - basic braces
|
||||
picomatch x 392,067 ops/sec ±0.70% (90 runs sampled)
|
||||
minimatch x 99,532 ops/sec ±2.03% (87 runs sampled))
|
||||
```
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## Philosophies
|
||||
|
||||
The goal of this library is to be blazing fast, without compromising on accuracy.
|
||||
|
||||
**Accuracy**
|
||||
|
||||
The number one of goal of this library is accuracy. However, it's not unusual for different glob implementations to have different rules for matching behavior, even with simple wildcard matching. It gets increasingly more complicated when combinations of different features are combined, like when extglobs are combined with globstars, braces, slashes, and so on: `!(**/{a,b,*/c})`.
|
||||
|
||||
Thus, given that there is no canonical glob specification to use as a single source of truth when differences of opinion arise regarding behavior, sometimes we have to implement our best judgement and rely on feedback from users to make improvements.
|
||||
|
||||
**Performance**
|
||||
|
||||
Although this library performs well in benchmarks, and in most cases it's faster than other popular libraries we benchmarked against, we will always choose accuracy over performance. It's not helpful to anyone if our library is faster at returning the wrong answer.
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
3
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/index.js
generated
vendored
Normal file
3
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require('./lib/picomatch');
|
||||
179
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/constants.js
generated
vendored
Normal file
179
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/constants.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const WIN_SLASH = '\\\\/';
|
||||
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
|
||||
|
||||
/**
|
||||
* Posix glob regex
|
||||
*/
|
||||
|
||||
const DOT_LITERAL = '\\.';
|
||||
const PLUS_LITERAL = '\\+';
|
||||
const QMARK_LITERAL = '\\?';
|
||||
const SLASH_LITERAL = '\\/';
|
||||
const ONE_CHAR = '(?=.)';
|
||||
const QMARK = '[^/]';
|
||||
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
|
||||
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
|
||||
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
|
||||
const NO_DOT = `(?!${DOT_LITERAL})`;
|
||||
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
|
||||
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
|
||||
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
|
||||
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
|
||||
const STAR = `${QMARK}*?`;
|
||||
|
||||
const POSIX_CHARS = {
|
||||
DOT_LITERAL,
|
||||
PLUS_LITERAL,
|
||||
QMARK_LITERAL,
|
||||
SLASH_LITERAL,
|
||||
ONE_CHAR,
|
||||
QMARK,
|
||||
END_ANCHOR,
|
||||
DOTS_SLASH,
|
||||
NO_DOT,
|
||||
NO_DOTS,
|
||||
NO_DOT_SLASH,
|
||||
NO_DOTS_SLASH,
|
||||
QMARK_NO_DOT,
|
||||
STAR,
|
||||
START_ANCHOR
|
||||
};
|
||||
|
||||
/**
|
||||
* Windows glob regex
|
||||
*/
|
||||
|
||||
const WINDOWS_CHARS = {
|
||||
...POSIX_CHARS,
|
||||
|
||||
SLASH_LITERAL: `[${WIN_SLASH}]`,
|
||||
QMARK: WIN_NO_SLASH,
|
||||
STAR: `${WIN_NO_SLASH}*?`,
|
||||
DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
|
||||
NO_DOT: `(?!${DOT_LITERAL})`,
|
||||
NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
|
||||
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
|
||||
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
|
||||
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
|
||||
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
|
||||
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
|
||||
};
|
||||
|
||||
/**
|
||||
* POSIX Bracket Regex
|
||||
*/
|
||||
|
||||
const POSIX_REGEX_SOURCE = {
|
||||
alnum: 'a-zA-Z0-9',
|
||||
alpha: 'a-zA-Z',
|
||||
ascii: '\\x00-\\x7F',
|
||||
blank: ' \\t',
|
||||
cntrl: '\\x00-\\x1F\\x7F',
|
||||
digit: '0-9',
|
||||
graph: '\\x21-\\x7E',
|
||||
lower: 'a-z',
|
||||
print: '\\x20-\\x7E ',
|
||||
punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
|
||||
space: ' \\t\\r\\n\\v\\f',
|
||||
upper: 'A-Z',
|
||||
word: 'A-Za-z0-9_',
|
||||
xdigit: 'A-Fa-f0-9'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
MAX_LENGTH: 1024 * 64,
|
||||
POSIX_REGEX_SOURCE,
|
||||
|
||||
// regular expressions
|
||||
REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
|
||||
REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
|
||||
REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
|
||||
REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
|
||||
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
|
||||
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
|
||||
|
||||
// Replace globs with equivalent patterns to reduce parsing time.
|
||||
REPLACEMENTS: {
|
||||
'***': '*',
|
||||
'**/**': '**',
|
||||
'**/**/**': '**'
|
||||
},
|
||||
|
||||
// Digits
|
||||
CHAR_0: 48, /* 0 */
|
||||
CHAR_9: 57, /* 9 */
|
||||
|
||||
// Alphabet chars.
|
||||
CHAR_UPPERCASE_A: 65, /* A */
|
||||
CHAR_LOWERCASE_A: 97, /* a */
|
||||
CHAR_UPPERCASE_Z: 90, /* Z */
|
||||
CHAR_LOWERCASE_Z: 122, /* z */
|
||||
|
||||
CHAR_LEFT_PARENTHESES: 40, /* ( */
|
||||
CHAR_RIGHT_PARENTHESES: 41, /* ) */
|
||||
|
||||
CHAR_ASTERISK: 42, /* * */
|
||||
|
||||
// Non-alphabetic chars.
|
||||
CHAR_AMPERSAND: 38, /* & */
|
||||
CHAR_AT: 64, /* @ */
|
||||
CHAR_BACKWARD_SLASH: 92, /* \ */
|
||||
CHAR_CARRIAGE_RETURN: 13, /* \r */
|
||||
CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
|
||||
CHAR_COLON: 58, /* : */
|
||||
CHAR_COMMA: 44, /* , */
|
||||
CHAR_DOT: 46, /* . */
|
||||
CHAR_DOUBLE_QUOTE: 34, /* " */
|
||||
CHAR_EQUAL: 61, /* = */
|
||||
CHAR_EXCLAMATION_MARK: 33, /* ! */
|
||||
CHAR_FORM_FEED: 12, /* \f */
|
||||
CHAR_FORWARD_SLASH: 47, /* / */
|
||||
CHAR_GRAVE_ACCENT: 96, /* ` */
|
||||
CHAR_HASH: 35, /* # */
|
||||
CHAR_HYPHEN_MINUS: 45, /* - */
|
||||
CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
|
||||
CHAR_LEFT_CURLY_BRACE: 123, /* { */
|
||||
CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
|
||||
CHAR_LINE_FEED: 10, /* \n */
|
||||
CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
|
||||
CHAR_PERCENT: 37, /* % */
|
||||
CHAR_PLUS: 43, /* + */
|
||||
CHAR_QUESTION_MARK: 63, /* ? */
|
||||
CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
|
||||
CHAR_RIGHT_CURLY_BRACE: 125, /* } */
|
||||
CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
|
||||
CHAR_SEMICOLON: 59, /* ; */
|
||||
CHAR_SINGLE_QUOTE: 39, /* ' */
|
||||
CHAR_SPACE: 32, /* */
|
||||
CHAR_TAB: 9, /* \t */
|
||||
CHAR_UNDERSCORE: 95, /* _ */
|
||||
CHAR_VERTICAL_LINE: 124, /* | */
|
||||
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
|
||||
|
||||
SEP: path.sep,
|
||||
|
||||
/**
|
||||
* Create EXTGLOB_CHARS
|
||||
*/
|
||||
|
||||
extglobChars(chars) {
|
||||
return {
|
||||
'!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
|
||||
'?': { type: 'qmark', open: '(?:', close: ')?' },
|
||||
'+': { type: 'plus', open: '(?:', close: ')+' },
|
||||
'*': { type: 'star', open: '(?:', close: ')*' },
|
||||
'@': { type: 'at', open: '(?:', close: ')' }
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Create GLOB_CHARS
|
||||
*/
|
||||
|
||||
globChars(win32) {
|
||||
return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
|
||||
}
|
||||
};
|
||||
1091
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/parse.js
generated
vendored
Normal file
1091
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/parse.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
342
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/picomatch.js
generated
vendored
Normal file
342
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/picomatch.js
generated
vendored
Normal file
@@ -0,0 +1,342 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const scan = require('./scan');
|
||||
const parse = require('./parse');
|
||||
const utils = require('./utils');
|
||||
const constants = require('./constants');
|
||||
const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
|
||||
|
||||
/**
|
||||
* Creates a matcher function from one or more glob patterns. The
|
||||
* returned function takes a string to match as its first argument,
|
||||
* and returns true if the string is a match. The returned matcher
|
||||
* function also takes a boolean as the second argument that, when true,
|
||||
* returns an object with additional information.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch(glob[, options]);
|
||||
*
|
||||
* const isMatch = picomatch('*.!(*a)');
|
||||
* console.log(isMatch('a.a')); //=> false
|
||||
* console.log(isMatch('a.b')); //=> true
|
||||
* ```
|
||||
* @name picomatch
|
||||
* @param {String|Array} `globs` One or more glob patterns.
|
||||
* @param {Object=} `options`
|
||||
* @return {Function=} Returns a matcher function.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
const picomatch = (glob, options, returnState = false) => {
|
||||
if (Array.isArray(glob)) {
|
||||
const fns = glob.map(input => picomatch(input, options, returnState));
|
||||
const arrayMatcher = str => {
|
||||
for (const isMatch of fns) {
|
||||
const state = isMatch(str);
|
||||
if (state) return state;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return arrayMatcher;
|
||||
}
|
||||
|
||||
const isState = isObject(glob) && glob.tokens && glob.input;
|
||||
|
||||
if (glob === '' || (typeof glob !== 'string' && !isState)) {
|
||||
throw new TypeError('Expected pattern to be a non-empty string');
|
||||
}
|
||||
|
||||
const opts = options || {};
|
||||
const posix = utils.isWindows(options);
|
||||
const regex = isState
|
||||
? picomatch.compileRe(glob, options)
|
||||
: picomatch.makeRe(glob, options, false, true);
|
||||
|
||||
const state = regex.state;
|
||||
delete regex.state;
|
||||
|
||||
let isIgnored = () => false;
|
||||
if (opts.ignore) {
|
||||
const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
|
||||
isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
|
||||
}
|
||||
|
||||
const matcher = (input, returnObject = false) => {
|
||||
const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
|
||||
const result = { glob, state, regex, posix, input, output, match, isMatch };
|
||||
|
||||
if (typeof opts.onResult === 'function') {
|
||||
opts.onResult(result);
|
||||
}
|
||||
|
||||
if (isMatch === false) {
|
||||
result.isMatch = false;
|
||||
return returnObject ? result : false;
|
||||
}
|
||||
|
||||
if (isIgnored(input)) {
|
||||
if (typeof opts.onIgnore === 'function') {
|
||||
opts.onIgnore(result);
|
||||
}
|
||||
result.isMatch = false;
|
||||
return returnObject ? result : false;
|
||||
}
|
||||
|
||||
if (typeof opts.onMatch === 'function') {
|
||||
opts.onMatch(result);
|
||||
}
|
||||
return returnObject ? result : true;
|
||||
};
|
||||
|
||||
if (returnState) {
|
||||
matcher.state = state;
|
||||
}
|
||||
|
||||
return matcher;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test `input` with the given `regex`. This is used by the main
|
||||
* `picomatch()` function to test the input string.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch.test(input, regex[, options]);
|
||||
*
|
||||
* console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
|
||||
* // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
|
||||
* ```
|
||||
* @param {String} `input` String to test.
|
||||
* @param {RegExp} `regex`
|
||||
* @return {Object} Returns an object with matching info.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.test = (input, regex, options, { glob, posix } = {}) => {
|
||||
if (typeof input !== 'string') {
|
||||
throw new TypeError('Expected input to be a string');
|
||||
}
|
||||
|
||||
if (input === '') {
|
||||
return { isMatch: false, output: '' };
|
||||
}
|
||||
|
||||
const opts = options || {};
|
||||
const format = opts.format || (posix ? utils.toPosixSlashes : null);
|
||||
let match = input === glob;
|
||||
let output = (match && format) ? format(input) : input;
|
||||
|
||||
if (match === false) {
|
||||
output = format ? format(input) : input;
|
||||
match = output === glob;
|
||||
}
|
||||
|
||||
if (match === false || opts.capture === true) {
|
||||
if (opts.matchBase === true || opts.basename === true) {
|
||||
match = picomatch.matchBase(input, regex, options, posix);
|
||||
} else {
|
||||
match = regex.exec(output);
|
||||
}
|
||||
}
|
||||
|
||||
return { isMatch: Boolean(match), match, output };
|
||||
};
|
||||
|
||||
/**
|
||||
* Match the basename of a filepath.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch.matchBase(input, glob[, options]);
|
||||
* console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
|
||||
* ```
|
||||
* @param {String} `input` String to test.
|
||||
* @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
|
||||
const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
|
||||
return regex.test(path.basename(input));
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if **any** of the given glob `patterns` match the specified `string`.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch.isMatch(string, patterns[, options]);
|
||||
*
|
||||
* console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
|
||||
* console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
|
||||
* ```
|
||||
* @param {String|Array} str The string to test.
|
||||
* @param {String|Array} patterns One or more glob patterns to use for matching.
|
||||
* @param {Object} [options] See available [options](#options).
|
||||
* @return {Boolean} Returns true if any patterns match `str`
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
|
||||
|
||||
/**
|
||||
* Parse a glob pattern to create the source string for a regular
|
||||
* expression.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* const result = picomatch.parse(pattern[, options]);
|
||||
* ```
|
||||
* @param {String} `pattern`
|
||||
* @param {Object} `options`
|
||||
* @return {Object} Returns an object with useful properties and output to be used as a regex source string.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.parse = (pattern, options) => {
|
||||
if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
|
||||
return parse(pattern, { ...options, fastpaths: false });
|
||||
};
|
||||
|
||||
/**
|
||||
* Scan a glob pattern to separate the pattern into segments.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch.scan(input[, options]);
|
||||
*
|
||||
* const result = picomatch.scan('!./foo/*.js');
|
||||
* console.log(result);
|
||||
* { prefix: '!./',
|
||||
* input: '!./foo/*.js',
|
||||
* start: 3,
|
||||
* base: 'foo',
|
||||
* glob: '*.js',
|
||||
* isBrace: false,
|
||||
* isBracket: false,
|
||||
* isGlob: true,
|
||||
* isExtglob: false,
|
||||
* isGlobstar: false,
|
||||
* negated: true }
|
||||
* ```
|
||||
* @param {String} `input` Glob pattern to scan.
|
||||
* @param {Object} `options`
|
||||
* @return {Object} Returns an object with
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.scan = (input, options) => scan(input, options);
|
||||
|
||||
/**
|
||||
* Compile a regular expression from the `state` object returned by the
|
||||
* [parse()](#parse) method.
|
||||
*
|
||||
* @param {Object} `state`
|
||||
* @param {Object} `options`
|
||||
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
|
||||
* @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
|
||||
* @return {RegExp}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
|
||||
if (returnOutput === true) {
|
||||
return state.output;
|
||||
}
|
||||
|
||||
const opts = options || {};
|
||||
const prepend = opts.contains ? '' : '^';
|
||||
const append = opts.contains ? '' : '$';
|
||||
|
||||
let source = `${prepend}(?:${state.output})${append}`;
|
||||
if (state && state.negated === true) {
|
||||
source = `^(?!${source}).*$`;
|
||||
}
|
||||
|
||||
const regex = picomatch.toRegex(source, options);
|
||||
if (returnState === true) {
|
||||
regex.state = state;
|
||||
}
|
||||
|
||||
return regex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a regular expression from a parsed glob pattern.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* const state = picomatch.parse('*.js');
|
||||
* // picomatch.compileRe(state[, options]);
|
||||
*
|
||||
* console.log(picomatch.compileRe(state));
|
||||
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
||||
* ```
|
||||
* @param {String} `state` The object returned from the `.parse` method.
|
||||
* @param {Object} `options`
|
||||
* @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
|
||||
* @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
|
||||
* @return {RegExp} Returns a regex created from the given pattern.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
|
||||
if (!input || typeof input !== 'string') {
|
||||
throw new TypeError('Expected a non-empty string');
|
||||
}
|
||||
|
||||
let parsed = { negated: false, fastpaths: true };
|
||||
|
||||
if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
|
||||
parsed.output = parse.fastpaths(input, options);
|
||||
}
|
||||
|
||||
if (!parsed.output) {
|
||||
parsed = parse(input, options);
|
||||
}
|
||||
|
||||
return picomatch.compileRe(parsed, options, returnOutput, returnState);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a regular expression from the given regex source string.
|
||||
*
|
||||
* ```js
|
||||
* const picomatch = require('picomatch');
|
||||
* // picomatch.toRegex(source[, options]);
|
||||
*
|
||||
* const { output } = picomatch.parse('*.js');
|
||||
* console.log(picomatch.toRegex(output));
|
||||
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
||||
* ```
|
||||
* @param {String} `source` Regular expression source string.
|
||||
* @param {Object} `options`
|
||||
* @return {RegExp}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
picomatch.toRegex = (source, options) => {
|
||||
try {
|
||||
const opts = options || {};
|
||||
return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
|
||||
} catch (err) {
|
||||
if (options && options.debug === true) throw err;
|
||||
return /$^/;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Picomatch constants.
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
picomatch.constants = constants;
|
||||
|
||||
/**
|
||||
* Expose "picomatch"
|
||||
*/
|
||||
|
||||
module.exports = picomatch;
|
||||
391
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/scan.js
generated
vendored
Normal file
391
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/scan.js
generated
vendored
Normal file
@@ -0,0 +1,391 @@
|
||||
'use strict';
|
||||
|
||||
const utils = require('./utils');
|
||||
const {
|
||||
CHAR_ASTERISK, /* * */
|
||||
CHAR_AT, /* @ */
|
||||
CHAR_BACKWARD_SLASH, /* \ */
|
||||
CHAR_COMMA, /* , */
|
||||
CHAR_DOT, /* . */
|
||||
CHAR_EXCLAMATION_MARK, /* ! */
|
||||
CHAR_FORWARD_SLASH, /* / */
|
||||
CHAR_LEFT_CURLY_BRACE, /* { */
|
||||
CHAR_LEFT_PARENTHESES, /* ( */
|
||||
CHAR_LEFT_SQUARE_BRACKET, /* [ */
|
||||
CHAR_PLUS, /* + */
|
||||
CHAR_QUESTION_MARK, /* ? */
|
||||
CHAR_RIGHT_CURLY_BRACE, /* } */
|
||||
CHAR_RIGHT_PARENTHESES, /* ) */
|
||||
CHAR_RIGHT_SQUARE_BRACKET /* ] */
|
||||
} = require('./constants');
|
||||
|
||||
const isPathSeparator = code => {
|
||||
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
|
||||
};
|
||||
|
||||
const depth = token => {
|
||||
if (token.isPrefix !== true) {
|
||||
token.depth = token.isGlobstar ? Infinity : 1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Quickly scans a glob pattern and returns an object with a handful of
|
||||
* useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
|
||||
* `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
|
||||
* with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
|
||||
*
|
||||
* ```js
|
||||
* const pm = require('picomatch');
|
||||
* console.log(pm.scan('foo/bar/*.js'));
|
||||
* { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
|
||||
* ```
|
||||
* @param {String} `str`
|
||||
* @param {Object} `options`
|
||||
* @return {Object} Returns an object with tokens and regex source string.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
const scan = (input, options) => {
|
||||
const opts = options || {};
|
||||
|
||||
const length = input.length - 1;
|
||||
const scanToEnd = opts.parts === true || opts.scanToEnd === true;
|
||||
const slashes = [];
|
||||
const tokens = [];
|
||||
const parts = [];
|
||||
|
||||
let str = input;
|
||||
let index = -1;
|
||||
let start = 0;
|
||||
let lastIndex = 0;
|
||||
let isBrace = false;
|
||||
let isBracket = false;
|
||||
let isGlob = false;
|
||||
let isExtglob = false;
|
||||
let isGlobstar = false;
|
||||
let braceEscaped = false;
|
||||
let backslashes = false;
|
||||
let negated = false;
|
||||
let negatedExtglob = false;
|
||||
let finished = false;
|
||||
let braces = 0;
|
||||
let prev;
|
||||
let code;
|
||||
let token = { value: '', depth: 0, isGlob: false };
|
||||
|
||||
const eos = () => index >= length;
|
||||
const peek = () => str.charCodeAt(index + 1);
|
||||
const advance = () => {
|
||||
prev = code;
|
||||
return str.charCodeAt(++index);
|
||||
};
|
||||
|
||||
while (index < length) {
|
||||
code = advance();
|
||||
let next;
|
||||
|
||||
if (code === CHAR_BACKWARD_SLASH) {
|
||||
backslashes = token.backslashes = true;
|
||||
code = advance();
|
||||
|
||||
if (code === CHAR_LEFT_CURLY_BRACE) {
|
||||
braceEscaped = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
|
||||
braces++;
|
||||
|
||||
while (eos() !== true && (code = advance())) {
|
||||
if (code === CHAR_BACKWARD_SLASH) {
|
||||
backslashes = token.backslashes = true;
|
||||
advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code === CHAR_LEFT_CURLY_BRACE) {
|
||||
braces++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
|
||||
isBrace = token.isBrace = true;
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (braceEscaped !== true && code === CHAR_COMMA) {
|
||||
isBrace = token.isBrace = true;
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (code === CHAR_RIGHT_CURLY_BRACE) {
|
||||
braces--;
|
||||
|
||||
if (braces === 0) {
|
||||
braceEscaped = false;
|
||||
isBrace = token.isBrace = true;
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (code === CHAR_FORWARD_SLASH) {
|
||||
slashes.push(index);
|
||||
tokens.push(token);
|
||||
token = { value: '', depth: 0, isGlob: false };
|
||||
|
||||
if (finished === true) continue;
|
||||
if (prev === CHAR_DOT && index === (start + 1)) {
|
||||
start += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
lastIndex = index + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opts.noext !== true) {
|
||||
const isExtglobChar = code === CHAR_PLUS
|
||||
|| code === CHAR_AT
|
||||
|| code === CHAR_ASTERISK
|
||||
|| code === CHAR_QUESTION_MARK
|
||||
|| code === CHAR_EXCLAMATION_MARK;
|
||||
|
||||
if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
|
||||
isGlob = token.isGlob = true;
|
||||
isExtglob = token.isExtglob = true;
|
||||
finished = true;
|
||||
if (code === CHAR_EXCLAMATION_MARK && index === start) {
|
||||
negatedExtglob = true;
|
||||
}
|
||||
|
||||
if (scanToEnd === true) {
|
||||
while (eos() !== true && (code = advance())) {
|
||||
if (code === CHAR_BACKWARD_SLASH) {
|
||||
backslashes = token.backslashes = true;
|
||||
code = advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code === CHAR_RIGHT_PARENTHESES) {
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code === CHAR_ASTERISK) {
|
||||
if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (code === CHAR_QUESTION_MARK) {
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (code === CHAR_LEFT_SQUARE_BRACKET) {
|
||||
while (eos() !== true && (next = advance())) {
|
||||
if (next === CHAR_BACKWARD_SLASH) {
|
||||
backslashes = token.backslashes = true;
|
||||
advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
isBracket = token.isBracket = true;
|
||||
isGlob = token.isGlob = true;
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
|
||||
negated = token.negated = true;
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
|
||||
isGlob = token.isGlob = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
while (eos() !== true && (code = advance())) {
|
||||
if (code === CHAR_LEFT_PARENTHESES) {
|
||||
backslashes = token.backslashes = true;
|
||||
code = advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code === CHAR_RIGHT_PARENTHESES) {
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isGlob === true) {
|
||||
finished = true;
|
||||
|
||||
if (scanToEnd === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.noext === true) {
|
||||
isExtglob = false;
|
||||
isGlob = false;
|
||||
}
|
||||
|
||||
let base = str;
|
||||
let prefix = '';
|
||||
let glob = '';
|
||||
|
||||
if (start > 0) {
|
||||
prefix = str.slice(0, start);
|
||||
str = str.slice(start);
|
||||
lastIndex -= start;
|
||||
}
|
||||
|
||||
if (base && isGlob === true && lastIndex > 0) {
|
||||
base = str.slice(0, lastIndex);
|
||||
glob = str.slice(lastIndex);
|
||||
} else if (isGlob === true) {
|
||||
base = '';
|
||||
glob = str;
|
||||
} else {
|
||||
base = str;
|
||||
}
|
||||
|
||||
if (base && base !== '' && base !== '/' && base !== str) {
|
||||
if (isPathSeparator(base.charCodeAt(base.length - 1))) {
|
||||
base = base.slice(0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.unescape === true) {
|
||||
if (glob) glob = utils.removeBackslashes(glob);
|
||||
|
||||
if (base && backslashes === true) {
|
||||
base = utils.removeBackslashes(base);
|
||||
}
|
||||
}
|
||||
|
||||
const state = {
|
||||
prefix,
|
||||
input,
|
||||
start,
|
||||
base,
|
||||
glob,
|
||||
isBrace,
|
||||
isBracket,
|
||||
isGlob,
|
||||
isExtglob,
|
||||
isGlobstar,
|
||||
negated,
|
||||
negatedExtglob
|
||||
};
|
||||
|
||||
if (opts.tokens === true) {
|
||||
state.maxDepth = 0;
|
||||
if (!isPathSeparator(code)) {
|
||||
tokens.push(token);
|
||||
}
|
||||
state.tokens = tokens;
|
||||
}
|
||||
|
||||
if (opts.parts === true || opts.tokens === true) {
|
||||
let prevIndex;
|
||||
|
||||
for (let idx = 0; idx < slashes.length; idx++) {
|
||||
const n = prevIndex ? prevIndex + 1 : start;
|
||||
const i = slashes[idx];
|
||||
const value = input.slice(n, i);
|
||||
if (opts.tokens) {
|
||||
if (idx === 0 && start !== 0) {
|
||||
tokens[idx].isPrefix = true;
|
||||
tokens[idx].value = prefix;
|
||||
} else {
|
||||
tokens[idx].value = value;
|
||||
}
|
||||
depth(tokens[idx]);
|
||||
state.maxDepth += tokens[idx].depth;
|
||||
}
|
||||
if (idx !== 0 || value !== '') {
|
||||
parts.push(value);
|
||||
}
|
||||
prevIndex = i;
|
||||
}
|
||||
|
||||
if (prevIndex && prevIndex + 1 < input.length) {
|
||||
const value = input.slice(prevIndex + 1);
|
||||
parts.push(value);
|
||||
|
||||
if (opts.tokens) {
|
||||
tokens[tokens.length - 1].value = value;
|
||||
depth(tokens[tokens.length - 1]);
|
||||
state.maxDepth += tokens[tokens.length - 1].depth;
|
||||
}
|
||||
}
|
||||
|
||||
state.slashes = slashes;
|
||||
state.parts = parts;
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
module.exports = scan;
|
||||
64
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/utils.js
generated
vendored
Normal file
64
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const win32 = process.platform === 'win32';
|
||||
const {
|
||||
REGEX_BACKSLASH,
|
||||
REGEX_REMOVE_BACKSLASH,
|
||||
REGEX_SPECIAL_CHARS,
|
||||
REGEX_SPECIAL_CHARS_GLOBAL
|
||||
} = require('./constants');
|
||||
|
||||
exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
|
||||
exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
|
||||
exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
|
||||
exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
|
||||
exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
|
||||
|
||||
exports.removeBackslashes = str => {
|
||||
return str.replace(REGEX_REMOVE_BACKSLASH, match => {
|
||||
return match === '\\' ? '' : match;
|
||||
});
|
||||
};
|
||||
|
||||
exports.supportsLookbehinds = () => {
|
||||
const segs = process.version.slice(1).split('.').map(Number);
|
||||
if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.isWindows = options => {
|
||||
if (options && typeof options.windows === 'boolean') {
|
||||
return options.windows;
|
||||
}
|
||||
return win32 === true || path.sep === '\\';
|
||||
};
|
||||
|
||||
exports.escapeLast = (input, char, lastIdx) => {
|
||||
const idx = input.lastIndexOf(char, lastIdx);
|
||||
if (idx === -1) return input;
|
||||
if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
|
||||
return `${input.slice(0, idx)}\\${input.slice(idx)}`;
|
||||
};
|
||||
|
||||
exports.removePrefix = (input, state = {}) => {
|
||||
let output = input;
|
||||
if (output.startsWith('./')) {
|
||||
output = output.slice(2);
|
||||
state.prefix = './';
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
exports.wrapOutput = (input, state = {}, options = {}) => {
|
||||
const prepend = options.contains ? '' : '^';
|
||||
const append = options.contains ? '' : '$';
|
||||
|
||||
let output = `${prepend}(?:${input})${append}`;
|
||||
if (state.negated === true) {
|
||||
output = `(?:^(?!${output}).*$)`;
|
||||
}
|
||||
return output;
|
||||
};
|
||||
84
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/package.json
generated
vendored
Normal file
84
node_modules/.store/anymatch@3.1.3/node_modules/picomatch/package.json
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "picomatch",
|
||||
"description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.",
|
||||
"version": "2.3.1",
|
||||
"homepage": "https://github.com/micromatch/picomatch",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"funding": "https://github.com/sponsors/jonschlinkert",
|
||||
"repository": "micromatch/picomatch",
|
||||
"bugs": {
|
||||
"url": "https://github.com/micromatch/picomatch/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --cache --cache-location node_modules/.cache/.eslintcache --report-unused-disable-directives --ignore-path .gitignore .",
|
||||
"mocha": "mocha --reporter dot",
|
||||
"test": "npm run lint && npm run mocha",
|
||||
"test:ci": "npm run test:cover",
|
||||
"test:cover": "nyc npm run mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^6.8.0",
|
||||
"fill-range": "^7.0.1",
|
||||
"gulp-format-md": "^2.0.0",
|
||||
"mocha": "^6.2.2",
|
||||
"nyc": "^15.0.0",
|
||||
"time-require": "github:jonschlinkert/time-require"
|
||||
},
|
||||
"keywords": [
|
||||
"glob",
|
||||
"match",
|
||||
"picomatch"
|
||||
],
|
||||
"nyc": {
|
||||
"reporter": [
|
||||
"html",
|
||||
"lcov",
|
||||
"text-summary"
|
||||
]
|
||||
},
|
||||
"verb": {
|
||||
"toc": {
|
||||
"render": true,
|
||||
"method": "preWrite",
|
||||
"maxdepth": 3
|
||||
},
|
||||
"layout": "empty",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
},
|
||||
"related": {
|
||||
"list": [
|
||||
"braces",
|
||||
"micromatch"
|
||||
]
|
||||
},
|
||||
"reflinks": [
|
||||
"braces",
|
||||
"expand-brackets",
|
||||
"extglob",
|
||||
"fill-range",
|
||||
"micromatch",
|
||||
"minimatch",
|
||||
"nanomatch",
|
||||
"picomatch"
|
||||
]
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "picomatch@2.3.1",
|
||||
"_resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz"
|
||||
}
|
||||
260
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/binary-extensions.json
generated
vendored
Normal file
260
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/binary-extensions.json
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
[
|
||||
"3dm",
|
||||
"3ds",
|
||||
"3g2",
|
||||
"3gp",
|
||||
"7z",
|
||||
"a",
|
||||
"aac",
|
||||
"adp",
|
||||
"ai",
|
||||
"aif",
|
||||
"aiff",
|
||||
"alz",
|
||||
"ape",
|
||||
"apk",
|
||||
"appimage",
|
||||
"ar",
|
||||
"arj",
|
||||
"asf",
|
||||
"au",
|
||||
"avi",
|
||||
"bak",
|
||||
"baml",
|
||||
"bh",
|
||||
"bin",
|
||||
"bk",
|
||||
"bmp",
|
||||
"btif",
|
||||
"bz2",
|
||||
"bzip2",
|
||||
"cab",
|
||||
"caf",
|
||||
"cgm",
|
||||
"class",
|
||||
"cmx",
|
||||
"cpio",
|
||||
"cr2",
|
||||
"cur",
|
||||
"dat",
|
||||
"dcm",
|
||||
"deb",
|
||||
"dex",
|
||||
"djvu",
|
||||
"dll",
|
||||
"dmg",
|
||||
"dng",
|
||||
"doc",
|
||||
"docm",
|
||||
"docx",
|
||||
"dot",
|
||||
"dotm",
|
||||
"dra",
|
||||
"DS_Store",
|
||||
"dsk",
|
||||
"dts",
|
||||
"dtshd",
|
||||
"dvb",
|
||||
"dwg",
|
||||
"dxf",
|
||||
"ecelp4800",
|
||||
"ecelp7470",
|
||||
"ecelp9600",
|
||||
"egg",
|
||||
"eol",
|
||||
"eot",
|
||||
"epub",
|
||||
"exe",
|
||||
"f4v",
|
||||
"fbs",
|
||||
"fh",
|
||||
"fla",
|
||||
"flac",
|
||||
"flatpak",
|
||||
"fli",
|
||||
"flv",
|
||||
"fpx",
|
||||
"fst",
|
||||
"fvt",
|
||||
"g3",
|
||||
"gh",
|
||||
"gif",
|
||||
"graffle",
|
||||
"gz",
|
||||
"gzip",
|
||||
"h261",
|
||||
"h263",
|
||||
"h264",
|
||||
"icns",
|
||||
"ico",
|
||||
"ief",
|
||||
"img",
|
||||
"ipa",
|
||||
"iso",
|
||||
"jar",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"jpgv",
|
||||
"jpm",
|
||||
"jxr",
|
||||
"key",
|
||||
"ktx",
|
||||
"lha",
|
||||
"lib",
|
||||
"lvp",
|
||||
"lz",
|
||||
"lzh",
|
||||
"lzma",
|
||||
"lzo",
|
||||
"m3u",
|
||||
"m4a",
|
||||
"m4v",
|
||||
"mar",
|
||||
"mdi",
|
||||
"mht",
|
||||
"mid",
|
||||
"midi",
|
||||
"mj2",
|
||||
"mka",
|
||||
"mkv",
|
||||
"mmr",
|
||||
"mng",
|
||||
"mobi",
|
||||
"mov",
|
||||
"movie",
|
||||
"mp3",
|
||||
"mp4",
|
||||
"mp4a",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"mpga",
|
||||
"mxu",
|
||||
"nef",
|
||||
"npx",
|
||||
"numbers",
|
||||
"nupkg",
|
||||
"o",
|
||||
"odp",
|
||||
"ods",
|
||||
"odt",
|
||||
"oga",
|
||||
"ogg",
|
||||
"ogv",
|
||||
"otf",
|
||||
"ott",
|
||||
"pages",
|
||||
"pbm",
|
||||
"pcx",
|
||||
"pdb",
|
||||
"pdf",
|
||||
"pea",
|
||||
"pgm",
|
||||
"pic",
|
||||
"png",
|
||||
"pnm",
|
||||
"pot",
|
||||
"potm",
|
||||
"potx",
|
||||
"ppa",
|
||||
"ppam",
|
||||
"ppm",
|
||||
"pps",
|
||||
"ppsm",
|
||||
"ppsx",
|
||||
"ppt",
|
||||
"pptm",
|
||||
"pptx",
|
||||
"psd",
|
||||
"pya",
|
||||
"pyc",
|
||||
"pyo",
|
||||
"pyv",
|
||||
"qt",
|
||||
"rar",
|
||||
"ras",
|
||||
"raw",
|
||||
"resources",
|
||||
"rgb",
|
||||
"rip",
|
||||
"rlc",
|
||||
"rmf",
|
||||
"rmvb",
|
||||
"rpm",
|
||||
"rtf",
|
||||
"rz",
|
||||
"s3m",
|
||||
"s7z",
|
||||
"scpt",
|
||||
"sgi",
|
||||
"shar",
|
||||
"snap",
|
||||
"sil",
|
||||
"sketch",
|
||||
"slk",
|
||||
"smv",
|
||||
"snk",
|
||||
"so",
|
||||
"stl",
|
||||
"suo",
|
||||
"sub",
|
||||
"swf",
|
||||
"tar",
|
||||
"tbz",
|
||||
"tbz2",
|
||||
"tga",
|
||||
"tgz",
|
||||
"thmx",
|
||||
"tif",
|
||||
"tiff",
|
||||
"tlz",
|
||||
"ttc",
|
||||
"ttf",
|
||||
"txz",
|
||||
"udf",
|
||||
"uvh",
|
||||
"uvi",
|
||||
"uvm",
|
||||
"uvp",
|
||||
"uvs",
|
||||
"uvu",
|
||||
"viv",
|
||||
"vob",
|
||||
"war",
|
||||
"wav",
|
||||
"wax",
|
||||
"wbmp",
|
||||
"wdp",
|
||||
"weba",
|
||||
"webm",
|
||||
"webp",
|
||||
"whl",
|
||||
"wim",
|
||||
"wm",
|
||||
"wma",
|
||||
"wmv",
|
||||
"wmx",
|
||||
"woff",
|
||||
"woff2",
|
||||
"wrm",
|
||||
"wvx",
|
||||
"xbm",
|
||||
"xif",
|
||||
"xla",
|
||||
"xlam",
|
||||
"xls",
|
||||
"xlsb",
|
||||
"xlsm",
|
||||
"xlsx",
|
||||
"xlt",
|
||||
"xltm",
|
||||
"xltx",
|
||||
"xm",
|
||||
"xmind",
|
||||
"xpi",
|
||||
"xpm",
|
||||
"xwd",
|
||||
"xz",
|
||||
"z",
|
||||
"zip",
|
||||
"zipx"
|
||||
]
|
||||
3
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/binary-extensions.json.d.ts
generated
vendored
Normal file
3
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/binary-extensions.json.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const binaryExtensionsJson: readonly string[];
|
||||
|
||||
export = binaryExtensionsJson;
|
||||
14
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/index.d.ts
generated
vendored
Normal file
14
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
List of binary file extensions.
|
||||
|
||||
@example
|
||||
```
|
||||
import binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
*/
|
||||
declare const binaryExtensions: readonly string[];
|
||||
|
||||
export = binaryExtensions;
|
||||
1
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/index.js
generated
vendored
Normal file
1
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/index.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./binary-extensions.json');
|
||||
9
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/license
generated
vendored
Normal file
9
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/license
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com), Paul Miller (https://paulmillr.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.
|
||||
41
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/package.json
generated
vendored
Normal file
41
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/package.json
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "binary-extensions",
|
||||
"version": "2.2.0",
|
||||
"description": "List of binary file extensions",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/binary-extensions",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"binary-extensions.json",
|
||||
"binary-extensions.json.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"binary",
|
||||
"extensions",
|
||||
"extension",
|
||||
"file",
|
||||
"json",
|
||||
"list",
|
||||
"array"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"tsd": "^0.7.2",
|
||||
"xo": "^0.24.0"
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "binary-extensions@2.2.0",
|
||||
"_resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz"
|
||||
}
|
||||
41
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/readme.md
generated
vendored
Normal file
41
node_modules/.store/binary-extensions@2.2.0/node_modules/binary-extensions/readme.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# binary-extensions
|
||||
|
||||
> List of binary file extensions
|
||||
|
||||
The list is just a [JSON file](binary-extensions.json) and can be used anywhere.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install binary-extensions
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file
|
||||
- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions
|
||||
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<b>
|
||||
<a href="https://tidelift.com/subscription/pkg/npm-binary-extensions?utm_source=npm-binary-extensions&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
|
||||
</b>
|
||||
<br>
|
||||
<sub>
|
||||
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
|
||||
</sub>
|
||||
</div>
|
||||
184
node_modules/.store/braces@3.0.2/node_modules/braces/CHANGELOG.md
generated
vendored
Normal file
184
node_modules/.store/braces@3.0.2/node_modules/braces/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
# Release history
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<details>
|
||||
<summary><strong>Guiding Principles</strong></summary>
|
||||
|
||||
- Changelogs are for humans, not machines.
|
||||
- There should be an entry for every single version.
|
||||
- The same types of changes should be grouped.
|
||||
- Versions and sections should be linkable.
|
||||
- The latest version comes first.
|
||||
- The release date of each versions is displayed.
|
||||
- Mention whether you follow Semantic Versioning.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Types of changes</strong></summary>
|
||||
|
||||
Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_):
|
||||
|
||||
- `Added` for new features.
|
||||
- `Changed` for changes in existing functionality.
|
||||
- `Deprecated` for soon-to-be removed features.
|
||||
- `Removed` for now removed features.
|
||||
- `Fixed` for any bug fixes.
|
||||
- `Security` in case of vulnerabilities.
|
||||
|
||||
</details>
|
||||
|
||||
## [3.0.0] - 2018-04-08
|
||||
|
||||
v3.0 is a complete refactor, resulting in a faster, smaller codebase, with fewer deps, and a more accurate parser and compiler.
|
||||
|
||||
**Breaking Changes**
|
||||
|
||||
- The undocumented `.makeRe` method was removed
|
||||
|
||||
**Non-breaking changes**
|
||||
|
||||
- Caching was removed
|
||||
|
||||
## [2.3.2] - 2018-04-08
|
||||
|
||||
- start refactoring
|
||||
- cover sets
|
||||
- better range handling
|
||||
|
||||
## [2.3.1] - 2018-02-17
|
||||
|
||||
- Remove unnecessary escape in Regex. (#14)
|
||||
|
||||
## [2.3.0] - 2017-10-19
|
||||
|
||||
- minor code reorganization
|
||||
- optimize regex
|
||||
- expose `maxLength` option
|
||||
|
||||
## [2.2.1] - 2017-05-30
|
||||
|
||||
- don't condense when braces contain extglobs
|
||||
|
||||
## [2.2.0] - 2017-05-28
|
||||
|
||||
- ensure word boundaries are preserved
|
||||
- fixes edge case where extglob characters precede a brace pattern
|
||||
|
||||
## [2.1.1] - 2017-04-27
|
||||
|
||||
- use snapdragon-node
|
||||
- handle edge case
|
||||
- optimizations, lint
|
||||
|
||||
## [2.0.4] - 2017-04-11
|
||||
|
||||
- pass opts to compiler
|
||||
- minor optimization in create method
|
||||
- re-write parser handlers to remove negation regex
|
||||
|
||||
## [2.0.3] - 2016-12-10
|
||||
|
||||
- use split-string
|
||||
- clear queue at the end
|
||||
- adds sequences example
|
||||
- add unit tests
|
||||
|
||||
## [2.0.2] - 2016-10-21
|
||||
|
||||
- fix comma handling in nested extglobs
|
||||
|
||||
## [2.0.1] - 2016-10-20
|
||||
|
||||
- add comments
|
||||
- more tests, ensure quotes are stripped
|
||||
|
||||
## [2.0.0] - 2016-10-19
|
||||
|
||||
- don't expand braces inside character classes
|
||||
- add quantifier pattern
|
||||
|
||||
## [1.8.5] - 2016-05-21
|
||||
|
||||
- Refactor (#10)
|
||||
|
||||
## [1.8.4] - 2016-04-20
|
||||
|
||||
- fixes https://github.com/jonschlinkert/micromatch/issues/66
|
||||
|
||||
## [1.8.0] - 2015-03-18
|
||||
|
||||
- adds exponent examples, tests
|
||||
- fixes the first example in https://github.com/jonschlinkert/micromatch/issues/38
|
||||
|
||||
## [1.6.0] - 2015-01-30
|
||||
|
||||
- optimizations, `bash` mode:
|
||||
- improve path escaping
|
||||
|
||||
## [1.5.0] - 2015-01-28
|
||||
|
||||
- Merge pull request #5 from eush77/lib-files
|
||||
|
||||
## [1.4.0] - 2015-01-24
|
||||
|
||||
- add extglob tests
|
||||
- externalize exponent function
|
||||
- better whitespace handling
|
||||
|
||||
## [1.3.0] - 2015-01-24
|
||||
|
||||
- make regex patterns explicity
|
||||
|
||||
## [1.1.0] - 2015-01-11
|
||||
|
||||
- don't create a match group with `makeRe`
|
||||
|
||||
## [1.0.0] - 2014-12-23
|
||||
|
||||
- Merge commit '97b05f5544f8348736a8efaecf5c32bbe3e2ad6e'
|
||||
- support empty brace syntax
|
||||
- better bash coverage
|
||||
- better support for regex strings
|
||||
|
||||
## [0.1.4] - 2014-11-14
|
||||
|
||||
- improve recognition of bad args, recognize mismatched argument types
|
||||
- support escaping
|
||||
- remove pathname-expansion
|
||||
- support whitespace in patterns
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
- first commit
|
||||
|
||||
[2.3.2]: https://github.com/micromatch/braces/compare/2.3.1...2.3.2
|
||||
[2.3.1]: https://github.com/micromatch/braces/compare/2.3.0...2.3.1
|
||||
[2.3.0]: https://github.com/micromatch/braces/compare/2.2.1...2.3.0
|
||||
[2.2.1]: https://github.com/micromatch/braces/compare/2.2.0...2.2.1
|
||||
[2.2.0]: https://github.com/micromatch/braces/compare/2.1.1...2.2.0
|
||||
[2.1.1]: https://github.com/micromatch/braces/compare/2.1.0...2.1.1
|
||||
[2.1.0]: https://github.com/micromatch/braces/compare/2.0.4...2.1.0
|
||||
[2.0.4]: https://github.com/micromatch/braces/compare/2.0.3...2.0.4
|
||||
[2.0.3]: https://github.com/micromatch/braces/compare/2.0.2...2.0.3
|
||||
[2.0.2]: https://github.com/micromatch/braces/compare/2.0.1...2.0.2
|
||||
[2.0.1]: https://github.com/micromatch/braces/compare/2.0.0...2.0.1
|
||||
[2.0.0]: https://github.com/micromatch/braces/compare/1.8.5...2.0.0
|
||||
[1.8.5]: https://github.com/micromatch/braces/compare/1.8.4...1.8.5
|
||||
[1.8.4]: https://github.com/micromatch/braces/compare/1.8.0...1.8.4
|
||||
[1.8.0]: https://github.com/micromatch/braces/compare/1.6.0...1.8.0
|
||||
[1.6.0]: https://github.com/micromatch/braces/compare/1.5.0...1.6.0
|
||||
[1.5.0]: https://github.com/micromatch/braces/compare/1.4.0...1.5.0
|
||||
[1.4.0]: https://github.com/micromatch/braces/compare/1.3.0...1.4.0
|
||||
[1.3.0]: https://github.com/micromatch/braces/compare/1.2.0...1.3.0
|
||||
[1.2.0]: https://github.com/micromatch/braces/compare/1.1.0...1.2.0
|
||||
[1.1.0]: https://github.com/micromatch/braces/compare/1.0.0...1.1.0
|
||||
[1.0.0]: https://github.com/micromatch/braces/compare/0.1.4...1.0.0
|
||||
[0.1.4]: https://github.com/micromatch/braces/compare/0.1.0...0.1.4
|
||||
|
||||
[Unreleased]: https://github.com/micromatch/braces/compare/0.1.0...HEAD
|
||||
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog
|
||||
21
node_modules/.store/braces@3.0.2/node_modules/braces/LICENSE
generated
vendored
Normal file
21
node_modules/.store/braces@3.0.2/node_modules/braces/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2018, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
593
node_modules/.store/braces@3.0.2/node_modules/braces/README.md
generated
vendored
Normal file
593
node_modules/.store/braces@3.0.2/node_modules/braces/README.md
generated
vendored
Normal file
@@ -0,0 +1,593 @@
|
||||
# braces [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/braces) [](https://npmjs.org/package/braces) [](https://npmjs.org/package/braces) [](https://travis-ci.org/micromatch/braces)
|
||||
|
||||
> Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save braces
|
||||
```
|
||||
|
||||
## v3.0.0 Released!!
|
||||
|
||||
See the [changelog](CHANGELOG.md) for details.
|
||||
|
||||
## Why use braces?
|
||||
|
||||
Brace patterns make globs more powerful by adding the ability to match specific ranges and sequences of characters.
|
||||
|
||||
* **Accurate** - complete support for the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/) specification (passes all of the Bash braces tests)
|
||||
* **[fast and performant](#benchmarks)** - Starts fast, runs fast and [scales well](#performance) as patterns increase in complexity.
|
||||
* **Organized code base** - The parser and compiler are easy to maintain and update when edge cases crop up.
|
||||
* **Well-tested** - Thousands of test assertions, and passes all of the Bash, minimatch, and [brace-expansion](https://github.com/juliangruber/brace-expansion) unit tests (as of the date this was written).
|
||||
* **Safer** - You shouldn't have to worry about users defining aggressive or malicious brace patterns that can break your application. Braces takes measures to prevent malicious regex that can be used for DDoS attacks (see [catastrophic backtracking](https://www.regular-expressions.info/catastrophic.html)).
|
||||
* [Supports lists](#lists) - (aka "sets") `a/{b,c}/d` => `['a/b/d', 'a/c/d']`
|
||||
* [Supports sequences](#sequences) - (aka "ranges") `{01..03}` => `['01', '02', '03']`
|
||||
* [Supports steps](#steps) - (aka "increments") `{2..10..2}` => `['2', '4', '6', '8', '10']`
|
||||
* [Supports escaping](#escaping) - To prevent evaluation of special characters.
|
||||
|
||||
## Usage
|
||||
|
||||
The main export is a function that takes one or more brace `patterns` and `options`.
|
||||
|
||||
```js
|
||||
const braces = require('braces');
|
||||
// braces(patterns[, options]);
|
||||
|
||||
console.log(braces(['{01..05}', '{a..e}']));
|
||||
//=> ['(0[1-5])', '([a-e])']
|
||||
|
||||
console.log(braces(['{01..05}', '{a..e}'], { expand: true }));
|
||||
//=> ['01', '02', '03', '04', '05', 'a', 'b', 'c', 'd', 'e']
|
||||
```
|
||||
|
||||
### Brace Expansion vs. Compilation
|
||||
|
||||
By default, brace patterns are compiled into strings that are optimized for creating regular expressions and matching.
|
||||
|
||||
**Compiled**
|
||||
|
||||
```js
|
||||
console.log(braces('a/{x,y,z}/b'));
|
||||
//=> ['a/(x|y|z)/b']
|
||||
console.log(braces(['a/{01..20}/b', 'a/{1..5}/b']));
|
||||
//=> [ 'a/(0[1-9]|1[0-9]|20)/b', 'a/([1-5])/b' ]
|
||||
```
|
||||
|
||||
**Expanded**
|
||||
|
||||
Enable brace expansion by setting the `expand` option to true, or by using [braces.expand()](#expand) (returns an array similar to what you'd expect from Bash, or `echo {1..5}`, or [minimatch](https://github.com/isaacs/minimatch)):
|
||||
|
||||
```js
|
||||
console.log(braces('a/{x,y,z}/b', { expand: true }));
|
||||
//=> ['a/x/b', 'a/y/b', 'a/z/b']
|
||||
|
||||
console.log(braces.expand('{01..10}'));
|
||||
//=> ['01','02','03','04','05','06','07','08','09','10']
|
||||
```
|
||||
|
||||
### Lists
|
||||
|
||||
Expand lists (like Bash "sets"):
|
||||
|
||||
```js
|
||||
console.log(braces('a/{foo,bar,baz}/*.js'));
|
||||
//=> ['a/(foo|bar|baz)/*.js']
|
||||
|
||||
console.log(braces.expand('a/{foo,bar,baz}/*.js'));
|
||||
//=> ['a/foo/*.js', 'a/bar/*.js', 'a/baz/*.js']
|
||||
```
|
||||
|
||||
### Sequences
|
||||
|
||||
Expand ranges of characters (like Bash "sequences"):
|
||||
|
||||
```js
|
||||
console.log(braces.expand('{1..3}')); // ['1', '2', '3']
|
||||
console.log(braces.expand('a/{1..3}/b')); // ['a/1/b', 'a/2/b', 'a/3/b']
|
||||
console.log(braces('{a..c}', { expand: true })); // ['a', 'b', 'c']
|
||||
console.log(braces('foo/{a..c}', { expand: true })); // ['foo/a', 'foo/b', 'foo/c']
|
||||
|
||||
// supports zero-padded ranges
|
||||
console.log(braces('a/{01..03}/b')); //=> ['a/(0[1-3])/b']
|
||||
console.log(braces('a/{001..300}/b')); //=> ['a/(0{2}[1-9]|0[1-9][0-9]|[12][0-9]{2}|300)/b']
|
||||
```
|
||||
|
||||
See [fill-range](https://github.com/jonschlinkert/fill-range) for all available range-expansion options.
|
||||
|
||||
### Steppped ranges
|
||||
|
||||
Steps, or increments, may be used with ranges:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('{2..10..2}'));
|
||||
//=> ['2', '4', '6', '8', '10']
|
||||
|
||||
console.log(braces('{2..10..2}'));
|
||||
//=> ['(2|4|6|8|10)']
|
||||
```
|
||||
|
||||
When the [.optimize](#optimize) method is used, or [options.optimize](#optionsoptimize) is set to true, sequences are passed to [to-regex-range](https://github.com/jonschlinkert/to-regex-range) for expansion.
|
||||
|
||||
### Nesting
|
||||
|
||||
Brace patterns may be nested. The results of each expanded string are not sorted, and left to right order is preserved.
|
||||
|
||||
**"Expanded" braces**
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b,c,/{x,y}}/e'));
|
||||
//=> ['ab/e', 'ac/e', 'a/x/e', 'a/y/e']
|
||||
|
||||
console.log(braces.expand('a/{x,{1..5},y}/c'));
|
||||
//=> ['a/x/c', 'a/1/c', 'a/2/c', 'a/3/c', 'a/4/c', 'a/5/c', 'a/y/c']
|
||||
```
|
||||
|
||||
**"Optimized" braces**
|
||||
|
||||
```js
|
||||
console.log(braces('a{b,c,/{x,y}}/e'));
|
||||
//=> ['a(b|c|/(x|y))/e']
|
||||
|
||||
console.log(braces('a/{x,{1..5},y}/c'));
|
||||
//=> ['a/(x|([1-5])|y)/c']
|
||||
```
|
||||
|
||||
### Escaping
|
||||
|
||||
**Escaping braces**
|
||||
|
||||
A brace pattern will not be expanded or evaluted if _either the opening or closing brace is escaped_:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a\\{d,c,b}e'));
|
||||
//=> ['a{d,c,b}e']
|
||||
|
||||
console.log(braces.expand('a{d,c,b\\}e'));
|
||||
//=> ['a{d,c,b}e']
|
||||
```
|
||||
|
||||
**Escaping commas**
|
||||
|
||||
Commas inside braces may also be escaped:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b\\,c}d'));
|
||||
//=> ['a{b,c}d']
|
||||
|
||||
console.log(braces.expand('a{d\\,c,b}e'));
|
||||
//=> ['ad,ce', 'abe']
|
||||
```
|
||||
|
||||
**Single items**
|
||||
|
||||
Following bash conventions, a brace pattern is also not expanded when it contains a single character:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b}c'));
|
||||
//=> ['a{b}c']
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### options.maxLength
|
||||
|
||||
**Type**: `Number`
|
||||
|
||||
**Default**: `65,536`
|
||||
|
||||
**Description**: Limit the length of the input string. Useful when the input string is generated or your application allows users to pass a string, et cetera.
|
||||
|
||||
```js
|
||||
console.log(braces('a/{b,c}/d', { maxLength: 3 })); //=> throws an error
|
||||
```
|
||||
|
||||
### options.expand
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Generate an "expanded" brace pattern (alternatively you can use the `braces.expand()` method, which does the same thing).
|
||||
|
||||
```js
|
||||
console.log(braces('a/{b,c}/d', { expand: true }));
|
||||
//=> [ 'a/b/d', 'a/c/d' ]
|
||||
```
|
||||
|
||||
### options.nodupes
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Remove duplicates from the returned array.
|
||||
|
||||
### options.rangeLimit
|
||||
|
||||
**Type**: `Number`
|
||||
|
||||
**Default**: `1000`
|
||||
|
||||
**Description**: To prevent malicious patterns from being passed by users, an error is thrown when `braces.expand()` is used or `options.expand` is true and the generated range will exceed the `rangeLimit`.
|
||||
|
||||
You can customize `options.rangeLimit` or set it to `Inifinity` to disable this altogether.
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
// pattern exceeds the "rangeLimit", so it's optimized automatically
|
||||
console.log(braces.expand('{1..1000}'));
|
||||
//=> ['([1-9]|[1-9][0-9]{1,2}|1000)']
|
||||
|
||||
// pattern does not exceed "rangeLimit", so it's NOT optimized
|
||||
console.log(braces.expand('{1..100}'));
|
||||
//=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100']
|
||||
```
|
||||
|
||||
### options.transform
|
||||
|
||||
**Type**: `Function`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Customize range expansion.
|
||||
|
||||
**Example: Transforming non-numeric values**
|
||||
|
||||
```js
|
||||
const alpha = braces.expand('x/{a..e}/y', {
|
||||
transform(value, index) {
|
||||
// When non-numeric values are passed, "value" is a character code.
|
||||
return 'foo/' + String.fromCharCode(value) + '-' + index;
|
||||
}
|
||||
});
|
||||
console.log(alpha);
|
||||
//=> [ 'x/foo/a-0/y', 'x/foo/b-1/y', 'x/foo/c-2/y', 'x/foo/d-3/y', 'x/foo/e-4/y' ]
|
||||
```
|
||||
|
||||
**Example: Transforming numeric values**
|
||||
|
||||
```js
|
||||
const numeric = braces.expand('{1..5}', {
|
||||
transform(value) {
|
||||
// when numeric values are passed, "value" is a number
|
||||
return 'foo/' + value * 2;
|
||||
}
|
||||
});
|
||||
console.log(numeric);
|
||||
//=> [ 'foo/2', 'foo/4', 'foo/6', 'foo/8', 'foo/10' ]
|
||||
```
|
||||
|
||||
### options.quantifiers
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: In regular expressions, quanitifiers can be used to specify how many times a token can be repeated. For example, `a{1,3}` will match the letter `a` one to three times.
|
||||
|
||||
Unfortunately, regex quantifiers happen to share the same syntax as [Bash lists](#lists)
|
||||
|
||||
The `quantifiers` option tells braces to detect when [regex quantifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#quantifiers) are defined in the given pattern, and not to try to expand them as lists.
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
const braces = require('braces');
|
||||
console.log(braces('a/b{1,3}/{x,y,z}'));
|
||||
//=> [ 'a/b(1|3)/(x|y|z)' ]
|
||||
console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true}));
|
||||
//=> [ 'a/b{1,3}/(x|y|z)' ]
|
||||
console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true, expand: true}));
|
||||
//=> [ 'a/b{1,3}/x', 'a/b{1,3}/y', 'a/b{1,3}/z' ]
|
||||
```
|
||||
|
||||
### options.unescape
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Strip backslashes that were used for escaping from the result.
|
||||
|
||||
## What is "brace expansion"?
|
||||
|
||||
Brace expansion is a type of parameter expansion that was made popular by unix shells for generating lists of strings, as well as regex-like matching when used alongside wildcards (globs).
|
||||
|
||||
In addition to "expansion", braces are also used for matching. In other words:
|
||||
|
||||
* [brace expansion](#brace-expansion) is for generating new lists
|
||||
* [brace matching](#brace-matching) is for filtering existing lists
|
||||
|
||||
<details>
|
||||
<summary><strong>More about brace expansion</strong> (click to expand)</summary>
|
||||
|
||||
There are two main types of brace expansion:
|
||||
|
||||
1. **lists**: which are defined using comma-separated values inside curly braces: `{a,b,c}`
|
||||
2. **sequences**: which are defined using a starting value and an ending value, separated by two dots: `a{1..3}b`. Optionally, a third argument may be passed to define a "step" or increment to use: `a{1..100..10}b`. These are also sometimes referred to as "ranges".
|
||||
|
||||
Here are some example brace patterns to illustrate how they work:
|
||||
|
||||
**Sets**
|
||||
|
||||
```
|
||||
{a,b,c} => a b c
|
||||
{a,b,c}{1,2} => a1 a2 b1 b2 c1 c2
|
||||
```
|
||||
|
||||
**Sequences**
|
||||
|
||||
```
|
||||
{1..9} => 1 2 3 4 5 6 7 8 9
|
||||
{4..-4} => 4 3 2 1 0 -1 -2 -3 -4
|
||||
{1..20..3} => 1 4 7 10 13 16 19
|
||||
{a..j} => a b c d e f g h i j
|
||||
{j..a} => j i h g f e d c b a
|
||||
{a..z..3} => a d g j m p s v y
|
||||
```
|
||||
|
||||
**Combination**
|
||||
|
||||
Sets and sequences can be mixed together or used along with any other strings.
|
||||
|
||||
```
|
||||
{a,b,c}{1..3} => a1 a2 a3 b1 b2 b3 c1 c2 c3
|
||||
foo/{a,b,c}/bar => foo/a/bar foo/b/bar foo/c/bar
|
||||
```
|
||||
|
||||
The fact that braces can be "expanded" from relatively simple patterns makes them ideal for quickly generating test fixtures, file paths, and similar use cases.
|
||||
|
||||
## Brace matching
|
||||
|
||||
In addition to _expansion_, brace patterns are also useful for performing regular-expression-like matching.
|
||||
|
||||
For example, the pattern `foo/{1..3}/bar` would match any of following strings:
|
||||
|
||||
```
|
||||
foo/1/bar
|
||||
foo/2/bar
|
||||
foo/3/bar
|
||||
```
|
||||
|
||||
But not:
|
||||
|
||||
```
|
||||
baz/1/qux
|
||||
baz/2/qux
|
||||
baz/3/qux
|
||||
```
|
||||
|
||||
Braces can also be combined with [glob patterns](https://github.com/jonschlinkert/micromatch) to perform more advanced wildcard matching. For example, the pattern `*/{1..3}/*` would match any of following strings:
|
||||
|
||||
```
|
||||
foo/1/bar
|
||||
foo/2/bar
|
||||
foo/3/bar
|
||||
baz/1/qux
|
||||
baz/2/qux
|
||||
baz/3/qux
|
||||
```
|
||||
|
||||
## Brace matching pitfalls
|
||||
|
||||
Although brace patterns offer a user-friendly way of matching ranges or sets of strings, there are also some major disadvantages and potential risks you should be aware of.
|
||||
|
||||
### tldr
|
||||
|
||||
**"brace bombs"**
|
||||
|
||||
* brace expansion can eat up a huge amount of processing resources
|
||||
* as brace patterns increase _linearly in size_, the system resources required to expand the pattern increase exponentially
|
||||
* users can accidentally (or intentially) exhaust your system's resources resulting in the equivalent of a DoS attack (bonus: no programming knowledge is required!)
|
||||
|
||||
For a more detailed explanation with examples, see the [geometric complexity](#geometric-complexity) section.
|
||||
|
||||
### The solution
|
||||
|
||||
Jump to the [performance section](#performance) to see how Braces solves this problem in comparison to other libraries.
|
||||
|
||||
### Geometric complexity
|
||||
|
||||
At minimum, brace patterns with sets limited to two elements have quadradic or `O(n^2)` complexity. But the complexity of the algorithm increases exponentially as the number of sets, _and elements per set_, increases, which is `O(n^c)`.
|
||||
|
||||
For example, the following sets demonstrate quadratic (`O(n^2)`) complexity:
|
||||
|
||||
```
|
||||
{1,2}{3,4} => (2X2) => 13 14 23 24
|
||||
{1,2}{3,4}{5,6} => (2X2X2) => 135 136 145 146 235 236 245 246
|
||||
```
|
||||
|
||||
But add an element to a set, and we get a n-fold Cartesian product with `O(n^c)` complexity:
|
||||
|
||||
```
|
||||
{1,2,3}{4,5,6}{7,8,9} => (3X3X3) => 147 148 149 157 158 159 167 168 169 247 248
|
||||
249 257 258 259 267 268 269 347 348 349 357
|
||||
358 359 367 368 369
|
||||
```
|
||||
|
||||
Now, imagine how this complexity grows given that each element is a n-tuple:
|
||||
|
||||
```
|
||||
{1..100}{1..100} => (100X100) => 10,000 elements (38.4 kB)
|
||||
{1..100}{1..100}{1..100} => (100X100X100) => 1,000,000 elements (5.76 MB)
|
||||
```
|
||||
|
||||
Although these examples are clearly contrived, they demonstrate how brace patterns can quickly grow out of control.
|
||||
|
||||
**More information**
|
||||
|
||||
Interested in learning more about brace expansion?
|
||||
|
||||
* [linuxjournal/bash-brace-expansion](http://www.linuxjournal.com/content/bash-brace-expansion)
|
||||
* [rosettacode/Brace_expansion](https://rosettacode.org/wiki/Brace_expansion)
|
||||
* [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product)
|
||||
|
||||
</details>
|
||||
|
||||
## Performance
|
||||
|
||||
Braces is not only screaming fast, it's also more accurate the other brace expansion libraries.
|
||||
|
||||
### Better algorithms
|
||||
|
||||
Fortunately there is a solution to the ["brace bomb" problem](#brace-matching-pitfalls): _don't expand brace patterns into an array when they're used for matching_.
|
||||
|
||||
Instead, convert the pattern into an optimized regular expression. This is easier said than done, and braces is the only library that does this currently.
|
||||
|
||||
**The proof is in the numbers**
|
||||
|
||||
Minimatch gets exponentially slower as patterns increase in complexity, braces does not. The following results were generated using `braces()` and `minimatch.braceExpand()`, respectively.
|
||||
|
||||
| **Pattern** | **braces** | **[minimatch][]** |
|
||||
| --- | --- | --- |
|
||||
| `{1..9007199254740991}`[^1] | `298 B` (5ms 459μs)| N/A (freezes) |
|
||||
| `{1..1000000000000000}` | `41 B` (1ms 15μs) | N/A (freezes) |
|
||||
| `{1..100000000000000}` | `40 B` (890μs) | N/A (freezes) |
|
||||
| `{1..10000000000000}` | `39 B` (2ms 49μs) | N/A (freezes) |
|
||||
| `{1..1000000000000}` | `38 B` (608μs) | N/A (freezes) |
|
||||
| `{1..100000000000}` | `37 B` (397μs) | N/A (freezes) |
|
||||
| `{1..10000000000}` | `35 B` (983μs) | N/A (freezes) |
|
||||
| `{1..1000000000}` | `34 B` (798μs) | N/A (freezes) |
|
||||
| `{1..100000000}` | `33 B` (733μs) | N/A (freezes) |
|
||||
| `{1..10000000}` | `32 B` (5ms 632μs) | `78.89 MB` (16s 388ms 569μs) |
|
||||
| `{1..1000000}` | `31 B` (1ms 381μs) | `6.89 MB` (1s 496ms 887μs) |
|
||||
| `{1..100000}` | `30 B` (950μs) | `588.89 kB` (146ms 921μs) |
|
||||
| `{1..10000}` | `29 B` (1ms 114μs) | `48.89 kB` (14ms 187μs) |
|
||||
| `{1..1000}` | `28 B` (760μs) | `3.89 kB` (1ms 453μs) |
|
||||
| `{1..100}` | `22 B` (345μs) | `291 B` (196μs) |
|
||||
| `{1..10}` | `10 B` (533μs) | `20 B` (37μs) |
|
||||
| `{1..3}` | `7 B` (190μs) | `5 B` (27μs) |
|
||||
|
||||
### Faster algorithms
|
||||
|
||||
When you need expansion, braces is still much faster.
|
||||
|
||||
_(the following results were generated using `braces.expand()` and `minimatch.braceExpand()`, respectively)_
|
||||
|
||||
| **Pattern** | **braces** | **[minimatch][]** |
|
||||
| --- | --- | --- |
|
||||
| `{1..10000000}` | `78.89 MB` (2s 698ms 642μs) | `78.89 MB` (18s 601ms 974μs) |
|
||||
| `{1..1000000}` | `6.89 MB` (458ms 576μs) | `6.89 MB` (1s 491ms 621μs) |
|
||||
| `{1..100000}` | `588.89 kB` (20ms 728μs) | `588.89 kB` (156ms 919μs) |
|
||||
| `{1..10000}` | `48.89 kB` (2ms 202μs) | `48.89 kB` (13ms 641μs) |
|
||||
| `{1..1000}` | `3.89 kB` (1ms 796μs) | `3.89 kB` (1ms 958μs) |
|
||||
| `{1..100}` | `291 B` (424μs) | `291 B` (211μs) |
|
||||
| `{1..10}` | `20 B` (487μs) | `20 B` (72μs) |
|
||||
| `{1..3}` | `5 B` (166μs) | `5 B` (27μs) |
|
||||
|
||||
If you'd like to run these comparisons yourself, see [test/support/generate.js](test/support/generate.js).
|
||||
|
||||
## Benchmarks
|
||||
|
||||
### Running benchmarks
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm benchmark
|
||||
```
|
||||
|
||||
### Latest results
|
||||
|
||||
Braces is more accurate, without sacrificing performance.
|
||||
|
||||
```bash
|
||||
# range (expanded)
|
||||
braces x 29,040 ops/sec ±3.69% (91 runs sampled))
|
||||
minimatch x 4,735 ops/sec ±1.28% (90 runs sampled)
|
||||
|
||||
# range (optimized for regex)
|
||||
braces x 382,878 ops/sec ±0.56% (94 runs sampled)
|
||||
minimatch x 1,040 ops/sec ±0.44% (93 runs sampled)
|
||||
|
||||
# nested ranges (expanded)
|
||||
braces x 19,744 ops/sec ±2.27% (92 runs sampled))
|
||||
minimatch x 4,579 ops/sec ±0.50% (93 runs sampled)
|
||||
|
||||
# nested ranges (optimized for regex)
|
||||
braces x 246,019 ops/sec ±2.02% (93 runs sampled)
|
||||
minimatch x 1,028 ops/sec ±0.39% (94 runs sampled)
|
||||
|
||||
# set (expanded)
|
||||
braces x 138,641 ops/sec ±0.53% (95 runs sampled)
|
||||
minimatch x 219,582 ops/sec ±0.98% (94 runs sampled)
|
||||
|
||||
# set (optimized for regex)
|
||||
braces x 388,408 ops/sec ±0.41% (95 runs sampled)
|
||||
minimatch x 44,724 ops/sec ±0.91% (89 runs sampled)
|
||||
|
||||
# nested sets (expanded)
|
||||
braces x 84,966 ops/sec ±0.48% (94 runs sampled)
|
||||
minimatch x 140,720 ops/sec ±0.37% (95 runs sampled)
|
||||
|
||||
# nested sets (optimized for regex)
|
||||
braces x 263,340 ops/sec ±2.06% (92 runs sampled)
|
||||
minimatch x 28,714 ops/sec ±0.40% (90 runs sampled)
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 197 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 4 | [doowb](https://github.com/doowb) |
|
||||
| 1 | [es128](https://github.com/es128) |
|
||||
| 1 | [eush77](https://github.com/eush77) |
|
||||
| 1 | [hemanth](https://github.com/hemanth) |
|
||||
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._
|
||||
170
node_modules/.store/braces@3.0.2/node_modules/braces/index.js
generated
vendored
Normal file
170
node_modules/.store/braces@3.0.2/node_modules/braces/index.js
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
const stringify = require('./lib/stringify');
|
||||
const compile = require('./lib/compile');
|
||||
const expand = require('./lib/expand');
|
||||
const parse = require('./lib/parse');
|
||||
|
||||
/**
|
||||
* Expand the given pattern or create a regex-compatible string.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
|
||||
* console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
|
||||
* ```
|
||||
* @param {String} `str`
|
||||
* @param {Object} `options`
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
const braces = (input, options = {}) => {
|
||||
let output = [];
|
||||
|
||||
if (Array.isArray(input)) {
|
||||
for (let pattern of input) {
|
||||
let result = braces.create(pattern, options);
|
||||
if (Array.isArray(result)) {
|
||||
output.push(...result);
|
||||
} else {
|
||||
output.push(result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output = [].concat(braces.create(input, options));
|
||||
}
|
||||
|
||||
if (options && options.expand === true && options.nodupes === true) {
|
||||
output = [...new Set(output)];
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` with the given `options`.
|
||||
*
|
||||
* ```js
|
||||
* // braces.parse(pattern, [, options]);
|
||||
* const ast = braces.parse('a/{b,c}/d');
|
||||
* console.log(ast);
|
||||
* ```
|
||||
* @param {String} pattern Brace pattern to parse
|
||||
* @param {Object} options
|
||||
* @return {Object} Returns an AST
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.parse = (input, options = {}) => parse(input, options);
|
||||
|
||||
/**
|
||||
* Creates a braces string from an AST, or an AST node.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* let ast = braces.parse('foo/{a,b}/bar');
|
||||
* console.log(stringify(ast.nodes[2])); //=> '{a,b}'
|
||||
* ```
|
||||
* @param {String} `input` Brace pattern or AST.
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.stringify = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
return stringify(braces.parse(input, options), options);
|
||||
}
|
||||
return stringify(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Compiles a brace pattern into a regex-compatible, optimized string.
|
||||
* This method is called by the main [braces](#braces) function by default.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.compile('a/{b,c}/d'));
|
||||
* //=> ['a/(b|c)/d']
|
||||
* ```
|
||||
* @param {String} `input` Brace pattern or AST.
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.compile = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
input = braces.parse(input, options);
|
||||
}
|
||||
return compile(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expands a brace pattern into an array. This method is called by the
|
||||
* main [braces](#braces) function when `options.expand` is true. Before
|
||||
* using this method it's recommended that you read the [performance notes](#performance))
|
||||
* and advantages of using [.compile](#compile) instead.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.expand('a/{b,c}/d'));
|
||||
* //=> ['a/b/d', 'a/c/d'];
|
||||
* ```
|
||||
* @param {String} `pattern` Brace pattern
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.expand = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
input = braces.parse(input, options);
|
||||
}
|
||||
|
||||
let result = expand(input, options);
|
||||
|
||||
// filter out empty strings if specified
|
||||
if (options.noempty === true) {
|
||||
result = result.filter(Boolean);
|
||||
}
|
||||
|
||||
// filter out duplicates if specified
|
||||
if (options.nodupes === true) {
|
||||
result = [...new Set(result)];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes a brace pattern and returns either an expanded array
|
||||
* (if `options.expand` is true), a highly optimized regex-compatible string.
|
||||
* This method is called by the main [braces](#braces) function.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
|
||||
* //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
|
||||
* ```
|
||||
* @param {String} `pattern` Brace pattern
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.create = (input, options = {}) => {
|
||||
if (input === '' || input.length < 3) {
|
||||
return [input];
|
||||
}
|
||||
|
||||
return options.expand !== true
|
||||
? braces.compile(input, options)
|
||||
: braces.expand(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose "braces"
|
||||
*/
|
||||
|
||||
module.exports = braces;
|
||||
57
node_modules/.store/braces@3.0.2/node_modules/braces/lib/compile.js
generated
vendored
Normal file
57
node_modules/.store/braces@3.0.2/node_modules/braces/lib/compile.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
const fill = require('fill-range');
|
||||
const utils = require('./utils');
|
||||
|
||||
const compile = (ast, options = {}) => {
|
||||
let walk = (node, parent = {}) => {
|
||||
let invalidBlock = utils.isInvalidBrace(parent);
|
||||
let invalidNode = node.invalid === true && options.escapeInvalid === true;
|
||||
let invalid = invalidBlock === true || invalidNode === true;
|
||||
let prefix = options.escapeInvalid === true ? '\\' : '';
|
||||
let output = '';
|
||||
|
||||
if (node.isOpen === true) {
|
||||
return prefix + node.value;
|
||||
}
|
||||
if (node.isClose === true) {
|
||||
return prefix + node.value;
|
||||
}
|
||||
|
||||
if (node.type === 'open') {
|
||||
return invalid ? (prefix + node.value) : '(';
|
||||
}
|
||||
|
||||
if (node.type === 'close') {
|
||||
return invalid ? (prefix + node.value) : ')';
|
||||
}
|
||||
|
||||
if (node.type === 'comma') {
|
||||
return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|');
|
||||
}
|
||||
|
||||
if (node.value) {
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.nodes && node.ranges > 0) {
|
||||
let args = utils.reduce(node.nodes);
|
||||
let range = fill(...args, { ...options, wrap: false, toRegex: true });
|
||||
|
||||
if (range.length !== 0) {
|
||||
return args.length > 1 && range.length > 1 ? `(${range})` : range;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.nodes) {
|
||||
for (let child of node.nodes) {
|
||||
output += walk(child, node);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
return walk(ast);
|
||||
};
|
||||
|
||||
module.exports = compile;
|
||||
57
node_modules/.store/braces@3.0.2/node_modules/braces/lib/constants.js
generated
vendored
Normal file
57
node_modules/.store/braces@3.0.2/node_modules/braces/lib/constants.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
MAX_LENGTH: 1024 * 64,
|
||||
|
||||
// Digits
|
||||
CHAR_0: '0', /* 0 */
|
||||
CHAR_9: '9', /* 9 */
|
||||
|
||||
// Alphabet chars.
|
||||
CHAR_UPPERCASE_A: 'A', /* A */
|
||||
CHAR_LOWERCASE_A: 'a', /* a */
|
||||
CHAR_UPPERCASE_Z: 'Z', /* Z */
|
||||
CHAR_LOWERCASE_Z: 'z', /* z */
|
||||
|
||||
CHAR_LEFT_PARENTHESES: '(', /* ( */
|
||||
CHAR_RIGHT_PARENTHESES: ')', /* ) */
|
||||
|
||||
CHAR_ASTERISK: '*', /* * */
|
||||
|
||||
// Non-alphabetic chars.
|
||||
CHAR_AMPERSAND: '&', /* & */
|
||||
CHAR_AT: '@', /* @ */
|
||||
CHAR_BACKSLASH: '\\', /* \ */
|
||||
CHAR_BACKTICK: '`', /* ` */
|
||||
CHAR_CARRIAGE_RETURN: '\r', /* \r */
|
||||
CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
|
||||
CHAR_COLON: ':', /* : */
|
||||
CHAR_COMMA: ',', /* , */
|
||||
CHAR_DOLLAR: '$', /* . */
|
||||
CHAR_DOT: '.', /* . */
|
||||
CHAR_DOUBLE_QUOTE: '"', /* " */
|
||||
CHAR_EQUAL: '=', /* = */
|
||||
CHAR_EXCLAMATION_MARK: '!', /* ! */
|
||||
CHAR_FORM_FEED: '\f', /* \f */
|
||||
CHAR_FORWARD_SLASH: '/', /* / */
|
||||
CHAR_HASH: '#', /* # */
|
||||
CHAR_HYPHEN_MINUS: '-', /* - */
|
||||
CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
|
||||
CHAR_LEFT_CURLY_BRACE: '{', /* { */
|
||||
CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
|
||||
CHAR_LINE_FEED: '\n', /* \n */
|
||||
CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
|
||||
CHAR_PERCENT: '%', /* % */
|
||||
CHAR_PLUS: '+', /* + */
|
||||
CHAR_QUESTION_MARK: '?', /* ? */
|
||||
CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
|
||||
CHAR_RIGHT_CURLY_BRACE: '}', /* } */
|
||||
CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
|
||||
CHAR_SEMICOLON: ';', /* ; */
|
||||
CHAR_SINGLE_QUOTE: '\'', /* ' */
|
||||
CHAR_SPACE: ' ', /* */
|
||||
CHAR_TAB: '\t', /* \t */
|
||||
CHAR_UNDERSCORE: '_', /* _ */
|
||||
CHAR_VERTICAL_LINE: '|', /* | */
|
||||
CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
|
||||
};
|
||||
113
node_modules/.store/braces@3.0.2/node_modules/braces/lib/expand.js
generated
vendored
Normal file
113
node_modules/.store/braces@3.0.2/node_modules/braces/lib/expand.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
const fill = require('fill-range');
|
||||
const stringify = require('./stringify');
|
||||
const utils = require('./utils');
|
||||
|
||||
const append = (queue = '', stash = '', enclose = false) => {
|
||||
let result = [];
|
||||
|
||||
queue = [].concat(queue);
|
||||
stash = [].concat(stash);
|
||||
|
||||
if (!stash.length) return queue;
|
||||
if (!queue.length) {
|
||||
return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
|
||||
}
|
||||
|
||||
for (let item of queue) {
|
||||
if (Array.isArray(item)) {
|
||||
for (let value of item) {
|
||||
result.push(append(value, stash, enclose));
|
||||
}
|
||||
} else {
|
||||
for (let ele of stash) {
|
||||
if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
|
||||
result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
|
||||
}
|
||||
}
|
||||
}
|
||||
return utils.flatten(result);
|
||||
};
|
||||
|
||||
const expand = (ast, options = {}) => {
|
||||
let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
|
||||
|
||||
let walk = (node, parent = {}) => {
|
||||
node.queue = [];
|
||||
|
||||
let p = parent;
|
||||
let q = parent.queue;
|
||||
|
||||
while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
|
||||
p = p.parent;
|
||||
q = p.queue;
|
||||
}
|
||||
|
||||
if (node.invalid || node.dollar) {
|
||||
q.push(append(q.pop(), stringify(node, options)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
|
||||
q.push(append(q.pop(), ['{}']));
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.nodes && node.ranges > 0) {
|
||||
let args = utils.reduce(node.nodes);
|
||||
|
||||
if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
|
||||
throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
|
||||
}
|
||||
|
||||
let range = fill(...args, options);
|
||||
if (range.length === 0) {
|
||||
range = stringify(node, options);
|
||||
}
|
||||
|
||||
q.push(append(q.pop(), range));
|
||||
node.nodes = [];
|
||||
return;
|
||||
}
|
||||
|
||||
let enclose = utils.encloseBrace(node);
|
||||
let queue = node.queue;
|
||||
let block = node;
|
||||
|
||||
while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
|
||||
block = block.parent;
|
||||
queue = block.queue;
|
||||
}
|
||||
|
||||
for (let i = 0; i < node.nodes.length; i++) {
|
||||
let child = node.nodes[i];
|
||||
|
||||
if (child.type === 'comma' && node.type === 'brace') {
|
||||
if (i === 1) queue.push('');
|
||||
queue.push('');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.type === 'close') {
|
||||
q.push(append(q.pop(), queue, enclose));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.value && child.type !== 'open') {
|
||||
queue.push(append(queue.pop(), child.value));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.nodes) {
|
||||
walk(child, node);
|
||||
}
|
||||
}
|
||||
|
||||
return queue;
|
||||
};
|
||||
|
||||
return utils.flatten(walk(ast));
|
||||
};
|
||||
|
||||
module.exports = expand;
|
||||
333
node_modules/.store/braces@3.0.2/node_modules/braces/lib/parse.js
generated
vendored
Normal file
333
node_modules/.store/braces@3.0.2/node_modules/braces/lib/parse.js
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
'use strict';
|
||||
|
||||
const stringify = require('./stringify');
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const {
|
||||
MAX_LENGTH,
|
||||
CHAR_BACKSLASH, /* \ */
|
||||
CHAR_BACKTICK, /* ` */
|
||||
CHAR_COMMA, /* , */
|
||||
CHAR_DOT, /* . */
|
||||
CHAR_LEFT_PARENTHESES, /* ( */
|
||||
CHAR_RIGHT_PARENTHESES, /* ) */
|
||||
CHAR_LEFT_CURLY_BRACE, /* { */
|
||||
CHAR_RIGHT_CURLY_BRACE, /* } */
|
||||
CHAR_LEFT_SQUARE_BRACKET, /* [ */
|
||||
CHAR_RIGHT_SQUARE_BRACKET, /* ] */
|
||||
CHAR_DOUBLE_QUOTE, /* " */
|
||||
CHAR_SINGLE_QUOTE, /* ' */
|
||||
CHAR_NO_BREAK_SPACE,
|
||||
CHAR_ZERO_WIDTH_NOBREAK_SPACE
|
||||
} = require('./constants');
|
||||
|
||||
/**
|
||||
* parse
|
||||
*/
|
||||
|
||||
const parse = (input, options = {}) => {
|
||||
if (typeof input !== 'string') {
|
||||
throw new TypeError('Expected a string');
|
||||
}
|
||||
|
||||
let opts = options || {};
|
||||
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
|
||||
if (input.length > max) {
|
||||
throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
|
||||
}
|
||||
|
||||
let ast = { type: 'root', input, nodes: [] };
|
||||
let stack = [ast];
|
||||
let block = ast;
|
||||
let prev = ast;
|
||||
let brackets = 0;
|
||||
let length = input.length;
|
||||
let index = 0;
|
||||
let depth = 0;
|
||||
let value;
|
||||
let memo = {};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
const advance = () => input[index++];
|
||||
const push = node => {
|
||||
if (node.type === 'text' && prev.type === 'dot') {
|
||||
prev.type = 'text';
|
||||
}
|
||||
|
||||
if (prev && prev.type === 'text' && node.type === 'text') {
|
||||
prev.value += node.value;
|
||||
return;
|
||||
}
|
||||
|
||||
block.nodes.push(node);
|
||||
node.parent = block;
|
||||
node.prev = prev;
|
||||
prev = node;
|
||||
return node;
|
||||
};
|
||||
|
||||
push({ type: 'bos' });
|
||||
|
||||
while (index < length) {
|
||||
block = stack[stack.length - 1];
|
||||
value = advance();
|
||||
|
||||
/**
|
||||
* Invalid chars
|
||||
*/
|
||||
|
||||
if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escaped chars
|
||||
*/
|
||||
|
||||
if (value === CHAR_BACKSLASH) {
|
||||
push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right square bracket (literal): ']'
|
||||
*/
|
||||
|
||||
if (value === CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
push({ type: 'text', value: '\\' + value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left square bracket: '['
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_SQUARE_BRACKET) {
|
||||
brackets++;
|
||||
|
||||
let closed = true;
|
||||
let next;
|
||||
|
||||
while (index < length && (next = advance())) {
|
||||
value += next;
|
||||
|
||||
if (next === CHAR_LEFT_SQUARE_BRACKET) {
|
||||
brackets++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === CHAR_BACKSLASH) {
|
||||
value += advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
brackets--;
|
||||
|
||||
if (brackets === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parentheses
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_PARENTHESES) {
|
||||
block = push({ type: 'paren', nodes: [] });
|
||||
stack.push(block);
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value === CHAR_RIGHT_PARENTHESES) {
|
||||
if (block.type !== 'paren') {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
block = stack.pop();
|
||||
push({ type: 'text', value });
|
||||
block = stack[stack.length - 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes: '|"|`
|
||||
*/
|
||||
|
||||
if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
|
||||
let open = value;
|
||||
let next;
|
||||
|
||||
if (options.keepQuotes !== true) {
|
||||
value = '';
|
||||
}
|
||||
|
||||
while (index < length && (next = advance())) {
|
||||
if (next === CHAR_BACKSLASH) {
|
||||
value += next + advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === open) {
|
||||
if (options.keepQuotes === true) value += next;
|
||||
break;
|
||||
}
|
||||
|
||||
value += next;
|
||||
}
|
||||
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left curly brace: '{'
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_CURLY_BRACE) {
|
||||
depth++;
|
||||
|
||||
let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
|
||||
let brace = {
|
||||
type: 'brace',
|
||||
open: true,
|
||||
close: false,
|
||||
dollar,
|
||||
depth,
|
||||
commas: 0,
|
||||
ranges: 0,
|
||||
nodes: []
|
||||
};
|
||||
|
||||
block = push(brace);
|
||||
stack.push(block);
|
||||
push({ type: 'open', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right curly brace: '}'
|
||||
*/
|
||||
|
||||
if (value === CHAR_RIGHT_CURLY_BRACE) {
|
||||
if (block.type !== 'brace') {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
let type = 'close';
|
||||
block = stack.pop();
|
||||
block.close = true;
|
||||
|
||||
push({ type, value });
|
||||
depth--;
|
||||
|
||||
block = stack[stack.length - 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comma: ','
|
||||
*/
|
||||
|
||||
if (value === CHAR_COMMA && depth > 0) {
|
||||
if (block.ranges > 0) {
|
||||
block.ranges = 0;
|
||||
let open = block.nodes.shift();
|
||||
block.nodes = [open, { type: 'text', value: stringify(block) }];
|
||||
}
|
||||
|
||||
push({ type: 'comma', value });
|
||||
block.commas++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dot: '.'
|
||||
*/
|
||||
|
||||
if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
|
||||
let siblings = block.nodes;
|
||||
|
||||
if (depth === 0 || siblings.length === 0) {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.type === 'dot') {
|
||||
block.range = [];
|
||||
prev.value += value;
|
||||
prev.type = 'range';
|
||||
|
||||
if (block.nodes.length !== 3 && block.nodes.length !== 5) {
|
||||
block.invalid = true;
|
||||
block.ranges = 0;
|
||||
prev.type = 'text';
|
||||
continue;
|
||||
}
|
||||
|
||||
block.ranges++;
|
||||
block.args = [];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.type === 'range') {
|
||||
siblings.pop();
|
||||
|
||||
let before = siblings[siblings.length - 1];
|
||||
before.value += prev.value + value;
|
||||
prev = before;
|
||||
block.ranges--;
|
||||
continue;
|
||||
}
|
||||
|
||||
push({ type: 'dot', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text
|
||||
*/
|
||||
|
||||
push({ type: 'text', value });
|
||||
}
|
||||
|
||||
// Mark imbalanced braces and brackets as invalid
|
||||
do {
|
||||
block = stack.pop();
|
||||
|
||||
if (block.type !== 'root') {
|
||||
block.nodes.forEach(node => {
|
||||
if (!node.nodes) {
|
||||
if (node.type === 'open') node.isOpen = true;
|
||||
if (node.type === 'close') node.isClose = true;
|
||||
if (!node.nodes) node.type = 'text';
|
||||
node.invalid = true;
|
||||
}
|
||||
});
|
||||
|
||||
// get the location of the block on parent.nodes (block's siblings)
|
||||
let parent = stack[stack.length - 1];
|
||||
let index = parent.nodes.indexOf(block);
|
||||
// replace the (invalid) block with it's nodes
|
||||
parent.nodes.splice(index, 1, ...block.nodes);
|
||||
}
|
||||
} while (stack.length > 0);
|
||||
|
||||
push({ type: 'eos' });
|
||||
return ast;
|
||||
};
|
||||
|
||||
module.exports = parse;
|
||||
32
node_modules/.store/braces@3.0.2/node_modules/braces/lib/stringify.js
generated
vendored
Normal file
32
node_modules/.store/braces@3.0.2/node_modules/braces/lib/stringify.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const utils = require('./utils');
|
||||
|
||||
module.exports = (ast, options = {}) => {
|
||||
let stringify = (node, parent = {}) => {
|
||||
let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
|
||||
let invalidNode = node.invalid === true && options.escapeInvalid === true;
|
||||
let output = '';
|
||||
|
||||
if (node.value) {
|
||||
if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
|
||||
return '\\' + node.value;
|
||||
}
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.value) {
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.nodes) {
|
||||
for (let child of node.nodes) {
|
||||
output += stringify(child);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
return stringify(ast);
|
||||
};
|
||||
|
||||
112
node_modules/.store/braces@3.0.2/node_modules/braces/lib/utils.js
generated
vendored
Normal file
112
node_modules/.store/braces@3.0.2/node_modules/braces/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
exports.isInteger = num => {
|
||||
if (typeof num === 'number') {
|
||||
return Number.isInteger(num);
|
||||
}
|
||||
if (typeof num === 'string' && num.trim() !== '') {
|
||||
return Number.isInteger(Number(num));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a node of the given type
|
||||
*/
|
||||
|
||||
exports.find = (node, type) => node.nodes.find(node => node.type === type);
|
||||
|
||||
/**
|
||||
* Find a node of the given type
|
||||
*/
|
||||
|
||||
exports.exceedsLimit = (min, max, step = 1, limit) => {
|
||||
if (limit === false) return false;
|
||||
if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
|
||||
return ((Number(max) - Number(min)) / Number(step)) >= limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given node with '\\' before node.value
|
||||
*/
|
||||
|
||||
exports.escapeNode = (block, n = 0, type) => {
|
||||
let node = block.nodes[n];
|
||||
if (!node) return;
|
||||
|
||||
if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
|
||||
if (node.escaped !== true) {
|
||||
node.value = '\\' + node.value;
|
||||
node.escaped = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given brace node should be enclosed in literal braces
|
||||
*/
|
||||
|
||||
exports.encloseBrace = node => {
|
||||
if (node.type !== 'brace') return false;
|
||||
if ((node.commas >> 0 + node.ranges >> 0) === 0) {
|
||||
node.invalid = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if a brace node is invalid.
|
||||
*/
|
||||
|
||||
exports.isInvalidBrace = block => {
|
||||
if (block.type !== 'brace') return false;
|
||||
if (block.invalid === true || block.dollar) return true;
|
||||
if ((block.commas >> 0 + block.ranges >> 0) === 0) {
|
||||
block.invalid = true;
|
||||
return true;
|
||||
}
|
||||
if (block.open !== true || block.close !== true) {
|
||||
block.invalid = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if a node is an open or close node
|
||||
*/
|
||||
|
||||
exports.isOpenOrClose = node => {
|
||||
if (node.type === 'open' || node.type === 'close') {
|
||||
return true;
|
||||
}
|
||||
return node.open === true || node.close === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reduce an array of text nodes.
|
||||
*/
|
||||
|
||||
exports.reduce = nodes => nodes.reduce((acc, node) => {
|
||||
if (node.type === 'text') acc.push(node.value);
|
||||
if (node.type === 'range') node.type = 'text';
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Flatten an array
|
||||
*/
|
||||
|
||||
exports.flatten = (...args) => {
|
||||
const result = [];
|
||||
const flat = arr => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let ele = arr[i];
|
||||
Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
flat(args);
|
||||
return result;
|
||||
};
|
||||
80
node_modules/.store/braces@3.0.2/node_modules/braces/package.json
generated
vendored
Normal file
80
node_modules/.store/braces@3.0.2/node_modules/braces/package.json
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "braces",
|
||||
"description": "Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.",
|
||||
"version": "3.0.2",
|
||||
"homepage": "https://github.com/micromatch/braces",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"contributors": [
|
||||
"Brian Woodward (https://twitter.com/doowb)",
|
||||
"Elan Shanker (https://github.com/es128)",
|
||||
"Eugene Sharygin (https://github.com/eush77)",
|
||||
"hemanth.hm (http://h3manth.com)",
|
||||
"Jon Schlinkert (http://twitter.com/jonschlinkert)"
|
||||
],
|
||||
"repository": "micromatch/braces",
|
||||
"bugs": {
|
||||
"url": "https://github.com/micromatch/braces/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"benchmark": "node benchmark"
|
||||
},
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ansi-colors": "^3.2.4",
|
||||
"bash-path": "^2.0.1",
|
||||
"gulp-format-md": "^2.0.0",
|
||||
"mocha": "^6.1.1"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"bash",
|
||||
"brace",
|
||||
"braces",
|
||||
"expand",
|
||||
"expansion",
|
||||
"filepath",
|
||||
"fill",
|
||||
"fs",
|
||||
"glob",
|
||||
"globbing",
|
||||
"letter",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"path",
|
||||
"range",
|
||||
"ranges",
|
||||
"sh"
|
||||
],
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
},
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
]
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "braces@3.0.2",
|
||||
"_resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz"
|
||||
}
|
||||
21
node_modules/.store/braces@3.0.2/node_modules/fill-range/LICENSE
generated
vendored
Normal file
21
node_modules/.store/braces@3.0.2/node_modules/fill-range/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-present, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
237
node_modules/.store/braces@3.0.2/node_modules/fill-range/README.md
generated
vendored
Normal file
237
node_modules/.store/braces@3.0.2/node_modules/fill-range/README.md
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
# fill-range [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/fill-range) [](https://npmjs.org/package/fill-range) [](https://npmjs.org/package/fill-range) [](https://travis-ci.org/jonschlinkert/fill-range)
|
||||
|
||||
> Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save fill-range
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Expands numbers and letters, optionally using a `step` as the last argument. _(Numbers may be defined as JavaScript numbers or strings)_.
|
||||
|
||||
```js
|
||||
const fill = require('fill-range');
|
||||
// fill(from, to[, step, options]);
|
||||
|
||||
console.log(fill('1', '10')); //=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
|
||||
console.log(fill('1', '10', { toRegex: true })); //=> [1-9]|10
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
* `from`: **{String|Number}** the number or letter to start with
|
||||
* `to`: **{String|Number}** the number or letter to end with
|
||||
* `step`: **{String|Number|Object|Function}** Optionally pass a [step](#optionsstep) to use.
|
||||
* `options`: **{Object|Function}**: See all available [options](#options)
|
||||
|
||||
## Examples
|
||||
|
||||
By default, an array of values is returned.
|
||||
|
||||
**Alphabetical ranges**
|
||||
|
||||
```js
|
||||
console.log(fill('a', 'e')); //=> ['a', 'b', 'c', 'd', 'e']
|
||||
console.log(fill('A', 'E')); //=> [ 'A', 'B', 'C', 'D', 'E' ]
|
||||
```
|
||||
|
||||
**Numerical ranges**
|
||||
|
||||
Numbers can be defined as actual numbers or strings.
|
||||
|
||||
```js
|
||||
console.log(fill(1, 5)); //=> [ 1, 2, 3, 4, 5 ]
|
||||
console.log(fill('1', '5')); //=> [ 1, 2, 3, 4, 5 ]
|
||||
```
|
||||
|
||||
**Negative ranges**
|
||||
|
||||
Numbers can be defined as actual numbers or strings.
|
||||
|
||||
```js
|
||||
console.log(fill('-5', '-1')); //=> [ '-5', '-4', '-3', '-2', '-1' ]
|
||||
console.log(fill('-5', '5')); //=> [ '-5', '-4', '-3', '-2', '-1', '0', '1', '2', '3', '4', '5' ]
|
||||
```
|
||||
|
||||
**Steps (increments)**
|
||||
|
||||
```js
|
||||
// numerical ranges with increments
|
||||
console.log(fill('0', '25', 4)); //=> [ '0', '4', '8', '12', '16', '20', '24' ]
|
||||
console.log(fill('0', '25', 5)); //=> [ '0', '5', '10', '15', '20', '25' ]
|
||||
console.log(fill('0', '25', 6)); //=> [ '0', '6', '12', '18', '24' ]
|
||||
|
||||
// alphabetical ranges with increments
|
||||
console.log(fill('a', 'z', 4)); //=> [ 'a', 'e', 'i', 'm', 'q', 'u', 'y' ]
|
||||
console.log(fill('a', 'z', 5)); //=> [ 'a', 'f', 'k', 'p', 'u', 'z' ]
|
||||
console.log(fill('a', 'z', 6)); //=> [ 'a', 'g', 'm', 's', 'y' ]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### options.step
|
||||
|
||||
**Type**: `number` (formatted as a string or number)
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: The increment to use for the range. Can be used with letters or numbers.
|
||||
|
||||
**Example(s)**
|
||||
|
||||
```js
|
||||
// numbers
|
||||
console.log(fill('1', '10', 2)); //=> [ '1', '3', '5', '7', '9' ]
|
||||
console.log(fill('1', '10', 3)); //=> [ '1', '4', '7', '10' ]
|
||||
console.log(fill('1', '10', 4)); //=> [ '1', '5', '9' ]
|
||||
|
||||
// letters
|
||||
console.log(fill('a', 'z', 5)); //=> [ 'a', 'f', 'k', 'p', 'u', 'z' ]
|
||||
console.log(fill('a', 'z', 7)); //=> [ 'a', 'h', 'o', 'v' ]
|
||||
console.log(fill('a', 'z', 9)); //=> [ 'a', 'j', 's' ]
|
||||
```
|
||||
|
||||
### options.strictRanges
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
**Default**: `false`
|
||||
|
||||
**Description**: By default, `null` is returned when an invalid range is passed. Enable this option to throw a `RangeError` on invalid ranges.
|
||||
|
||||
**Example(s)**
|
||||
|
||||
The following are all invalid:
|
||||
|
||||
```js
|
||||
fill('1.1', '2'); // decimals not supported in ranges
|
||||
fill('a', '2'); // incompatible range values
|
||||
fill(1, 10, 'foo'); // invalid "step" argument
|
||||
```
|
||||
|
||||
### options.stringify
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Cast all returned values to strings. By default, integers are returned as numbers.
|
||||
|
||||
**Example(s)**
|
||||
|
||||
```js
|
||||
console.log(fill(1, 5)); //=> [ 1, 2, 3, 4, 5 ]
|
||||
console.log(fill(1, 5, { stringify: true })); //=> [ '1', '2', '3', '4', '5' ]
|
||||
```
|
||||
|
||||
### options.toRegex
|
||||
|
||||
**Type**: `boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Create a regex-compatible source string, instead of expanding values to an array.
|
||||
|
||||
**Example(s)**
|
||||
|
||||
```js
|
||||
// alphabetical range
|
||||
console.log(fill('a', 'e', { toRegex: true })); //=> '[a-e]'
|
||||
// alphabetical with step
|
||||
console.log(fill('a', 'z', 3, { toRegex: true })); //=> 'a|d|g|j|m|p|s|v|y'
|
||||
// numerical range
|
||||
console.log(fill('1', '100', { toRegex: true })); //=> '[1-9]|[1-9][0-9]|100'
|
||||
// numerical range with zero padding
|
||||
console.log(fill('000001', '100000', { toRegex: true }));
|
||||
//=> '0{5}[1-9]|0{4}[1-9][0-9]|0{3}[1-9][0-9]{2}|0{2}[1-9][0-9]{3}|0[1-9][0-9]{4}|100000'
|
||||
```
|
||||
|
||||
### options.transform
|
||||
|
||||
**Type**: `function`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Customize each value in the returned array (or [string](#optionstoRegex)). _(you can also pass this function as the last argument to `fill()`)_.
|
||||
|
||||
**Example(s)**
|
||||
|
||||
```js
|
||||
// add zero padding
|
||||
console.log(fill(1, 5, value => String(value).padStart(4, '0')));
|
||||
//=> ['0001', '0002', '0003', '0004', '0005']
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 116 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 4 | [paulmillr](https://github.com/paulmillr) |
|
||||
| 2 | [realityking](https://github.com/realityking) |
|
||||
| 2 | [bluelovers](https://github.com/bluelovers) |
|
||||
| 1 | [edorivai](https://github.com/edorivai) |
|
||||
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
Please consider supporting me on Patreon, or [start your own Patreon page](https://patreon.com/invite/bxpbvm)!
|
||||
|
||||
<a href="https://www.patreon.com/jonschlinkert">
|
||||
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" height="50">
|
||||
</a>
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._
|
||||
249
node_modules/.store/braces@3.0.2/node_modules/fill-range/index.js
generated
vendored
Normal file
249
node_modules/.store/braces@3.0.2/node_modules/fill-range/index.js
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
/*!
|
||||
* fill-range <https://github.com/jonschlinkert/fill-range>
|
||||
*
|
||||
* Copyright (c) 2014-present, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
const toRegexRange = require('to-regex-range');
|
||||
|
||||
const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
|
||||
|
||||
const transform = toNumber => {
|
||||
return value => toNumber === true ? Number(value) : String(value);
|
||||
};
|
||||
|
||||
const isValidValue = value => {
|
||||
return typeof value === 'number' || (typeof value === 'string' && value !== '');
|
||||
};
|
||||
|
||||
const isNumber = num => Number.isInteger(+num);
|
||||
|
||||
const zeros = input => {
|
||||
let value = `${input}`;
|
||||
let index = -1;
|
||||
if (value[0] === '-') value = value.slice(1);
|
||||
if (value === '0') return false;
|
||||
while (value[++index] === '0');
|
||||
return index > 0;
|
||||
};
|
||||
|
||||
const stringify = (start, end, options) => {
|
||||
if (typeof start === 'string' || typeof end === 'string') {
|
||||
return true;
|
||||
}
|
||||
return options.stringify === true;
|
||||
};
|
||||
|
||||
const pad = (input, maxLength, toNumber) => {
|
||||
if (maxLength > 0) {
|
||||
let dash = input[0] === '-' ? '-' : '';
|
||||
if (dash) input = input.slice(1);
|
||||
input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
|
||||
}
|
||||
if (toNumber === false) {
|
||||
return String(input);
|
||||
}
|
||||
return input;
|
||||
};
|
||||
|
||||
const toMaxLen = (input, maxLength) => {
|
||||
let negative = input[0] === '-' ? '-' : '';
|
||||
if (negative) {
|
||||
input = input.slice(1);
|
||||
maxLength--;
|
||||
}
|
||||
while (input.length < maxLength) input = '0' + input;
|
||||
return negative ? ('-' + input) : input;
|
||||
};
|
||||
|
||||
const toSequence = (parts, options) => {
|
||||
parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
||||
parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
||||
|
||||
let prefix = options.capture ? '' : '?:';
|
||||
let positives = '';
|
||||
let negatives = '';
|
||||
let result;
|
||||
|
||||
if (parts.positives.length) {
|
||||
positives = parts.positives.join('|');
|
||||
}
|
||||
|
||||
if (parts.negatives.length) {
|
||||
negatives = `-(${prefix}${parts.negatives.join('|')})`;
|
||||
}
|
||||
|
||||
if (positives && negatives) {
|
||||
result = `${positives}|${negatives}`;
|
||||
} else {
|
||||
result = positives || negatives;
|
||||
}
|
||||
|
||||
if (options.wrap) {
|
||||
return `(${prefix}${result})`;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const toRange = (a, b, isNumbers, options) => {
|
||||
if (isNumbers) {
|
||||
return toRegexRange(a, b, { wrap: false, ...options });
|
||||
}
|
||||
|
||||
let start = String.fromCharCode(a);
|
||||
if (a === b) return start;
|
||||
|
||||
let stop = String.fromCharCode(b);
|
||||
return `[${start}-${stop}]`;
|
||||
};
|
||||
|
||||
const toRegex = (start, end, options) => {
|
||||
if (Array.isArray(start)) {
|
||||
let wrap = options.wrap === true;
|
||||
let prefix = options.capture ? '' : '?:';
|
||||
return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
|
||||
}
|
||||
return toRegexRange(start, end, options);
|
||||
};
|
||||
|
||||
const rangeError = (...args) => {
|
||||
return new RangeError('Invalid range arguments: ' + util.inspect(...args));
|
||||
};
|
||||
|
||||
const invalidRange = (start, end, options) => {
|
||||
if (options.strictRanges === true) throw rangeError([start, end]);
|
||||
return [];
|
||||
};
|
||||
|
||||
const invalidStep = (step, options) => {
|
||||
if (options.strictRanges === true) {
|
||||
throw new TypeError(`Expected step "${step}" to be a number`);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const fillNumbers = (start, end, step = 1, options = {}) => {
|
||||
let a = Number(start);
|
||||
let b = Number(end);
|
||||
|
||||
if (!Number.isInteger(a) || !Number.isInteger(b)) {
|
||||
if (options.strictRanges === true) throw rangeError([start, end]);
|
||||
return [];
|
||||
}
|
||||
|
||||
// fix negative zero
|
||||
if (a === 0) a = 0;
|
||||
if (b === 0) b = 0;
|
||||
|
||||
let descending = a > b;
|
||||
let startString = String(start);
|
||||
let endString = String(end);
|
||||
let stepString = String(step);
|
||||
step = Math.max(Math.abs(step), 1);
|
||||
|
||||
let padded = zeros(startString) || zeros(endString) || zeros(stepString);
|
||||
let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
|
||||
let toNumber = padded === false && stringify(start, end, options) === false;
|
||||
let format = options.transform || transform(toNumber);
|
||||
|
||||
if (options.toRegex && step === 1) {
|
||||
return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
|
||||
}
|
||||
|
||||
let parts = { negatives: [], positives: [] };
|
||||
let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
|
||||
let range = [];
|
||||
let index = 0;
|
||||
|
||||
while (descending ? a >= b : a <= b) {
|
||||
if (options.toRegex === true && step > 1) {
|
||||
push(a);
|
||||
} else {
|
||||
range.push(pad(format(a, index), maxLen, toNumber));
|
||||
}
|
||||
a = descending ? a - step : a + step;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (options.toRegex === true) {
|
||||
return step > 1
|
||||
? toSequence(parts, options)
|
||||
: toRegex(range, null, { wrap: false, ...options });
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
const fillLetters = (start, end, step = 1, options = {}) => {
|
||||
if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
|
||||
return invalidRange(start, end, options);
|
||||
}
|
||||
|
||||
|
||||
let format = options.transform || (val => String.fromCharCode(val));
|
||||
let a = `${start}`.charCodeAt(0);
|
||||
let b = `${end}`.charCodeAt(0);
|
||||
|
||||
let descending = a > b;
|
||||
let min = Math.min(a, b);
|
||||
let max = Math.max(a, b);
|
||||
|
||||
if (options.toRegex && step === 1) {
|
||||
return toRange(min, max, false, options);
|
||||
}
|
||||
|
||||
let range = [];
|
||||
let index = 0;
|
||||
|
||||
while (descending ? a >= b : a <= b) {
|
||||
range.push(format(a, index));
|
||||
a = descending ? a - step : a + step;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (options.toRegex === true) {
|
||||
return toRegex(range, null, { wrap: false, options });
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
const fill = (start, end, step, options = {}) => {
|
||||
if (end == null && isValidValue(start)) {
|
||||
return [start];
|
||||
}
|
||||
|
||||
if (!isValidValue(start) || !isValidValue(end)) {
|
||||
return invalidRange(start, end, options);
|
||||
}
|
||||
|
||||
if (typeof step === 'function') {
|
||||
return fill(start, end, 1, { transform: step });
|
||||
}
|
||||
|
||||
if (isObject(step)) {
|
||||
return fill(start, end, 0, step);
|
||||
}
|
||||
|
||||
let opts = { ...options };
|
||||
if (opts.capture === true) opts.wrap = true;
|
||||
step = step || opts.step || 1;
|
||||
|
||||
if (!isNumber(step)) {
|
||||
if (step != null && !isObject(step)) return invalidStep(step, opts);
|
||||
return fill(start, end, 1, step);
|
||||
}
|
||||
|
||||
if (isNumber(start) && isNumber(end)) {
|
||||
return fillNumbers(start, end, step, opts);
|
||||
}
|
||||
|
||||
return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
|
||||
};
|
||||
|
||||
module.exports = fill;
|
||||
72
node_modules/.store/braces@3.0.2/node_modules/fill-range/package.json
generated
vendored
Normal file
72
node_modules/.store/braces@3.0.2/node_modules/fill-range/package.json
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "fill-range",
|
||||
"description": "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`",
|
||||
"version": "7.0.1",
|
||||
"homepage": "https://github.com/jonschlinkert/fill-range",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"contributors": [
|
||||
"Edo Rivai (edo.rivai.nl)",
|
||||
"Jon Schlinkert (http://twitter.com/jonschlinkert)",
|
||||
"Paul Miller (paulmillr.com)",
|
||||
"Rouven Weßling (www.rouvenwessling.de)",
|
||||
"(https://github.com/wtgtybhertgeghgtwtg)"
|
||||
],
|
||||
"repository": "jonschlinkert/fill-range",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/fill-range/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp-format-md": "^2.0.0",
|
||||
"mocha": "^6.1.1"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"array",
|
||||
"bash",
|
||||
"brace",
|
||||
"expand",
|
||||
"expansion",
|
||||
"fill",
|
||||
"glob",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"range",
|
||||
"ranges",
|
||||
"regex",
|
||||
"sh"
|
||||
],
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "fill-range@7.0.1",
|
||||
"_resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz"
|
||||
}
|
||||
15
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/LICENSE
generated
vendored
Normal file
15
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com)
|
||||
|
||||
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.
|
||||
87
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/README.md
generated
vendored
Normal file
87
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
anymatch [](https://travis-ci.org/micromatch/anymatch) [](https://coveralls.io/r/micromatch/anymatch?branch=master)
|
||||
======
|
||||
Javascript module to match a string against a regular expression, glob, string,
|
||||
or function that takes the string as an argument and returns a truthy or falsy
|
||||
value. The matcher can also be an array of any or all of these. Useful for
|
||||
allowing a very flexible user-defined config to define things like file paths.
|
||||
|
||||
__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
```sh
|
||||
npm install anymatch
|
||||
```
|
||||
|
||||
#### anymatch(matchers, testString, [returnIndex], [options])
|
||||
* __matchers__: (_Array|String|RegExp|Function_)
|
||||
String to be directly matched, string with glob patterns, regular expression
|
||||
test, function that takes the testString as an argument and returns a truthy
|
||||
value if it should be matched, or an array of any number and mix of these types.
|
||||
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||
passed as an array, the first element of the array will be used as the
|
||||
`testString` for non-function matchers, while the entire array will be applied
|
||||
as the arguments for function matchers.
|
||||
* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options.
|
||||
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||
boolean result.
|
||||
|
||||
```js
|
||||
const anymatch = require('anymatch');
|
||||
|
||||
const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ;
|
||||
|
||||
anymatch(matchers, 'path/to/file.js'); // true
|
||||
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||
anymatch(matchers, 'path/to/foo.js'); // true
|
||||
anymatch(matchers, 'path/to/bar.js'); // true
|
||||
anymatch(matchers, 'bar.js'); // false
|
||||
|
||||
// returnIndex = true
|
||||
anymatch(matchers, 'foo.js', {returnIndex: true}); // 2
|
||||
anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1
|
||||
|
||||
// any picomatc
|
||||
|
||||
// using globs to match directories and their children
|
||||
anymatch('node_modules', 'node_modules'); // true
|
||||
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
|
||||
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
|
||||
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
|
||||
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
|
||||
|
||||
const matcher = anymatch(matchers);
|
||||
['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ]
|
||||
anymatch master* ❯
|
||||
|
||||
```
|
||||
|
||||
#### anymatch(matchers)
|
||||
You can also pass in only your matcher(s) to get a curried function that has
|
||||
already been bound to the provided matching criteria. This can be used as an
|
||||
`Array#filter` callback.
|
||||
|
||||
```js
|
||||
var matcher = anymatch(matchers);
|
||||
|
||||
matcher('path/to/file.js'); // true
|
||||
matcher('path/anyjs/baz.js', true); // 1
|
||||
|
||||
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||
```
|
||||
|
||||
Changelog
|
||||
----------
|
||||
[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases)
|
||||
|
||||
- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only.
|
||||
- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information).
|
||||
- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||
for glob pattern matching. Issues with glob pattern matching should be
|
||||
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||
|
||||
License
|
||||
-------
|
||||
[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE)
|
||||
20
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
20
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
type AnymatchFn = (testString: string) => boolean;
|
||||
type AnymatchPattern = string|RegExp|AnymatchFn;
|
||||
type AnymatchMatcher = AnymatchPattern|AnymatchPattern[]
|
||||
type AnymatchTester = {
|
||||
(testString: string|any[], returnIndex: true): number;
|
||||
(testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
type PicomatchOptions = {dot: boolean};
|
||||
|
||||
declare const anymatch: {
|
||||
(matchers: AnymatchMatcher): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number;
|
||||
(matchers: AnymatchMatcher, testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
export {AnymatchMatcher as Matcher}
|
||||
export {AnymatchTester as Tester}
|
||||
export default anymatch
|
||||
104
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/index.js
generated
vendored
Normal file
104
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const picomatch = require('picomatch');
|
||||
const normalizePath = require('normalize-path');
|
||||
|
||||
/**
|
||||
* @typedef {(testString: string) => boolean} AnymatchFn
|
||||
* @typedef {string|RegExp|AnymatchFn} AnymatchPattern
|
||||
* @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
|
||||
*/
|
||||
const BANG = '!';
|
||||
const DEFAULT_OPTIONS = {returnIndex: false};
|
||||
const arrify = (item) => Array.isArray(item) ? item : [item];
|
||||
|
||||
/**
|
||||
* @param {AnymatchPattern} matcher
|
||||
* @param {object} options
|
||||
* @returns {AnymatchFn}
|
||||
*/
|
||||
const createPattern = (matcher, options) => {
|
||||
if (typeof matcher === 'function') {
|
||||
return matcher;
|
||||
}
|
||||
if (typeof matcher === 'string') {
|
||||
const glob = picomatch(matcher, options);
|
||||
return (string) => matcher === string || glob(string);
|
||||
}
|
||||
if (matcher instanceof RegExp) {
|
||||
return (string) => matcher.test(string);
|
||||
}
|
||||
return (string) => false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<Function>} patterns
|
||||
* @param {Array<Function>} negPatterns
|
||||
* @param {String|Array} args
|
||||
* @param {Boolean} returnIndex
|
||||
* @returns {boolean|number}
|
||||
*/
|
||||
const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
|
||||
const isList = Array.isArray(args);
|
||||
const _path = isList ? args[0] : args;
|
||||
if (!isList && typeof _path !== 'string') {
|
||||
throw new TypeError('anymatch: second argument must be a string: got ' +
|
||||
Object.prototype.toString.call(_path))
|
||||
}
|
||||
const path = normalizePath(_path, false);
|
||||
|
||||
for (let index = 0; index < negPatterns.length; index++) {
|
||||
const nglob = negPatterns[index];
|
||||
if (nglob(path)) {
|
||||
return returnIndex ? -1 : false;
|
||||
}
|
||||
}
|
||||
|
||||
const applied = isList && [path].concat(args.slice(1));
|
||||
for (let index = 0; index < patterns.length; index++) {
|
||||
const pattern = patterns[index];
|
||||
if (isList ? pattern(...applied) : pattern(path)) {
|
||||
return returnIndex ? index : true;
|
||||
}
|
||||
}
|
||||
|
||||
return returnIndex ? -1 : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {AnymatchMatcher} matchers
|
||||
* @param {Array|string} testString
|
||||
* @param {object} options
|
||||
* @returns {boolean|number|Function}
|
||||
*/
|
||||
const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
|
||||
if (matchers == null) {
|
||||
throw new TypeError('anymatch: specify first argument');
|
||||
}
|
||||
const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
|
||||
const returnIndex = opts.returnIndex || false;
|
||||
|
||||
// Early cache for matchers.
|
||||
const mtchers = arrify(matchers);
|
||||
const negatedGlobs = mtchers
|
||||
.filter(item => typeof item === 'string' && item.charAt(0) === BANG)
|
||||
.map(item => item.slice(1))
|
||||
.map(item => picomatch(item, opts));
|
||||
const patterns = mtchers
|
||||
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
|
||||
.map(matcher => createPattern(matcher, opts));
|
||||
|
||||
if (testString == null) {
|
||||
return (testString, ri = false) => {
|
||||
const returnIndex = typeof ri === 'boolean' ? ri : false;
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
};
|
||||
|
||||
anymatch.default = anymatch;
|
||||
module.exports = anymatch;
|
||||
51
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/package.json
generated
vendored
Normal file
51
node_modules/.store/chokidar@3.5.3/node_modules/anymatch/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "anymatch",
|
||||
"version": "3.1.3",
|
||||
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Elan Shanker",
|
||||
"url": "https://github.com/es128"
|
||||
},
|
||||
"license": "ISC",
|
||||
"homepage": "https://github.com/micromatch/anymatch",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/micromatch/anymatch"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"any",
|
||||
"string",
|
||||
"file",
|
||||
"fs",
|
||||
"list",
|
||||
"glob",
|
||||
"regex",
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"function"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "nyc mocha",
|
||||
"mocha": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^6.1.3",
|
||||
"nyc": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "anymatch@3.1.3",
|
||||
"_resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz"
|
||||
}
|
||||
184
node_modules/.store/chokidar@3.5.3/node_modules/braces/CHANGELOG.md
generated
vendored
Normal file
184
node_modules/.store/chokidar@3.5.3/node_modules/braces/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
# Release history
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
<details>
|
||||
<summary><strong>Guiding Principles</strong></summary>
|
||||
|
||||
- Changelogs are for humans, not machines.
|
||||
- There should be an entry for every single version.
|
||||
- The same types of changes should be grouped.
|
||||
- Versions and sections should be linkable.
|
||||
- The latest version comes first.
|
||||
- The release date of each versions is displayed.
|
||||
- Mention whether you follow Semantic Versioning.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Types of changes</strong></summary>
|
||||
|
||||
Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_):
|
||||
|
||||
- `Added` for new features.
|
||||
- `Changed` for changes in existing functionality.
|
||||
- `Deprecated` for soon-to-be removed features.
|
||||
- `Removed` for now removed features.
|
||||
- `Fixed` for any bug fixes.
|
||||
- `Security` in case of vulnerabilities.
|
||||
|
||||
</details>
|
||||
|
||||
## [3.0.0] - 2018-04-08
|
||||
|
||||
v3.0 is a complete refactor, resulting in a faster, smaller codebase, with fewer deps, and a more accurate parser and compiler.
|
||||
|
||||
**Breaking Changes**
|
||||
|
||||
- The undocumented `.makeRe` method was removed
|
||||
|
||||
**Non-breaking changes**
|
||||
|
||||
- Caching was removed
|
||||
|
||||
## [2.3.2] - 2018-04-08
|
||||
|
||||
- start refactoring
|
||||
- cover sets
|
||||
- better range handling
|
||||
|
||||
## [2.3.1] - 2018-02-17
|
||||
|
||||
- Remove unnecessary escape in Regex. (#14)
|
||||
|
||||
## [2.3.0] - 2017-10-19
|
||||
|
||||
- minor code reorganization
|
||||
- optimize regex
|
||||
- expose `maxLength` option
|
||||
|
||||
## [2.2.1] - 2017-05-30
|
||||
|
||||
- don't condense when braces contain extglobs
|
||||
|
||||
## [2.2.0] - 2017-05-28
|
||||
|
||||
- ensure word boundaries are preserved
|
||||
- fixes edge case where extglob characters precede a brace pattern
|
||||
|
||||
## [2.1.1] - 2017-04-27
|
||||
|
||||
- use snapdragon-node
|
||||
- handle edge case
|
||||
- optimizations, lint
|
||||
|
||||
## [2.0.4] - 2017-04-11
|
||||
|
||||
- pass opts to compiler
|
||||
- minor optimization in create method
|
||||
- re-write parser handlers to remove negation regex
|
||||
|
||||
## [2.0.3] - 2016-12-10
|
||||
|
||||
- use split-string
|
||||
- clear queue at the end
|
||||
- adds sequences example
|
||||
- add unit tests
|
||||
|
||||
## [2.0.2] - 2016-10-21
|
||||
|
||||
- fix comma handling in nested extglobs
|
||||
|
||||
## [2.0.1] - 2016-10-20
|
||||
|
||||
- add comments
|
||||
- more tests, ensure quotes are stripped
|
||||
|
||||
## [2.0.0] - 2016-10-19
|
||||
|
||||
- don't expand braces inside character classes
|
||||
- add quantifier pattern
|
||||
|
||||
## [1.8.5] - 2016-05-21
|
||||
|
||||
- Refactor (#10)
|
||||
|
||||
## [1.8.4] - 2016-04-20
|
||||
|
||||
- fixes https://github.com/jonschlinkert/micromatch/issues/66
|
||||
|
||||
## [1.8.0] - 2015-03-18
|
||||
|
||||
- adds exponent examples, tests
|
||||
- fixes the first example in https://github.com/jonschlinkert/micromatch/issues/38
|
||||
|
||||
## [1.6.0] - 2015-01-30
|
||||
|
||||
- optimizations, `bash` mode:
|
||||
- improve path escaping
|
||||
|
||||
## [1.5.0] - 2015-01-28
|
||||
|
||||
- Merge pull request #5 from eush77/lib-files
|
||||
|
||||
## [1.4.0] - 2015-01-24
|
||||
|
||||
- add extglob tests
|
||||
- externalize exponent function
|
||||
- better whitespace handling
|
||||
|
||||
## [1.3.0] - 2015-01-24
|
||||
|
||||
- make regex patterns explicity
|
||||
|
||||
## [1.1.0] - 2015-01-11
|
||||
|
||||
- don't create a match group with `makeRe`
|
||||
|
||||
## [1.0.0] - 2014-12-23
|
||||
|
||||
- Merge commit '97b05f5544f8348736a8efaecf5c32bbe3e2ad6e'
|
||||
- support empty brace syntax
|
||||
- better bash coverage
|
||||
- better support for regex strings
|
||||
|
||||
## [0.1.4] - 2014-11-14
|
||||
|
||||
- improve recognition of bad args, recognize mismatched argument types
|
||||
- support escaping
|
||||
- remove pathname-expansion
|
||||
- support whitespace in patterns
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
- first commit
|
||||
|
||||
[2.3.2]: https://github.com/micromatch/braces/compare/2.3.1...2.3.2
|
||||
[2.3.1]: https://github.com/micromatch/braces/compare/2.3.0...2.3.1
|
||||
[2.3.0]: https://github.com/micromatch/braces/compare/2.2.1...2.3.0
|
||||
[2.2.1]: https://github.com/micromatch/braces/compare/2.2.0...2.2.1
|
||||
[2.2.0]: https://github.com/micromatch/braces/compare/2.1.1...2.2.0
|
||||
[2.1.1]: https://github.com/micromatch/braces/compare/2.1.0...2.1.1
|
||||
[2.1.0]: https://github.com/micromatch/braces/compare/2.0.4...2.1.0
|
||||
[2.0.4]: https://github.com/micromatch/braces/compare/2.0.3...2.0.4
|
||||
[2.0.3]: https://github.com/micromatch/braces/compare/2.0.2...2.0.3
|
||||
[2.0.2]: https://github.com/micromatch/braces/compare/2.0.1...2.0.2
|
||||
[2.0.1]: https://github.com/micromatch/braces/compare/2.0.0...2.0.1
|
||||
[2.0.0]: https://github.com/micromatch/braces/compare/1.8.5...2.0.0
|
||||
[1.8.5]: https://github.com/micromatch/braces/compare/1.8.4...1.8.5
|
||||
[1.8.4]: https://github.com/micromatch/braces/compare/1.8.0...1.8.4
|
||||
[1.8.0]: https://github.com/micromatch/braces/compare/1.6.0...1.8.0
|
||||
[1.6.0]: https://github.com/micromatch/braces/compare/1.5.0...1.6.0
|
||||
[1.5.0]: https://github.com/micromatch/braces/compare/1.4.0...1.5.0
|
||||
[1.4.0]: https://github.com/micromatch/braces/compare/1.3.0...1.4.0
|
||||
[1.3.0]: https://github.com/micromatch/braces/compare/1.2.0...1.3.0
|
||||
[1.2.0]: https://github.com/micromatch/braces/compare/1.1.0...1.2.0
|
||||
[1.1.0]: https://github.com/micromatch/braces/compare/1.0.0...1.1.0
|
||||
[1.0.0]: https://github.com/micromatch/braces/compare/0.1.4...1.0.0
|
||||
[0.1.4]: https://github.com/micromatch/braces/compare/0.1.0...0.1.4
|
||||
|
||||
[Unreleased]: https://github.com/micromatch/braces/compare/0.1.0...HEAD
|
||||
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog
|
||||
21
node_modules/.store/chokidar@3.5.3/node_modules/braces/LICENSE
generated
vendored
Normal file
21
node_modules/.store/chokidar@3.5.3/node_modules/braces/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2018, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
593
node_modules/.store/chokidar@3.5.3/node_modules/braces/README.md
generated
vendored
Normal file
593
node_modules/.store/chokidar@3.5.3/node_modules/braces/README.md
generated
vendored
Normal file
@@ -0,0 +1,593 @@
|
||||
# braces [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W8YFZ425KND68) [](https://www.npmjs.com/package/braces) [](https://npmjs.org/package/braces) [](https://npmjs.org/package/braces) [](https://travis-ci.org/micromatch/braces)
|
||||
|
||||
> Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.
|
||||
|
||||
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save braces
|
||||
```
|
||||
|
||||
## v3.0.0 Released!!
|
||||
|
||||
See the [changelog](CHANGELOG.md) for details.
|
||||
|
||||
## Why use braces?
|
||||
|
||||
Brace patterns make globs more powerful by adding the ability to match specific ranges and sequences of characters.
|
||||
|
||||
* **Accurate** - complete support for the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/) specification (passes all of the Bash braces tests)
|
||||
* **[fast and performant](#benchmarks)** - Starts fast, runs fast and [scales well](#performance) as patterns increase in complexity.
|
||||
* **Organized code base** - The parser and compiler are easy to maintain and update when edge cases crop up.
|
||||
* **Well-tested** - Thousands of test assertions, and passes all of the Bash, minimatch, and [brace-expansion](https://github.com/juliangruber/brace-expansion) unit tests (as of the date this was written).
|
||||
* **Safer** - You shouldn't have to worry about users defining aggressive or malicious brace patterns that can break your application. Braces takes measures to prevent malicious regex that can be used for DDoS attacks (see [catastrophic backtracking](https://www.regular-expressions.info/catastrophic.html)).
|
||||
* [Supports lists](#lists) - (aka "sets") `a/{b,c}/d` => `['a/b/d', 'a/c/d']`
|
||||
* [Supports sequences](#sequences) - (aka "ranges") `{01..03}` => `['01', '02', '03']`
|
||||
* [Supports steps](#steps) - (aka "increments") `{2..10..2}` => `['2', '4', '6', '8', '10']`
|
||||
* [Supports escaping](#escaping) - To prevent evaluation of special characters.
|
||||
|
||||
## Usage
|
||||
|
||||
The main export is a function that takes one or more brace `patterns` and `options`.
|
||||
|
||||
```js
|
||||
const braces = require('braces');
|
||||
// braces(patterns[, options]);
|
||||
|
||||
console.log(braces(['{01..05}', '{a..e}']));
|
||||
//=> ['(0[1-5])', '([a-e])']
|
||||
|
||||
console.log(braces(['{01..05}', '{a..e}'], { expand: true }));
|
||||
//=> ['01', '02', '03', '04', '05', 'a', 'b', 'c', 'd', 'e']
|
||||
```
|
||||
|
||||
### Brace Expansion vs. Compilation
|
||||
|
||||
By default, brace patterns are compiled into strings that are optimized for creating regular expressions and matching.
|
||||
|
||||
**Compiled**
|
||||
|
||||
```js
|
||||
console.log(braces('a/{x,y,z}/b'));
|
||||
//=> ['a/(x|y|z)/b']
|
||||
console.log(braces(['a/{01..20}/b', 'a/{1..5}/b']));
|
||||
//=> [ 'a/(0[1-9]|1[0-9]|20)/b', 'a/([1-5])/b' ]
|
||||
```
|
||||
|
||||
**Expanded**
|
||||
|
||||
Enable brace expansion by setting the `expand` option to true, or by using [braces.expand()](#expand) (returns an array similar to what you'd expect from Bash, or `echo {1..5}`, or [minimatch](https://github.com/isaacs/minimatch)):
|
||||
|
||||
```js
|
||||
console.log(braces('a/{x,y,z}/b', { expand: true }));
|
||||
//=> ['a/x/b', 'a/y/b', 'a/z/b']
|
||||
|
||||
console.log(braces.expand('{01..10}'));
|
||||
//=> ['01','02','03','04','05','06','07','08','09','10']
|
||||
```
|
||||
|
||||
### Lists
|
||||
|
||||
Expand lists (like Bash "sets"):
|
||||
|
||||
```js
|
||||
console.log(braces('a/{foo,bar,baz}/*.js'));
|
||||
//=> ['a/(foo|bar|baz)/*.js']
|
||||
|
||||
console.log(braces.expand('a/{foo,bar,baz}/*.js'));
|
||||
//=> ['a/foo/*.js', 'a/bar/*.js', 'a/baz/*.js']
|
||||
```
|
||||
|
||||
### Sequences
|
||||
|
||||
Expand ranges of characters (like Bash "sequences"):
|
||||
|
||||
```js
|
||||
console.log(braces.expand('{1..3}')); // ['1', '2', '3']
|
||||
console.log(braces.expand('a/{1..3}/b')); // ['a/1/b', 'a/2/b', 'a/3/b']
|
||||
console.log(braces('{a..c}', { expand: true })); // ['a', 'b', 'c']
|
||||
console.log(braces('foo/{a..c}', { expand: true })); // ['foo/a', 'foo/b', 'foo/c']
|
||||
|
||||
// supports zero-padded ranges
|
||||
console.log(braces('a/{01..03}/b')); //=> ['a/(0[1-3])/b']
|
||||
console.log(braces('a/{001..300}/b')); //=> ['a/(0{2}[1-9]|0[1-9][0-9]|[12][0-9]{2}|300)/b']
|
||||
```
|
||||
|
||||
See [fill-range](https://github.com/jonschlinkert/fill-range) for all available range-expansion options.
|
||||
|
||||
### Steppped ranges
|
||||
|
||||
Steps, or increments, may be used with ranges:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('{2..10..2}'));
|
||||
//=> ['2', '4', '6', '8', '10']
|
||||
|
||||
console.log(braces('{2..10..2}'));
|
||||
//=> ['(2|4|6|8|10)']
|
||||
```
|
||||
|
||||
When the [.optimize](#optimize) method is used, or [options.optimize](#optionsoptimize) is set to true, sequences are passed to [to-regex-range](https://github.com/jonschlinkert/to-regex-range) for expansion.
|
||||
|
||||
### Nesting
|
||||
|
||||
Brace patterns may be nested. The results of each expanded string are not sorted, and left to right order is preserved.
|
||||
|
||||
**"Expanded" braces**
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b,c,/{x,y}}/e'));
|
||||
//=> ['ab/e', 'ac/e', 'a/x/e', 'a/y/e']
|
||||
|
||||
console.log(braces.expand('a/{x,{1..5},y}/c'));
|
||||
//=> ['a/x/c', 'a/1/c', 'a/2/c', 'a/3/c', 'a/4/c', 'a/5/c', 'a/y/c']
|
||||
```
|
||||
|
||||
**"Optimized" braces**
|
||||
|
||||
```js
|
||||
console.log(braces('a{b,c,/{x,y}}/e'));
|
||||
//=> ['a(b|c|/(x|y))/e']
|
||||
|
||||
console.log(braces('a/{x,{1..5},y}/c'));
|
||||
//=> ['a/(x|([1-5])|y)/c']
|
||||
```
|
||||
|
||||
### Escaping
|
||||
|
||||
**Escaping braces**
|
||||
|
||||
A brace pattern will not be expanded or evaluted if _either the opening or closing brace is escaped_:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a\\{d,c,b}e'));
|
||||
//=> ['a{d,c,b}e']
|
||||
|
||||
console.log(braces.expand('a{d,c,b\\}e'));
|
||||
//=> ['a{d,c,b}e']
|
||||
```
|
||||
|
||||
**Escaping commas**
|
||||
|
||||
Commas inside braces may also be escaped:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b\\,c}d'));
|
||||
//=> ['a{b,c}d']
|
||||
|
||||
console.log(braces.expand('a{d\\,c,b}e'));
|
||||
//=> ['ad,ce', 'abe']
|
||||
```
|
||||
|
||||
**Single items**
|
||||
|
||||
Following bash conventions, a brace pattern is also not expanded when it contains a single character:
|
||||
|
||||
```js
|
||||
console.log(braces.expand('a{b}c'));
|
||||
//=> ['a{b}c']
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### options.maxLength
|
||||
|
||||
**Type**: `Number`
|
||||
|
||||
**Default**: `65,536`
|
||||
|
||||
**Description**: Limit the length of the input string. Useful when the input string is generated or your application allows users to pass a string, et cetera.
|
||||
|
||||
```js
|
||||
console.log(braces('a/{b,c}/d', { maxLength: 3 })); //=> throws an error
|
||||
```
|
||||
|
||||
### options.expand
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Generate an "expanded" brace pattern (alternatively you can use the `braces.expand()` method, which does the same thing).
|
||||
|
||||
```js
|
||||
console.log(braces('a/{b,c}/d', { expand: true }));
|
||||
//=> [ 'a/b/d', 'a/c/d' ]
|
||||
```
|
||||
|
||||
### options.nodupes
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Remove duplicates from the returned array.
|
||||
|
||||
### options.rangeLimit
|
||||
|
||||
**Type**: `Number`
|
||||
|
||||
**Default**: `1000`
|
||||
|
||||
**Description**: To prevent malicious patterns from being passed by users, an error is thrown when `braces.expand()` is used or `options.expand` is true and the generated range will exceed the `rangeLimit`.
|
||||
|
||||
You can customize `options.rangeLimit` or set it to `Inifinity` to disable this altogether.
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
// pattern exceeds the "rangeLimit", so it's optimized automatically
|
||||
console.log(braces.expand('{1..1000}'));
|
||||
//=> ['([1-9]|[1-9][0-9]{1,2}|1000)']
|
||||
|
||||
// pattern does not exceed "rangeLimit", so it's NOT optimized
|
||||
console.log(braces.expand('{1..100}'));
|
||||
//=> ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100']
|
||||
```
|
||||
|
||||
### options.transform
|
||||
|
||||
**Type**: `Function`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Customize range expansion.
|
||||
|
||||
**Example: Transforming non-numeric values**
|
||||
|
||||
```js
|
||||
const alpha = braces.expand('x/{a..e}/y', {
|
||||
transform(value, index) {
|
||||
// When non-numeric values are passed, "value" is a character code.
|
||||
return 'foo/' + String.fromCharCode(value) + '-' + index;
|
||||
}
|
||||
});
|
||||
console.log(alpha);
|
||||
//=> [ 'x/foo/a-0/y', 'x/foo/b-1/y', 'x/foo/c-2/y', 'x/foo/d-3/y', 'x/foo/e-4/y' ]
|
||||
```
|
||||
|
||||
**Example: Transforming numeric values**
|
||||
|
||||
```js
|
||||
const numeric = braces.expand('{1..5}', {
|
||||
transform(value) {
|
||||
// when numeric values are passed, "value" is a number
|
||||
return 'foo/' + value * 2;
|
||||
}
|
||||
});
|
||||
console.log(numeric);
|
||||
//=> [ 'foo/2', 'foo/4', 'foo/6', 'foo/8', 'foo/10' ]
|
||||
```
|
||||
|
||||
### options.quantifiers
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: In regular expressions, quanitifiers can be used to specify how many times a token can be repeated. For example, `a{1,3}` will match the letter `a` one to three times.
|
||||
|
||||
Unfortunately, regex quantifiers happen to share the same syntax as [Bash lists](#lists)
|
||||
|
||||
The `quantifiers` option tells braces to detect when [regex quantifiers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#quantifiers) are defined in the given pattern, and not to try to expand them as lists.
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
const braces = require('braces');
|
||||
console.log(braces('a/b{1,3}/{x,y,z}'));
|
||||
//=> [ 'a/b(1|3)/(x|y|z)' ]
|
||||
console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true}));
|
||||
//=> [ 'a/b{1,3}/(x|y|z)' ]
|
||||
console.log(braces('a/b{1,3}/{x,y,z}', {quantifiers: true, expand: true}));
|
||||
//=> [ 'a/b{1,3}/x', 'a/b{1,3}/y', 'a/b{1,3}/z' ]
|
||||
```
|
||||
|
||||
### options.unescape
|
||||
|
||||
**Type**: `Boolean`
|
||||
|
||||
**Default**: `undefined`
|
||||
|
||||
**Description**: Strip backslashes that were used for escaping from the result.
|
||||
|
||||
## What is "brace expansion"?
|
||||
|
||||
Brace expansion is a type of parameter expansion that was made popular by unix shells for generating lists of strings, as well as regex-like matching when used alongside wildcards (globs).
|
||||
|
||||
In addition to "expansion", braces are also used for matching. In other words:
|
||||
|
||||
* [brace expansion](#brace-expansion) is for generating new lists
|
||||
* [brace matching](#brace-matching) is for filtering existing lists
|
||||
|
||||
<details>
|
||||
<summary><strong>More about brace expansion</strong> (click to expand)</summary>
|
||||
|
||||
There are two main types of brace expansion:
|
||||
|
||||
1. **lists**: which are defined using comma-separated values inside curly braces: `{a,b,c}`
|
||||
2. **sequences**: which are defined using a starting value and an ending value, separated by two dots: `a{1..3}b`. Optionally, a third argument may be passed to define a "step" or increment to use: `a{1..100..10}b`. These are also sometimes referred to as "ranges".
|
||||
|
||||
Here are some example brace patterns to illustrate how they work:
|
||||
|
||||
**Sets**
|
||||
|
||||
```
|
||||
{a,b,c} => a b c
|
||||
{a,b,c}{1,2} => a1 a2 b1 b2 c1 c2
|
||||
```
|
||||
|
||||
**Sequences**
|
||||
|
||||
```
|
||||
{1..9} => 1 2 3 4 5 6 7 8 9
|
||||
{4..-4} => 4 3 2 1 0 -1 -2 -3 -4
|
||||
{1..20..3} => 1 4 7 10 13 16 19
|
||||
{a..j} => a b c d e f g h i j
|
||||
{j..a} => j i h g f e d c b a
|
||||
{a..z..3} => a d g j m p s v y
|
||||
```
|
||||
|
||||
**Combination**
|
||||
|
||||
Sets and sequences can be mixed together or used along with any other strings.
|
||||
|
||||
```
|
||||
{a,b,c}{1..3} => a1 a2 a3 b1 b2 b3 c1 c2 c3
|
||||
foo/{a,b,c}/bar => foo/a/bar foo/b/bar foo/c/bar
|
||||
```
|
||||
|
||||
The fact that braces can be "expanded" from relatively simple patterns makes them ideal for quickly generating test fixtures, file paths, and similar use cases.
|
||||
|
||||
## Brace matching
|
||||
|
||||
In addition to _expansion_, brace patterns are also useful for performing regular-expression-like matching.
|
||||
|
||||
For example, the pattern `foo/{1..3}/bar` would match any of following strings:
|
||||
|
||||
```
|
||||
foo/1/bar
|
||||
foo/2/bar
|
||||
foo/3/bar
|
||||
```
|
||||
|
||||
But not:
|
||||
|
||||
```
|
||||
baz/1/qux
|
||||
baz/2/qux
|
||||
baz/3/qux
|
||||
```
|
||||
|
||||
Braces can also be combined with [glob patterns](https://github.com/jonschlinkert/micromatch) to perform more advanced wildcard matching. For example, the pattern `*/{1..3}/*` would match any of following strings:
|
||||
|
||||
```
|
||||
foo/1/bar
|
||||
foo/2/bar
|
||||
foo/3/bar
|
||||
baz/1/qux
|
||||
baz/2/qux
|
||||
baz/3/qux
|
||||
```
|
||||
|
||||
## Brace matching pitfalls
|
||||
|
||||
Although brace patterns offer a user-friendly way of matching ranges or sets of strings, there are also some major disadvantages and potential risks you should be aware of.
|
||||
|
||||
### tldr
|
||||
|
||||
**"brace bombs"**
|
||||
|
||||
* brace expansion can eat up a huge amount of processing resources
|
||||
* as brace patterns increase _linearly in size_, the system resources required to expand the pattern increase exponentially
|
||||
* users can accidentally (or intentially) exhaust your system's resources resulting in the equivalent of a DoS attack (bonus: no programming knowledge is required!)
|
||||
|
||||
For a more detailed explanation with examples, see the [geometric complexity](#geometric-complexity) section.
|
||||
|
||||
### The solution
|
||||
|
||||
Jump to the [performance section](#performance) to see how Braces solves this problem in comparison to other libraries.
|
||||
|
||||
### Geometric complexity
|
||||
|
||||
At minimum, brace patterns with sets limited to two elements have quadradic or `O(n^2)` complexity. But the complexity of the algorithm increases exponentially as the number of sets, _and elements per set_, increases, which is `O(n^c)`.
|
||||
|
||||
For example, the following sets demonstrate quadratic (`O(n^2)`) complexity:
|
||||
|
||||
```
|
||||
{1,2}{3,4} => (2X2) => 13 14 23 24
|
||||
{1,2}{3,4}{5,6} => (2X2X2) => 135 136 145 146 235 236 245 246
|
||||
```
|
||||
|
||||
But add an element to a set, and we get a n-fold Cartesian product with `O(n^c)` complexity:
|
||||
|
||||
```
|
||||
{1,2,3}{4,5,6}{7,8,9} => (3X3X3) => 147 148 149 157 158 159 167 168 169 247 248
|
||||
249 257 258 259 267 268 269 347 348 349 357
|
||||
358 359 367 368 369
|
||||
```
|
||||
|
||||
Now, imagine how this complexity grows given that each element is a n-tuple:
|
||||
|
||||
```
|
||||
{1..100}{1..100} => (100X100) => 10,000 elements (38.4 kB)
|
||||
{1..100}{1..100}{1..100} => (100X100X100) => 1,000,000 elements (5.76 MB)
|
||||
```
|
||||
|
||||
Although these examples are clearly contrived, they demonstrate how brace patterns can quickly grow out of control.
|
||||
|
||||
**More information**
|
||||
|
||||
Interested in learning more about brace expansion?
|
||||
|
||||
* [linuxjournal/bash-brace-expansion](http://www.linuxjournal.com/content/bash-brace-expansion)
|
||||
* [rosettacode/Brace_expansion](https://rosettacode.org/wiki/Brace_expansion)
|
||||
* [cartesian product](https://en.wikipedia.org/wiki/Cartesian_product)
|
||||
|
||||
</details>
|
||||
|
||||
## Performance
|
||||
|
||||
Braces is not only screaming fast, it's also more accurate the other brace expansion libraries.
|
||||
|
||||
### Better algorithms
|
||||
|
||||
Fortunately there is a solution to the ["brace bomb" problem](#brace-matching-pitfalls): _don't expand brace patterns into an array when they're used for matching_.
|
||||
|
||||
Instead, convert the pattern into an optimized regular expression. This is easier said than done, and braces is the only library that does this currently.
|
||||
|
||||
**The proof is in the numbers**
|
||||
|
||||
Minimatch gets exponentially slower as patterns increase in complexity, braces does not. The following results were generated using `braces()` and `minimatch.braceExpand()`, respectively.
|
||||
|
||||
| **Pattern** | **braces** | **[minimatch][]** |
|
||||
| --- | --- | --- |
|
||||
| `{1..9007199254740991}`[^1] | `298 B` (5ms 459μs)| N/A (freezes) |
|
||||
| `{1..1000000000000000}` | `41 B` (1ms 15μs) | N/A (freezes) |
|
||||
| `{1..100000000000000}` | `40 B` (890μs) | N/A (freezes) |
|
||||
| `{1..10000000000000}` | `39 B` (2ms 49μs) | N/A (freezes) |
|
||||
| `{1..1000000000000}` | `38 B` (608μs) | N/A (freezes) |
|
||||
| `{1..100000000000}` | `37 B` (397μs) | N/A (freezes) |
|
||||
| `{1..10000000000}` | `35 B` (983μs) | N/A (freezes) |
|
||||
| `{1..1000000000}` | `34 B` (798μs) | N/A (freezes) |
|
||||
| `{1..100000000}` | `33 B` (733μs) | N/A (freezes) |
|
||||
| `{1..10000000}` | `32 B` (5ms 632μs) | `78.89 MB` (16s 388ms 569μs) |
|
||||
| `{1..1000000}` | `31 B` (1ms 381μs) | `6.89 MB` (1s 496ms 887μs) |
|
||||
| `{1..100000}` | `30 B` (950μs) | `588.89 kB` (146ms 921μs) |
|
||||
| `{1..10000}` | `29 B` (1ms 114μs) | `48.89 kB` (14ms 187μs) |
|
||||
| `{1..1000}` | `28 B` (760μs) | `3.89 kB` (1ms 453μs) |
|
||||
| `{1..100}` | `22 B` (345μs) | `291 B` (196μs) |
|
||||
| `{1..10}` | `10 B` (533μs) | `20 B` (37μs) |
|
||||
| `{1..3}` | `7 B` (190μs) | `5 B` (27μs) |
|
||||
|
||||
### Faster algorithms
|
||||
|
||||
When you need expansion, braces is still much faster.
|
||||
|
||||
_(the following results were generated using `braces.expand()` and `minimatch.braceExpand()`, respectively)_
|
||||
|
||||
| **Pattern** | **braces** | **[minimatch][]** |
|
||||
| --- | --- | --- |
|
||||
| `{1..10000000}` | `78.89 MB` (2s 698ms 642μs) | `78.89 MB` (18s 601ms 974μs) |
|
||||
| `{1..1000000}` | `6.89 MB` (458ms 576μs) | `6.89 MB` (1s 491ms 621μs) |
|
||||
| `{1..100000}` | `588.89 kB` (20ms 728μs) | `588.89 kB` (156ms 919μs) |
|
||||
| `{1..10000}` | `48.89 kB` (2ms 202μs) | `48.89 kB` (13ms 641μs) |
|
||||
| `{1..1000}` | `3.89 kB` (1ms 796μs) | `3.89 kB` (1ms 958μs) |
|
||||
| `{1..100}` | `291 B` (424μs) | `291 B` (211μs) |
|
||||
| `{1..10}` | `20 B` (487μs) | `20 B` (72μs) |
|
||||
| `{1..3}` | `5 B` (166μs) | `5 B` (27μs) |
|
||||
|
||||
If you'd like to run these comparisons yourself, see [test/support/generate.js](test/support/generate.js).
|
||||
|
||||
## Benchmarks
|
||||
|
||||
### Running benchmarks
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm benchmark
|
||||
```
|
||||
|
||||
### Latest results
|
||||
|
||||
Braces is more accurate, without sacrificing performance.
|
||||
|
||||
```bash
|
||||
# range (expanded)
|
||||
braces x 29,040 ops/sec ±3.69% (91 runs sampled))
|
||||
minimatch x 4,735 ops/sec ±1.28% (90 runs sampled)
|
||||
|
||||
# range (optimized for regex)
|
||||
braces x 382,878 ops/sec ±0.56% (94 runs sampled)
|
||||
minimatch x 1,040 ops/sec ±0.44% (93 runs sampled)
|
||||
|
||||
# nested ranges (expanded)
|
||||
braces x 19,744 ops/sec ±2.27% (92 runs sampled))
|
||||
minimatch x 4,579 ops/sec ±0.50% (93 runs sampled)
|
||||
|
||||
# nested ranges (optimized for regex)
|
||||
braces x 246,019 ops/sec ±2.02% (93 runs sampled)
|
||||
minimatch x 1,028 ops/sec ±0.39% (94 runs sampled)
|
||||
|
||||
# set (expanded)
|
||||
braces x 138,641 ops/sec ±0.53% (95 runs sampled)
|
||||
minimatch x 219,582 ops/sec ±0.98% (94 runs sampled)
|
||||
|
||||
# set (optimized for regex)
|
||||
braces x 388,408 ops/sec ±0.41% (95 runs sampled)
|
||||
minimatch x 44,724 ops/sec ±0.91% (89 runs sampled)
|
||||
|
||||
# nested sets (expanded)
|
||||
braces x 84,966 ops/sec ±0.48% (94 runs sampled)
|
||||
minimatch x 140,720 ops/sec ±0.37% (95 runs sampled)
|
||||
|
||||
# nested sets (optimized for regex)
|
||||
braces x 263,340 ops/sec ±2.06% (92 runs sampled)
|
||||
minimatch x 28,714 ops/sec ±0.40% (90 runs sampled)
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
<details>
|
||||
<summary><strong>Contributing</strong></summary>
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Running Tests</strong></summary>
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Building docs</strong></summary>
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 197 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 4 | [doowb](https://github.com/doowb) |
|
||||
| 1 | [es128](https://github.com/es128) |
|
||||
| 1 | [eush77](https://github.com/eush77) |
|
||||
| 1 | [hemanth](https://github.com/hemanth) |
|
||||
| 1 | [wtgtybhertgeghgtwtg](https://github.com/wtgtybhertgeghgtwtg) |
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [GitHub Profile](https://github.com/jonschlinkert)
|
||||
* [Twitter Profile](https://twitter.com/jonschlinkert)
|
||||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2019, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on April 08, 2019._
|
||||
170
node_modules/.store/chokidar@3.5.3/node_modules/braces/index.js
generated
vendored
Normal file
170
node_modules/.store/chokidar@3.5.3/node_modules/braces/index.js
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
const stringify = require('./lib/stringify');
|
||||
const compile = require('./lib/compile');
|
||||
const expand = require('./lib/expand');
|
||||
const parse = require('./lib/parse');
|
||||
|
||||
/**
|
||||
* Expand the given pattern or create a regex-compatible string.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
|
||||
* console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
|
||||
* ```
|
||||
* @param {String} `str`
|
||||
* @param {Object} `options`
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
const braces = (input, options = {}) => {
|
||||
let output = [];
|
||||
|
||||
if (Array.isArray(input)) {
|
||||
for (let pattern of input) {
|
||||
let result = braces.create(pattern, options);
|
||||
if (Array.isArray(result)) {
|
||||
output.push(...result);
|
||||
} else {
|
||||
output.push(result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output = [].concat(braces.create(input, options));
|
||||
}
|
||||
|
||||
if (options && options.expand === true && options.nodupes === true) {
|
||||
output = [...new Set(output)];
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` with the given `options`.
|
||||
*
|
||||
* ```js
|
||||
* // braces.parse(pattern, [, options]);
|
||||
* const ast = braces.parse('a/{b,c}/d');
|
||||
* console.log(ast);
|
||||
* ```
|
||||
* @param {String} pattern Brace pattern to parse
|
||||
* @param {Object} options
|
||||
* @return {Object} Returns an AST
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.parse = (input, options = {}) => parse(input, options);
|
||||
|
||||
/**
|
||||
* Creates a braces string from an AST, or an AST node.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* let ast = braces.parse('foo/{a,b}/bar');
|
||||
* console.log(stringify(ast.nodes[2])); //=> '{a,b}'
|
||||
* ```
|
||||
* @param {String} `input` Brace pattern or AST.
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.stringify = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
return stringify(braces.parse(input, options), options);
|
||||
}
|
||||
return stringify(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Compiles a brace pattern into a regex-compatible, optimized string.
|
||||
* This method is called by the main [braces](#braces) function by default.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.compile('a/{b,c}/d'));
|
||||
* //=> ['a/(b|c)/d']
|
||||
* ```
|
||||
* @param {String} `input` Brace pattern or AST.
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.compile = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
input = braces.parse(input, options);
|
||||
}
|
||||
return compile(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expands a brace pattern into an array. This method is called by the
|
||||
* main [braces](#braces) function when `options.expand` is true. Before
|
||||
* using this method it's recommended that you read the [performance notes](#performance))
|
||||
* and advantages of using [.compile](#compile) instead.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.expand('a/{b,c}/d'));
|
||||
* //=> ['a/b/d', 'a/c/d'];
|
||||
* ```
|
||||
* @param {String} `pattern` Brace pattern
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.expand = (input, options = {}) => {
|
||||
if (typeof input === 'string') {
|
||||
input = braces.parse(input, options);
|
||||
}
|
||||
|
||||
let result = expand(input, options);
|
||||
|
||||
// filter out empty strings if specified
|
||||
if (options.noempty === true) {
|
||||
result = result.filter(Boolean);
|
||||
}
|
||||
|
||||
// filter out duplicates if specified
|
||||
if (options.nodupes === true) {
|
||||
result = [...new Set(result)];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes a brace pattern and returns either an expanded array
|
||||
* (if `options.expand` is true), a highly optimized regex-compatible string.
|
||||
* This method is called by the main [braces](#braces) function.
|
||||
*
|
||||
* ```js
|
||||
* const braces = require('braces');
|
||||
* console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
|
||||
* //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
|
||||
* ```
|
||||
* @param {String} `pattern` Brace pattern
|
||||
* @param {Object} `options`
|
||||
* @return {Array} Returns an array of expanded values.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
braces.create = (input, options = {}) => {
|
||||
if (input === '' || input.length < 3) {
|
||||
return [input];
|
||||
}
|
||||
|
||||
return options.expand !== true
|
||||
? braces.compile(input, options)
|
||||
: braces.expand(input, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose "braces"
|
||||
*/
|
||||
|
||||
module.exports = braces;
|
||||
57
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/compile.js
generated
vendored
Normal file
57
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/compile.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
const fill = require('fill-range');
|
||||
const utils = require('./utils');
|
||||
|
||||
const compile = (ast, options = {}) => {
|
||||
let walk = (node, parent = {}) => {
|
||||
let invalidBlock = utils.isInvalidBrace(parent);
|
||||
let invalidNode = node.invalid === true && options.escapeInvalid === true;
|
||||
let invalid = invalidBlock === true || invalidNode === true;
|
||||
let prefix = options.escapeInvalid === true ? '\\' : '';
|
||||
let output = '';
|
||||
|
||||
if (node.isOpen === true) {
|
||||
return prefix + node.value;
|
||||
}
|
||||
if (node.isClose === true) {
|
||||
return prefix + node.value;
|
||||
}
|
||||
|
||||
if (node.type === 'open') {
|
||||
return invalid ? (prefix + node.value) : '(';
|
||||
}
|
||||
|
||||
if (node.type === 'close') {
|
||||
return invalid ? (prefix + node.value) : ')';
|
||||
}
|
||||
|
||||
if (node.type === 'comma') {
|
||||
return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|');
|
||||
}
|
||||
|
||||
if (node.value) {
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.nodes && node.ranges > 0) {
|
||||
let args = utils.reduce(node.nodes);
|
||||
let range = fill(...args, { ...options, wrap: false, toRegex: true });
|
||||
|
||||
if (range.length !== 0) {
|
||||
return args.length > 1 && range.length > 1 ? `(${range})` : range;
|
||||
}
|
||||
}
|
||||
|
||||
if (node.nodes) {
|
||||
for (let child of node.nodes) {
|
||||
output += walk(child, node);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
return walk(ast);
|
||||
};
|
||||
|
||||
module.exports = compile;
|
||||
57
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/constants.js
generated
vendored
Normal file
57
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/constants.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
MAX_LENGTH: 1024 * 64,
|
||||
|
||||
// Digits
|
||||
CHAR_0: '0', /* 0 */
|
||||
CHAR_9: '9', /* 9 */
|
||||
|
||||
// Alphabet chars.
|
||||
CHAR_UPPERCASE_A: 'A', /* A */
|
||||
CHAR_LOWERCASE_A: 'a', /* a */
|
||||
CHAR_UPPERCASE_Z: 'Z', /* Z */
|
||||
CHAR_LOWERCASE_Z: 'z', /* z */
|
||||
|
||||
CHAR_LEFT_PARENTHESES: '(', /* ( */
|
||||
CHAR_RIGHT_PARENTHESES: ')', /* ) */
|
||||
|
||||
CHAR_ASTERISK: '*', /* * */
|
||||
|
||||
// Non-alphabetic chars.
|
||||
CHAR_AMPERSAND: '&', /* & */
|
||||
CHAR_AT: '@', /* @ */
|
||||
CHAR_BACKSLASH: '\\', /* \ */
|
||||
CHAR_BACKTICK: '`', /* ` */
|
||||
CHAR_CARRIAGE_RETURN: '\r', /* \r */
|
||||
CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
|
||||
CHAR_COLON: ':', /* : */
|
||||
CHAR_COMMA: ',', /* , */
|
||||
CHAR_DOLLAR: '$', /* . */
|
||||
CHAR_DOT: '.', /* . */
|
||||
CHAR_DOUBLE_QUOTE: '"', /* " */
|
||||
CHAR_EQUAL: '=', /* = */
|
||||
CHAR_EXCLAMATION_MARK: '!', /* ! */
|
||||
CHAR_FORM_FEED: '\f', /* \f */
|
||||
CHAR_FORWARD_SLASH: '/', /* / */
|
||||
CHAR_HASH: '#', /* # */
|
||||
CHAR_HYPHEN_MINUS: '-', /* - */
|
||||
CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
|
||||
CHAR_LEFT_CURLY_BRACE: '{', /* { */
|
||||
CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
|
||||
CHAR_LINE_FEED: '\n', /* \n */
|
||||
CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
|
||||
CHAR_PERCENT: '%', /* % */
|
||||
CHAR_PLUS: '+', /* + */
|
||||
CHAR_QUESTION_MARK: '?', /* ? */
|
||||
CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
|
||||
CHAR_RIGHT_CURLY_BRACE: '}', /* } */
|
||||
CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
|
||||
CHAR_SEMICOLON: ';', /* ; */
|
||||
CHAR_SINGLE_QUOTE: '\'', /* ' */
|
||||
CHAR_SPACE: ' ', /* */
|
||||
CHAR_TAB: '\t', /* \t */
|
||||
CHAR_UNDERSCORE: '_', /* _ */
|
||||
CHAR_VERTICAL_LINE: '|', /* | */
|
||||
CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
|
||||
};
|
||||
113
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/expand.js
generated
vendored
Normal file
113
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/expand.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
const fill = require('fill-range');
|
||||
const stringify = require('./stringify');
|
||||
const utils = require('./utils');
|
||||
|
||||
const append = (queue = '', stash = '', enclose = false) => {
|
||||
let result = [];
|
||||
|
||||
queue = [].concat(queue);
|
||||
stash = [].concat(stash);
|
||||
|
||||
if (!stash.length) return queue;
|
||||
if (!queue.length) {
|
||||
return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
|
||||
}
|
||||
|
||||
for (let item of queue) {
|
||||
if (Array.isArray(item)) {
|
||||
for (let value of item) {
|
||||
result.push(append(value, stash, enclose));
|
||||
}
|
||||
} else {
|
||||
for (let ele of stash) {
|
||||
if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
|
||||
result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
|
||||
}
|
||||
}
|
||||
}
|
||||
return utils.flatten(result);
|
||||
};
|
||||
|
||||
const expand = (ast, options = {}) => {
|
||||
let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
|
||||
|
||||
let walk = (node, parent = {}) => {
|
||||
node.queue = [];
|
||||
|
||||
let p = parent;
|
||||
let q = parent.queue;
|
||||
|
||||
while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
|
||||
p = p.parent;
|
||||
q = p.queue;
|
||||
}
|
||||
|
||||
if (node.invalid || node.dollar) {
|
||||
q.push(append(q.pop(), stringify(node, options)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
|
||||
q.push(append(q.pop(), ['{}']));
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.nodes && node.ranges > 0) {
|
||||
let args = utils.reduce(node.nodes);
|
||||
|
||||
if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
|
||||
throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
|
||||
}
|
||||
|
||||
let range = fill(...args, options);
|
||||
if (range.length === 0) {
|
||||
range = stringify(node, options);
|
||||
}
|
||||
|
||||
q.push(append(q.pop(), range));
|
||||
node.nodes = [];
|
||||
return;
|
||||
}
|
||||
|
||||
let enclose = utils.encloseBrace(node);
|
||||
let queue = node.queue;
|
||||
let block = node;
|
||||
|
||||
while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
|
||||
block = block.parent;
|
||||
queue = block.queue;
|
||||
}
|
||||
|
||||
for (let i = 0; i < node.nodes.length; i++) {
|
||||
let child = node.nodes[i];
|
||||
|
||||
if (child.type === 'comma' && node.type === 'brace') {
|
||||
if (i === 1) queue.push('');
|
||||
queue.push('');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.type === 'close') {
|
||||
q.push(append(q.pop(), queue, enclose));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.value && child.type !== 'open') {
|
||||
queue.push(append(queue.pop(), child.value));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.nodes) {
|
||||
walk(child, node);
|
||||
}
|
||||
}
|
||||
|
||||
return queue;
|
||||
};
|
||||
|
||||
return utils.flatten(walk(ast));
|
||||
};
|
||||
|
||||
module.exports = expand;
|
||||
333
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/parse.js
generated
vendored
Normal file
333
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/parse.js
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
'use strict';
|
||||
|
||||
const stringify = require('./stringify');
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const {
|
||||
MAX_LENGTH,
|
||||
CHAR_BACKSLASH, /* \ */
|
||||
CHAR_BACKTICK, /* ` */
|
||||
CHAR_COMMA, /* , */
|
||||
CHAR_DOT, /* . */
|
||||
CHAR_LEFT_PARENTHESES, /* ( */
|
||||
CHAR_RIGHT_PARENTHESES, /* ) */
|
||||
CHAR_LEFT_CURLY_BRACE, /* { */
|
||||
CHAR_RIGHT_CURLY_BRACE, /* } */
|
||||
CHAR_LEFT_SQUARE_BRACKET, /* [ */
|
||||
CHAR_RIGHT_SQUARE_BRACKET, /* ] */
|
||||
CHAR_DOUBLE_QUOTE, /* " */
|
||||
CHAR_SINGLE_QUOTE, /* ' */
|
||||
CHAR_NO_BREAK_SPACE,
|
||||
CHAR_ZERO_WIDTH_NOBREAK_SPACE
|
||||
} = require('./constants');
|
||||
|
||||
/**
|
||||
* parse
|
||||
*/
|
||||
|
||||
const parse = (input, options = {}) => {
|
||||
if (typeof input !== 'string') {
|
||||
throw new TypeError('Expected a string');
|
||||
}
|
||||
|
||||
let opts = options || {};
|
||||
let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
|
||||
if (input.length > max) {
|
||||
throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
|
||||
}
|
||||
|
||||
let ast = { type: 'root', input, nodes: [] };
|
||||
let stack = [ast];
|
||||
let block = ast;
|
||||
let prev = ast;
|
||||
let brackets = 0;
|
||||
let length = input.length;
|
||||
let index = 0;
|
||||
let depth = 0;
|
||||
let value;
|
||||
let memo = {};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
const advance = () => input[index++];
|
||||
const push = node => {
|
||||
if (node.type === 'text' && prev.type === 'dot') {
|
||||
prev.type = 'text';
|
||||
}
|
||||
|
||||
if (prev && prev.type === 'text' && node.type === 'text') {
|
||||
prev.value += node.value;
|
||||
return;
|
||||
}
|
||||
|
||||
block.nodes.push(node);
|
||||
node.parent = block;
|
||||
node.prev = prev;
|
||||
prev = node;
|
||||
return node;
|
||||
};
|
||||
|
||||
push({ type: 'bos' });
|
||||
|
||||
while (index < length) {
|
||||
block = stack[stack.length - 1];
|
||||
value = advance();
|
||||
|
||||
/**
|
||||
* Invalid chars
|
||||
*/
|
||||
|
||||
if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escaped chars
|
||||
*/
|
||||
|
||||
if (value === CHAR_BACKSLASH) {
|
||||
push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right square bracket (literal): ']'
|
||||
*/
|
||||
|
||||
if (value === CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
push({ type: 'text', value: '\\' + value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left square bracket: '['
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_SQUARE_BRACKET) {
|
||||
brackets++;
|
||||
|
||||
let closed = true;
|
||||
let next;
|
||||
|
||||
while (index < length && (next = advance())) {
|
||||
value += next;
|
||||
|
||||
if (next === CHAR_LEFT_SQUARE_BRACKET) {
|
||||
brackets++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === CHAR_BACKSLASH) {
|
||||
value += advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
|
||||
brackets--;
|
||||
|
||||
if (brackets === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parentheses
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_PARENTHESES) {
|
||||
block = push({ type: 'paren', nodes: [] });
|
||||
stack.push(block);
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value === CHAR_RIGHT_PARENTHESES) {
|
||||
if (block.type !== 'paren') {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
block = stack.pop();
|
||||
push({ type: 'text', value });
|
||||
block = stack[stack.length - 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotes: '|"|`
|
||||
*/
|
||||
|
||||
if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
|
||||
let open = value;
|
||||
let next;
|
||||
|
||||
if (options.keepQuotes !== true) {
|
||||
value = '';
|
||||
}
|
||||
|
||||
while (index < length && (next = advance())) {
|
||||
if (next === CHAR_BACKSLASH) {
|
||||
value += next + advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next === open) {
|
||||
if (options.keepQuotes === true) value += next;
|
||||
break;
|
||||
}
|
||||
|
||||
value += next;
|
||||
}
|
||||
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Left curly brace: '{'
|
||||
*/
|
||||
|
||||
if (value === CHAR_LEFT_CURLY_BRACE) {
|
||||
depth++;
|
||||
|
||||
let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
|
||||
let brace = {
|
||||
type: 'brace',
|
||||
open: true,
|
||||
close: false,
|
||||
dollar,
|
||||
depth,
|
||||
commas: 0,
|
||||
ranges: 0,
|
||||
nodes: []
|
||||
};
|
||||
|
||||
block = push(brace);
|
||||
stack.push(block);
|
||||
push({ type: 'open', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right curly brace: '}'
|
||||
*/
|
||||
|
||||
if (value === CHAR_RIGHT_CURLY_BRACE) {
|
||||
if (block.type !== 'brace') {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
let type = 'close';
|
||||
block = stack.pop();
|
||||
block.close = true;
|
||||
|
||||
push({ type, value });
|
||||
depth--;
|
||||
|
||||
block = stack[stack.length - 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comma: ','
|
||||
*/
|
||||
|
||||
if (value === CHAR_COMMA && depth > 0) {
|
||||
if (block.ranges > 0) {
|
||||
block.ranges = 0;
|
||||
let open = block.nodes.shift();
|
||||
block.nodes = [open, { type: 'text', value: stringify(block) }];
|
||||
}
|
||||
|
||||
push({ type: 'comma', value });
|
||||
block.commas++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dot: '.'
|
||||
*/
|
||||
|
||||
if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
|
||||
let siblings = block.nodes;
|
||||
|
||||
if (depth === 0 || siblings.length === 0) {
|
||||
push({ type: 'text', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.type === 'dot') {
|
||||
block.range = [];
|
||||
prev.value += value;
|
||||
prev.type = 'range';
|
||||
|
||||
if (block.nodes.length !== 3 && block.nodes.length !== 5) {
|
||||
block.invalid = true;
|
||||
block.ranges = 0;
|
||||
prev.type = 'text';
|
||||
continue;
|
||||
}
|
||||
|
||||
block.ranges++;
|
||||
block.args = [];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.type === 'range') {
|
||||
siblings.pop();
|
||||
|
||||
let before = siblings[siblings.length - 1];
|
||||
before.value += prev.value + value;
|
||||
prev = before;
|
||||
block.ranges--;
|
||||
continue;
|
||||
}
|
||||
|
||||
push({ type: 'dot', value });
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Text
|
||||
*/
|
||||
|
||||
push({ type: 'text', value });
|
||||
}
|
||||
|
||||
// Mark imbalanced braces and brackets as invalid
|
||||
do {
|
||||
block = stack.pop();
|
||||
|
||||
if (block.type !== 'root') {
|
||||
block.nodes.forEach(node => {
|
||||
if (!node.nodes) {
|
||||
if (node.type === 'open') node.isOpen = true;
|
||||
if (node.type === 'close') node.isClose = true;
|
||||
if (!node.nodes) node.type = 'text';
|
||||
node.invalid = true;
|
||||
}
|
||||
});
|
||||
|
||||
// get the location of the block on parent.nodes (block's siblings)
|
||||
let parent = stack[stack.length - 1];
|
||||
let index = parent.nodes.indexOf(block);
|
||||
// replace the (invalid) block with it's nodes
|
||||
parent.nodes.splice(index, 1, ...block.nodes);
|
||||
}
|
||||
} while (stack.length > 0);
|
||||
|
||||
push({ type: 'eos' });
|
||||
return ast;
|
||||
};
|
||||
|
||||
module.exports = parse;
|
||||
32
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/stringify.js
generated
vendored
Normal file
32
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/stringify.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const utils = require('./utils');
|
||||
|
||||
module.exports = (ast, options = {}) => {
|
||||
let stringify = (node, parent = {}) => {
|
||||
let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
|
||||
let invalidNode = node.invalid === true && options.escapeInvalid === true;
|
||||
let output = '';
|
||||
|
||||
if (node.value) {
|
||||
if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
|
||||
return '\\' + node.value;
|
||||
}
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.value) {
|
||||
return node.value;
|
||||
}
|
||||
|
||||
if (node.nodes) {
|
||||
for (let child of node.nodes) {
|
||||
output += stringify(child);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
return stringify(ast);
|
||||
};
|
||||
|
||||
112
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/utils.js
generated
vendored
Normal file
112
node_modules/.store/chokidar@3.5.3/node_modules/braces/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
exports.isInteger = num => {
|
||||
if (typeof num === 'number') {
|
||||
return Number.isInteger(num);
|
||||
}
|
||||
if (typeof num === 'string' && num.trim() !== '') {
|
||||
return Number.isInteger(Number(num));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a node of the given type
|
||||
*/
|
||||
|
||||
exports.find = (node, type) => node.nodes.find(node => node.type === type);
|
||||
|
||||
/**
|
||||
* Find a node of the given type
|
||||
*/
|
||||
|
||||
exports.exceedsLimit = (min, max, step = 1, limit) => {
|
||||
if (limit === false) return false;
|
||||
if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
|
||||
return ((Number(max) - Number(min)) / Number(step)) >= limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape the given node with '\\' before node.value
|
||||
*/
|
||||
|
||||
exports.escapeNode = (block, n = 0, type) => {
|
||||
let node = block.nodes[n];
|
||||
if (!node) return;
|
||||
|
||||
if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
|
||||
if (node.escaped !== true) {
|
||||
node.value = '\\' + node.value;
|
||||
node.escaped = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the given brace node should be enclosed in literal braces
|
||||
*/
|
||||
|
||||
exports.encloseBrace = node => {
|
||||
if (node.type !== 'brace') return false;
|
||||
if ((node.commas >> 0 + node.ranges >> 0) === 0) {
|
||||
node.invalid = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if a brace node is invalid.
|
||||
*/
|
||||
|
||||
exports.isInvalidBrace = block => {
|
||||
if (block.type !== 'brace') return false;
|
||||
if (block.invalid === true || block.dollar) return true;
|
||||
if ((block.commas >> 0 + block.ranges >> 0) === 0) {
|
||||
block.invalid = true;
|
||||
return true;
|
||||
}
|
||||
if (block.open !== true || block.close !== true) {
|
||||
block.invalid = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if a node is an open or close node
|
||||
*/
|
||||
|
||||
exports.isOpenOrClose = node => {
|
||||
if (node.type === 'open' || node.type === 'close') {
|
||||
return true;
|
||||
}
|
||||
return node.open === true || node.close === true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reduce an array of text nodes.
|
||||
*/
|
||||
|
||||
exports.reduce = nodes => nodes.reduce((acc, node) => {
|
||||
if (node.type === 'text') acc.push(node.value);
|
||||
if (node.type === 'range') node.type = 'text';
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Flatten an array
|
||||
*/
|
||||
|
||||
exports.flatten = (...args) => {
|
||||
const result = [];
|
||||
const flat = arr => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let ele = arr[i];
|
||||
Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
flat(args);
|
||||
return result;
|
||||
};
|
||||
80
node_modules/.store/chokidar@3.5.3/node_modules/braces/package.json
generated
vendored
Normal file
80
node_modules/.store/chokidar@3.5.3/node_modules/braces/package.json
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "braces",
|
||||
"description": "Bash-like brace expansion, implemented in JavaScript. Safer than other brace expansion libs, with complete support for the Bash 4.3 braces specification, without sacrificing speed.",
|
||||
"version": "3.0.2",
|
||||
"homepage": "https://github.com/micromatch/braces",
|
||||
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
|
||||
"contributors": [
|
||||
"Brian Woodward (https://twitter.com/doowb)",
|
||||
"Elan Shanker (https://github.com/es128)",
|
||||
"Eugene Sharygin (https://github.com/eush77)",
|
||||
"hemanth.hm (http://h3manth.com)",
|
||||
"Jon Schlinkert (http://twitter.com/jonschlinkert)"
|
||||
],
|
||||
"repository": "micromatch/braces",
|
||||
"bugs": {
|
||||
"url": "https://github.com/micromatch/braces/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"benchmark": "node benchmark"
|
||||
},
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ansi-colors": "^3.2.4",
|
||||
"bash-path": "^2.0.1",
|
||||
"gulp-format-md": "^2.0.0",
|
||||
"mocha": "^6.1.1"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"bash",
|
||||
"brace",
|
||||
"braces",
|
||||
"expand",
|
||||
"expansion",
|
||||
"filepath",
|
||||
"fill",
|
||||
"fs",
|
||||
"glob",
|
||||
"globbing",
|
||||
"letter",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"path",
|
||||
"range",
|
||||
"ranges",
|
||||
"sh"
|
||||
],
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
},
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
]
|
||||
},
|
||||
"__npminstall_done": true,
|
||||
"_from": "braces@3.0.2",
|
||||
"_resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz"
|
||||
}
|
||||
21
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/LICENSE
generated
vendored
Normal file
21
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker
|
||||
|
||||
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.
|
||||
308
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/README.md
generated
vendored
Normal file
308
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/README.md
generated
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
# Chokidar [](https://github.com/paulmillr/chokidar) [](https://github.com/paulmillr/chokidar)
|
||||
|
||||
> Minimal and efficient cross-platform file watching library
|
||||
|
||||
[](https://www.npmjs.com/package/chokidar)
|
||||
|
||||
## Why?
|
||||
|
||||
Node.js `fs.watch`:
|
||||
|
||||
* Doesn't report filenames on MacOS.
|
||||
* Doesn't report events at all when using editors like Sublime on MacOS.
|
||||
* Often reports events twice.
|
||||
* Emits most changes as `rename`.
|
||||
* Does not provide an easy way to recursively watch file trees.
|
||||
* Does not support recursive watching on Linux.
|
||||
|
||||
Node.js `fs.watchFile`:
|
||||
|
||||
* Almost as bad at event handling.
|
||||
* Also does not provide any recursive watching.
|
||||
* Results in high CPU utilization.
|
||||
|
||||
Chokidar resolves these problems.
|
||||
|
||||
Initially made for **[Brunch](https://brunch.io/)** (an ultra-swift web app build tool), it is now used in
|
||||
[Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
|
||||
[gulp](https://github.com/gulpjs/gulp/),
|
||||
[karma](https://karma-runner.github.io/),
|
||||
[PM2](https://github.com/Unitech/PM2),
|
||||
[browserify](http://browserify.org/),
|
||||
[webpack](https://webpack.github.io/),
|
||||
[BrowserSync](https://www.browsersync.io/),
|
||||
and [many others](https://www.npmjs.com/browse/depended/chokidar).
|
||||
It has proven itself in production environments.
|
||||
|
||||
Version 3 is out! Check out our blog post about it: [Chokidar 3: How to save 32TB of traffic every week](https://paulmillr.com/posts/chokidar-3-save-32tb-of-traffic/)
|
||||
|
||||
## How?
|
||||
|
||||
Chokidar does still rely on the Node.js core `fs` module, but when using
|
||||
`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
|
||||
receives, often checking for truth by getting file stats and/or dir contents.
|
||||
|
||||
On MacOS, chokidar by default uses a native extension exposing the Darwin
|
||||
`FSEvents` API. This provides very efficient recursive watching compared with
|
||||
implementations like `kqueue` available on most \*nix platforms. Chokidar still
|
||||
does have to do some work to normalize the events received that way as well.
|
||||
|
||||
On most other platforms, the `fs.watch`-based implementation is the default, which
|
||||
avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
|
||||
watchers recursively for everything within scope of the paths that have been
|
||||
specified, so be judicious about not wasting system resources by watching much
|
||||
more than needed.
|
||||
|
||||
## Getting started
|
||||
|
||||
Install with npm:
|
||||
|
||||
```sh
|
||||
npm install chokidar
|
||||
```
|
||||
|
||||
Then `require` and use it in your code:
|
||||
|
||||
```javascript
|
||||
const chokidar = require('chokidar');
|
||||
|
||||
// One-liner for current directory
|
||||
chokidar.watch('.').on('all', (event, path) => {
|
||||
console.log(event, path);
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```javascript
|
||||
// Example of a more typical implementation structure
|
||||
|
||||
// Initialize watcher.
|
||||
const watcher = chokidar.watch('file, dir, glob, or array', {
|
||||
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
||||
persistent: true
|
||||
});
|
||||
|
||||
// Something to use when events are received.
|
||||
const log = console.log.bind(console);
|
||||
// Add event listeners.
|
||||
watcher
|
||||
.on('add', path => log(`File ${path} has been added`))
|
||||
.on('change', path => log(`File ${path} has been changed`))
|
||||
.on('unlink', path => log(`File ${path} has been removed`));
|
||||
|
||||
// More possible events.
|
||||
watcher
|
||||
.on('addDir', path => log(`Directory ${path} has been added`))
|
||||
.on('unlinkDir', path => log(`Directory ${path} has been removed`))
|
||||
.on('error', error => log(`Watcher error: ${error}`))
|
||||
.on('ready', () => log('Initial scan complete. Ready for changes'))
|
||||
.on('raw', (event, path, details) => { // internal
|
||||
log('Raw event info:', event, path, details);
|
||||
});
|
||||
|
||||
// 'add', 'addDir' and 'change' events also receive stat() results as second
|
||||
// argument when available: https://nodejs.org/api/fs.html#fs_class_fs_stats
|
||||
watcher.on('change', (path, stats) => {
|
||||
if (stats) console.log(`File ${path} changed size to ${stats.size}`);
|
||||
});
|
||||
|
||||
// Watch new files.
|
||||
watcher.add('new-file');
|
||||
watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
|
||||
|
||||
// Get list of actual paths being watched on the filesystem
|
||||
var watchedPaths = watcher.getWatched();
|
||||
|
||||
// Un-watch some files.
|
||||
await watcher.unwatch('new-file*');
|
||||
|
||||
// Stop watching.
|
||||
// The method is async!
|
||||
watcher.close().then(() => console.log('closed'));
|
||||
|
||||
// Full list of options. See below for descriptions.
|
||||
// Do not use this example!
|
||||
chokidar.watch('file', {
|
||||
persistent: true,
|
||||
|
||||
ignored: '*.txt',
|
||||
ignoreInitial: false,
|
||||
followSymlinks: true,
|
||||
cwd: '.',
|
||||
disableGlobbing: false,
|
||||
|
||||
usePolling: false,
|
||||
interval: 100,
|
||||
binaryInterval: 300,
|
||||
alwaysStat: false,
|
||||
depth: 99,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 2000,
|
||||
pollInterval: 100
|
||||
},
|
||||
|
||||
ignorePermissionErrors: false,
|
||||
atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
`chokidar.watch(paths, [options])`
|
||||
|
||||
* `paths` (string or array of strings). Paths to files, dirs to be watched
|
||||
recursively, or glob patterns.
|
||||
- Note: globs must not contain windows separators (`\`),
|
||||
because that's how they work by the standard —
|
||||
you'll need to replace them with forward slashes (`/`).
|
||||
- Note 2: for additional glob documentation, check out low-level
|
||||
library: [picomatch](https://github.com/micromatch/picomatch).
|
||||
* `options` (object) Options object as defined below:
|
||||
|
||||
#### Persistence
|
||||
|
||||
* `persistent` (default: `true`). Indicates whether the process
|
||||
should continue to run as long as files are being watched. If set to
|
||||
`false` when using `fsevents` to watch, no more events will be emitted
|
||||
after `ready`, even if the process continues to run.
|
||||
|
||||
#### Path filtering
|
||||
|
||||
* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
|
||||
Defines files/paths to be ignored. The whole relative or absolute path is
|
||||
tested, not just filename. If a function with two arguments is provided, it
|
||||
gets called twice per path - once with a single argument (the path), second
|
||||
time with two arguments (the path and the
|
||||
[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object of that path).
|
||||
* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while
|
||||
instantiating the watching as chokidar discovers these file paths (before the `ready` event).
|
||||
* `followSymlinks` (default: `true`). When `false`, only the
|
||||
symlinks themselves will be watched for changes instead of following
|
||||
the link references and bubbling events through the link's path.
|
||||
* `cwd` (no default). The base directory from which watch `paths` are to be
|
||||
derived. Paths emitted with events will be relative to this.
|
||||
* `disableGlobbing` (default: `false`). If set to `true` then the strings passed to `.watch()` and `.add()` are treated as
|
||||
literal path names, even if they look like globs.
|
||||
|
||||
#### Performance
|
||||
|
||||
* `usePolling` (default: `false`).
|
||||
Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
|
||||
leads to high CPU utilization, consider setting this to `false`. It is
|
||||
typically necessary to **set this to `true` to successfully watch files over
|
||||
a network**, and it may be necessary to successfully watch files in other
|
||||
non-standard situations. Setting to `true` explicitly on MacOS overrides the
|
||||
`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
|
||||
to true (1) or false (0) in order to override this option.
|
||||
* _Polling-specific settings_ (effective when `usePolling: true`)
|
||||
* `interval` (default: `100`). Interval of file system polling, in milliseconds. You may also
|
||||
set the CHOKIDAR_INTERVAL env variable to override this option.
|
||||
* `binaryInterval` (default: `300`). Interval of file system
|
||||
polling for binary files.
|
||||
([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
|
||||
* `useFsEvents` (default: `true` on MacOS). Whether to use the
|
||||
`fsevents` watching interface if available. When set to `true` explicitly
|
||||
and `fsevents` is available this supercedes the `usePolling` setting. When
|
||||
set to `false` on MacOS, `usePolling: true` becomes the default.
|
||||
* `alwaysStat` (default: `false`). If relying upon the
|
||||
[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object that may get passed with `add`, `addDir`, and `change` events, set
|
||||
this to `true` to ensure it is provided even in cases where it wasn't
|
||||
already available from the underlying watch events.
|
||||
* `depth` (default: `undefined`). If set, limits how many levels of
|
||||
subdirectories will be traversed.
|
||||
* `awaitWriteFinish` (default: `false`).
|
||||
By default, the `add` event will fire when a file first appears on disk, before
|
||||
the entire file has been written. Furthermore, in some cases some `change`
|
||||
events will be emitted while the file is being written. In some cases,
|
||||
especially when watching for large files there will be a need to wait for the
|
||||
write operation to finish before responding to a file creation or modification.
|
||||
Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
|
||||
holding its `add` and `change` events until the size does not change for a
|
||||
configurable amount of time. The appropriate duration setting is heavily
|
||||
dependent on the OS and hardware. For accurate detection this parameter should
|
||||
be relatively high, making file watching much less responsive.
|
||||
Use with caution.
|
||||
* *`options.awaitWriteFinish` can be set to an object in order to adjust
|
||||
timing params:*
|
||||
* `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
|
||||
milliseconds for a file size to remain constant before emitting its event.
|
||||
* `awaitWriteFinish.pollInterval` (default: 100). File size polling interval, in milliseconds.
|
||||
|
||||
#### Errors
|
||||
|
||||
* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
|
||||
that don't have read permissions if possible. If watching fails due to `EPERM`
|
||||
or `EACCES` with this set to `true`, the errors will be suppressed silently.
|
||||
* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
|
||||
Automatically filters out artifacts that occur when using editors that use
|
||||
"atomic writes" instead of writing directly to the source file. If a file is
|
||||
re-added within 100 ms of being deleted, Chokidar emits a `change` event
|
||||
rather than `unlink` then `add`. If the default of 100 ms does not work well
|
||||
for you, you can override it by setting `atomic` to a custom value, in
|
||||
milliseconds.
|
||||
|
||||
### Methods & Events
|
||||
|
||||
`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
|
||||
|
||||
* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
|
||||
Takes an array of strings or just one string.
|
||||
* `.on(event, callback)`: Listen for an FS event.
|
||||
Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
|
||||
`raw`, `error`.
|
||||
Additionally `all` is available which gets emitted with the underlying event
|
||||
name and path for every event other than `ready`, `raw`, and `error`. `raw` is internal, use it carefully.
|
||||
* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
|
||||
Takes an array of strings or just one string.
|
||||
* `.close()`: **async** Removes all listeners from watched files. Asynchronous, returns Promise. Use with `await` to ensure bugs don't happen.
|
||||
* `.getWatched()`: Returns an object representing all the paths on the file
|
||||
system being watched by this `FSWatcher` instance. The object's keys are all the
|
||||
directories (using absolute paths unless the `cwd` option was used), and the
|
||||
values are arrays of the names of the items contained in each directory.
|
||||
|
||||
## CLI
|
||||
|
||||
If you need a CLI interface for your file watching, check out
|
||||
[chokidar-cli](https://github.com/open-cli-tools/chokidar-cli), allowing you to
|
||||
execute a command on each change, or get a stdio stream of change events.
|
||||
|
||||
## Install Troubleshooting
|
||||
|
||||
* `npm WARN optional dep failed, continuing fsevents@n.n.n`
|
||||
* This message is normal part of how `npm` handles optional dependencies and is
|
||||
not indicative of a problem. Even if accompanied by other related error messages,
|
||||
Chokidar should function properly.
|
||||
|
||||
* `TypeError: fsevents is not a constructor`
|
||||
* Update chokidar by doing `rm -rf node_modules package-lock.json yarn.lock && npm install`, or update your dependency that uses chokidar.
|
||||
|
||||
* Chokidar is producing `ENOSP` error on Linux, like this:
|
||||
* `bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell`
|
||||
`Error: watch /home/ ENOSPC`
|
||||
* This means Chokidar ran out of file handles and you'll need to increase their count by executing the following command in Terminal:
|
||||
`echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`
|
||||
|
||||
## Changelog
|
||||
|
||||
For more detailed changelog, see [`full_changelog.md`](.github/full_changelog.md).
|
||||
- **v3.5 (Jan 6, 2021):** Support for ARM Macs with Apple Silicon. Fixes for deleted symlinks.
|
||||
- **v3.4 (Apr 26, 2020):** Support for directory-based symlinks. Fixes for macos file replacement.
|
||||
- **v3.3 (Nov 2, 2019):** `FSWatcher#close()` method became async. That fixes IO race conditions related to close method.
|
||||
- **v3.2 (Oct 1, 2019):** Improve Linux RAM usage by 50%. Race condition fixes. Windows glob fixes. Improve stability by using tight range of dependency versions.
|
||||
- **v3.1 (Sep 16, 2019):** dotfiles are no longer filtered out by default. Use `ignored` option if needed. Improve initial Linux scan time by 50%.
|
||||
- **v3 (Apr 30, 2019):** massive CPU & RAM consumption improvements; reduces deps / package size by a factor of 17x and bumps Node.js requirement to v8.16 and higher.
|
||||
- **v2 (Dec 29, 2017):** Globs are now posix-style-only; without windows support. Tons of bugfixes.
|
||||
- **v1 (Apr 7, 2015):** Glob support, symlink support, tons of bugfixes. Node 0.8+ is supported
|
||||
- **v0.1 (Apr 20, 2012):** Initial release, extracted from [Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)
|
||||
|
||||
## Also
|
||||
|
||||
Why was chokidar named this way? What's the meaning behind it?
|
||||
|
||||
>Chowkidar is a transliteration of a Hindi word meaning 'watchman, gatekeeper', चौकीदार. This ultimately comes from Sanskrit _ चतुष्क_ (crossway, quadrangle, consisting-of-four).
|
||||
|
||||
## License
|
||||
|
||||
MIT (c) Paul Miller (<https://paulmillr.com>), see [LICENSE](LICENSE) file.
|
||||
973
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/index.js
generated
vendored
Normal file
973
node_modules/.store/chokidar@3.5.3/node_modules/chokidar/index.js
generated
vendored
Normal file
@@ -0,0 +1,973 @@
|
||||
'use strict';
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const fs = require('fs');
|
||||
const sysPath = require('path');
|
||||
const { promisify } = require('util');
|
||||
const readdirp = require('readdirp');
|
||||
const anymatch = require('anymatch').default;
|
||||
const globParent = require('glob-parent');
|
||||
const isGlob = require('is-glob');
|
||||
const braces = require('braces');
|
||||
const normalizePath = require('normalize-path');
|
||||
|
||||
const NodeFsHandler = require('./lib/nodefs-handler');
|
||||
const FsEventsHandler = require('./lib/fsevents-handler');
|
||||
const {
|
||||
EV_ALL,
|
||||
EV_READY,
|
||||
EV_ADD,
|
||||
EV_CHANGE,
|
||||
EV_UNLINK,
|
||||
EV_ADD_DIR,
|
||||
EV_UNLINK_DIR,
|
||||
EV_RAW,
|
||||
EV_ERROR,
|
||||
|
||||
STR_CLOSE,
|
||||
STR_END,
|
||||
|
||||
BACK_SLASH_RE,
|
||||
DOUBLE_SLASH_RE,
|
||||
SLASH_OR_BACK_SLASH_RE,
|
||||
DOT_RE,
|
||||
REPLACER_RE,
|
||||
|
||||
SLASH,
|
||||
SLASH_SLASH,
|
||||
BRACE_START,
|
||||
BANG,
|
||||
ONE_DOT,
|
||||
TWO_DOTS,
|
||||
GLOBSTAR,
|
||||
SLASH_GLOBSTAR,
|
||||
ANYMATCH_OPTS,
|
||||
STRING_TYPE,
|
||||
FUNCTION_TYPE,
|
||||
EMPTY_STR,
|
||||
EMPTY_FN,
|
||||
|
||||
isWindows,
|
||||
isMacos,
|
||||
isIBMi
|
||||
} = require('./lib/constants');
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
const readdir = promisify(fs.readdir);
|
||||
|
||||
/**
|
||||
* @typedef {String} Path
|
||||
* @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName
|
||||
* @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @typedef {Object} WatchHelpers
|
||||
* @property {Boolean} followSymlinks
|
||||
* @property {'stat'|'lstat'} statMethod
|
||||
* @property {Path} path
|
||||
* @property {Path} watchPath
|
||||
* @property {Function} entryPath
|
||||
* @property {Boolean} hasGlob
|
||||
* @property {Object} globFilter
|
||||
* @property {Function} filterPath
|
||||
* @property {Function} filterDir
|
||||
*/
|
||||
|
||||
const arrify = (value = []) => Array.isArray(value) ? value : [value];
|
||||
const flatten = (list, result = []) => {
|
||||
list.forEach(item => {
|
||||
if (Array.isArray(item)) {
|
||||
flatten(item, result);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const unifyPaths = (paths_) => {
|
||||
/**
|
||||
* @type {Array<String>}
|
||||
*/
|
||||
const paths = flatten(arrify(paths_));
|
||||
if (!paths.every(p => typeof p === STRING_TYPE)) {
|
||||
throw new TypeError(`Non-string provided as watch path: ${paths}`);
|
||||
}
|
||||
return paths.map(normalizePathToUnix);
|
||||
};
|
||||
|
||||
// If SLASH_SLASH occurs at the beginning of path, it is not replaced
|
||||
// because "//StoragePC/DrivePool/Movies" is a valid network path
|
||||
const toUnix = (string) => {
|
||||
let str = string.replace(BACK_SLASH_RE, SLASH);
|
||||
let prepend = false;
|
||||
if (str.startsWith(SLASH_SLASH)) {
|
||||
prepend = true;
|
||||
}
|
||||
while (str.match(DOUBLE_SLASH_RE)) {
|
||||
str = str.replace(DOUBLE_SLASH_RE, SLASH);
|
||||
}
|
||||
if (prepend) {
|
||||
str = SLASH + str;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// Our version of upath.normalize
|
||||
// TODO: this is not equal to path-normalize module - investigate why
|
||||
const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path)));
|
||||
|
||||
const normalizeIgnored = (cwd = EMPTY_STR) => (path) => {
|
||||
if (typeof path !== STRING_TYPE) return path;
|
||||
return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path));
|
||||
};
|
||||
|
||||
const getAbsolutePath = (path, cwd) => {
|
||||
if (sysPath.isAbsolute(path)) {
|
||||
return path;
|
||||
}
|
||||
if (path.startsWith(BANG)) {
|
||||
return BANG + sysPath.join(cwd, path.slice(1));
|
||||
}
|
||||
return sysPath.join(cwd, path);
|
||||
};
|
||||
|
||||
const undef = (opts, key) => opts[key] === undefined;
|
||||
|
||||
/**
|
||||
* Directory entry.
|
||||
* @property {Path} path
|
||||
* @property {Set<Path>} items
|
||||
*/
|
||||
class DirEntry {
|
||||
/**
|
||||
* @param {Path} dir
|
||||
* @param {Function} removeWatcher
|
||||
*/
|
||||
constructor(dir, removeWatcher) {
|
||||
this.path = dir;
|
||||
this._removeWatcher = removeWatcher;
|
||||
/** @type {Set<Path>} */
|
||||
this.items = new Set();
|
||||
}
|
||||
|
||||
add(item) {
|
||||
const {items} = this;
|
||||
if (!items) return;
|
||||
if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item);
|
||||
}
|
||||
|
||||
async remove(item) {
|
||||
const {items} = this;
|
||||
if (!items) return;
|
||||
items.delete(item);
|
||||
if (items.size > 0) return;
|
||||
|
||||
const dir = this.path;
|
||||
try {
|
||||
await readdir(dir);
|
||||
} catch (err) {
|
||||
if (this._removeWatcher) {
|
||||
this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
has(item) {
|
||||
const {items} = this;
|
||||
if (!items) return;
|
||||
return items.has(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array<String>}
|
||||
*/
|
||||
getChildren() {
|
||||
const {items} = this;
|
||||
if (!items) return;
|
||||
return [...items.values()];
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.items.clear();
|
||||
delete this.path;
|
||||
delete this._removeWatcher;
|
||||
delete this.items;
|
||||
Object.freeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
const STAT_METHOD_F = 'stat';
|
||||
const STAT_METHOD_L = 'lstat';
|
||||
class WatchHelper {
|
||||
constructor(path, watchPath, follow, fsw) {
|
||||
this.fsw = fsw;
|
||||
this.path = path = path.replace(REPLACER_RE, EMPTY_STR);
|
||||
this.watchPath = watchPath;
|
||||
this.fullWatchPath = sysPath.resolve(watchPath);
|
||||
this.hasGlob = watchPath !== path;
|
||||
/** @type {object|boolean} */
|
||||
if (path === EMPTY_STR) this.hasGlob = false;
|
||||
this.globSymlink = this.hasGlob && follow ? undefined : false;
|
||||
this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false;
|
||||
this.dirParts = this.getDirParts(path);
|
||||
this.dirParts.forEach((parts) => {
|
||||
if (parts.length > 1) parts.pop();
|
||||
});
|
||||
this.followSymlinks = follow;
|
||||
this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
|
||||
}
|
||||
|
||||
checkGlobSymlink(entry) {
|
||||
// only need to resolve once
|
||||
// first entry should always have entry.parentDir === EMPTY_STR
|
||||
if (this.globSymlink === undefined) {
|
||||
this.globSymlink = entry.fullParentDir === this.fullWatchPath ?
|
||||
false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath};
|
||||
}
|
||||
|
||||
if (this.globSymlink) {
|
||||
return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath);
|
||||
}
|
||||
|
||||
return entry.fullPath;
|
||||
}
|
||||
|
||||
entryPath(entry) {
|
||||
return sysPath.join(this.watchPath,
|
||||
sysPath.relative(this.watchPath, this.checkGlobSymlink(entry))
|
||||
);
|
||||
}
|
||||
|
||||
filterPath(entry) {
|
||||
const {stats} = entry;
|
||||
if (stats && stats.isSymbolicLink()) return this.filterDir(entry);
|
||||
const resolvedPath = this.entryPath(entry);
|
||||
const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ?
|
||||
this.globFilter(resolvedPath) : true;
|
||||
return matchesGlob &&
|
||||
this.fsw._isntIgnored(resolvedPath, stats) &&
|
||||
this.fsw._hasReadPermissions(stats);
|
||||
}
|
||||
|
||||
getDirParts(path) {
|
||||
if (!this.hasGlob) return [];
|
||||
const parts = [];
|
||||
const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path];
|
||||
expandedPath.forEach((path) => {
|
||||
parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE));
|
||||
});
|
||||
return parts;
|
||||
}
|
||||
|
||||
filterDir(entry) {
|
||||
if (this.hasGlob) {
|
||||
const entryParts = this.getDirParts(this.checkGlobSymlink(entry));
|
||||
let globstar = false;
|
||||
this.unmatchedGlob = !this.dirParts.some((parts) => {
|
||||
return parts.every((part, i) => {
|
||||
if (part === GLOBSTAR) globstar = true;
|
||||
return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS);
|
||||
});
|
||||
});
|
||||
}
|
||||
return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watches files & directories for changes. Emitted events:
|
||||
* `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
|
||||
*
|
||||
* new FSWatcher()
|
||||
* .add(directories)
|
||||
* .on('add', path => log('File', path, 'was added'))
|
||||
*/
|
||||
class FSWatcher extends EventEmitter {
|
||||
// Not indenting methods for history sake; for now.
|
||||
constructor(_opts) {
|
||||
super();
|
||||
|
||||
const opts = {};
|
||||
if (_opts) Object.assign(opts, _opts); // for frozen objects
|
||||
|
||||
/** @type {Map<String, DirEntry>} */
|
||||
this._watched = new Map();
|
||||
/** @type {Map<String, Array>} */
|
||||
this._closers = new Map();
|
||||
/** @type {Set<String>} */
|
||||
this._ignoredPaths = new Set();
|
||||
|
||||
/** @type {Map<ThrottleType, Map>} */
|
||||
this._throttled = new Map();
|
||||
|
||||
/** @type {Map<Path, String|Boolean>} */
|
||||
this._symlinkPaths = new Map();
|
||||
|
||||
this._streams = new Set();
|
||||
this.closed = false;
|
||||
|
||||
// Set up default options.
|
||||
if (undef(opts, 'persistent')) opts.persistent = true;
|
||||
if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false;
|
||||
if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false;
|
||||
if (undef(opts, 'interval')) opts.interval = 100;
|
||||
if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300;
|
||||
if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false;
|
||||
opts.enableBinaryInterval = opts.binaryInterval !== opts.interval;
|
||||
|
||||
// Enable fsevents on OS X when polling isn't explicitly enabled.
|
||||
if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling;
|
||||
|
||||
// If we can't use fsevents, ensure the options reflect it's disabled.
|
||||
const canUseFsEvents = FsEventsHandler.canUse();
|
||||
if (!canUseFsEvents) opts.useFsEvents = false;
|
||||
|
||||
// Use polling on Mac if not using fsevents.
|
||||
// Other platforms use non-polling fs_watch.
|
||||
if (undef(opts, 'usePolling') && !opts.useFsEvents) {
|
||||
opts.usePolling = isMacos;
|
||||
}
|
||||
|
||||
// Always default to polling on IBM i because fs.watch() is not available on IBM i.
|
||||
if(isIBMi) {
|
||||
opts.usePolling = true;
|
||||
}
|
||||
|
||||
// Global override (useful for end-developers that need to force polling for all
|
||||
// instances of chokidar, regardless of usage/dependency depth)
|
||||
const envPoll = process.env.CHOKIDAR_USEPOLLING;
|
||||
if (envPoll !== undefined) {
|
||||
const envLower = envPoll.toLowerCase();
|
||||
|
||||
if (envLower === 'false' || envLower === '0') {
|
||||
opts.usePolling = false;
|
||||
} else if (envLower === 'true' || envLower === '1') {
|
||||
opts.usePolling = true;
|
||||
} else {
|
||||
opts.usePolling = !!envLower;
|
||||
}
|
||||
}
|
||||
const envInterval = process.env.CHOKIDAR_INTERVAL;
|
||||
if (envInterval) {
|
||||
opts.interval = Number.parseInt(envInterval, 10);
|
||||
}
|
||||
|
||||
// Editor atomic write normalization enabled by default with fs.watch
|
||||
if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
|
||||
if (opts.atomic) this._pendingUnlinks = new Map();
|
||||
|
||||
if (undef(opts, 'followSymlinks')) opts.followSymlinks = true;
|
||||
|
||||
if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false;
|
||||
if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
|
||||
const awf = opts.awaitWriteFinish;
|
||||
if (awf) {
|
||||
if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
|
||||
if (!awf.pollInterval) awf.pollInterval = 100;
|
||||
this._pendingWrites = new Map();
|
||||
}
|
||||
if (opts.ignored) opts.ignored = arrify(opts.ignored);
|
||||
|
||||
let readyCalls = 0;
|
||||
this._emitReady = () => {
|
||||
readyCalls++;
|
||||
if (readyCalls >= this._readyCount) {
|
||||
this._emitReady = EMPTY_FN;
|
||||
this._readyEmitted = true;
|
||||
// use process.nextTick to allow time for listener to be bound
|
||||
process.nextTick(() => this.emit(EV_READY));
|
||||
}
|
||||
};
|
||||
this._emitRaw = (...args) => this.emit(EV_RAW, ...args);
|
||||
this._readyEmitted = false;
|
||||
this.options = opts;
|
||||
|
||||
// Initialize with proper watcher.
|
||||
if (opts.useFsEvents) {
|
||||
this._fsEventsHandler = new FsEventsHandler(this);
|
||||
} else {
|
||||
this._nodeFsHandler = new NodeFsHandler(this);
|
||||
}
|
||||
|
||||
// You’re frozen when your heart’s not open.
|
||||
Object.freeze(opts);
|
||||
}
|
||||
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* Adds paths to be watched on an existing FSWatcher instance
|
||||
* @param {Path|Array<Path>} paths_
|
||||
* @param {String=} _origAdd private; for handling non-existent paths to be watched
|
||||
* @param {Boolean=} _internal private; indicates a non-user add
|
||||
* @returns {FSWatcher} for chaining
|
||||
*/
|
||||
add(paths_, _origAdd, _internal) {
|
||||
const {cwd, disableGlobbing} = this.options;
|
||||
this.closed = false;
|
||||
let paths = unifyPaths(paths_);
|
||||
if (cwd) {
|
||||
paths = paths.map((path) => {
|
||||
const absPath = getAbsolutePath(path, cwd);
|
||||
|
||||
// Check `path` instead of `absPath` because the cwd portion can't be a glob
|
||||
if (disableGlobbing || !isGlob(path)) {
|
||||
return absPath;
|
||||
}
|
||||
return normalizePath(absPath);
|
||||
});
|
||||
}
|
||||
|
||||
// set aside negated glob strings
|
||||
paths = paths.filter((path) => {
|
||||
if (path.startsWith(BANG)) {
|
||||
this._ignoredPaths.add(path.slice(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if a path is being added that was previously ignored, stop ignoring it
|
||||
this._ignoredPaths.delete(path);
|
||||
this._ignoredPaths.delete(path + SLASH_GLOBSTAR);
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = undefined;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (this.options.useFsEvents && this._fsEventsHandler) {
|
||||
if (!this._readyCount) this._readyCount = paths.length;
|
||||
if (this.options.persistent) this._readyCount *= 2;
|
||||
paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path));
|
||||
} else {
|
||||
if (!this._readyCount) this._readyCount = 0;
|
||||
this._readyCount += paths.length;
|
||||
Promise.all(
|
||||
paths.map(async path => {
|
||||
const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd);
|
||||
if (res) this._emitReady();
|
||||
return res;
|
||||
})
|
||||
).then(results => {
|
||||
if (this.closed) return;
|
||||
results.filter(item => item).forEach(item => {
|
||||
this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close watchers or start ignoring events from specified paths.
|
||||
* @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs
|
||||
* @returns {FSWatcher} for chaining
|
||||
*/
|
||||
unwatch(paths_) {
|
||||
if (this.closed) return this;
|
||||
const paths = unifyPaths(paths_);
|
||||
const {cwd} = this.options;
|
||||
|
||||
paths.forEach((path) => {
|
||||
// convert to absolute path unless relative path already matches
|
||||
if (!sysPath.isAbsolute(path) && !this._closers.has(path)) {
|
||||
if (cwd) path = sysPath.join(cwd, path);
|
||||
path = sysPath.resolve(path);
|
||||
}
|
||||
|
||||
this._closePath(path);
|
||||
|
||||
this._ignoredPaths.add(path);
|
||||
if (this._watched.has(path)) {
|
||||
this._ignoredPaths.add(path + SLASH_GLOBSTAR);
|
||||
}
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = undefined;
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close watchers and remove all listeners from watched paths.
|
||||
* @returns {Promise<void>}.
|
||||
*/
|
||||
close() {
|
||||
if (this.closed) return this._closePromise;
|
||||
this.closed = true;
|
||||
|
||||
// Memory management.
|
||||
this.removeAllListeners();
|
||||
const closers = [];
|
||||
this._closers.forEach(closerList => closerList.forEach(closer => {
|
||||
const promise = closer();
|
||||
if (promise instanceof Promise) closers.push(promise);
|
||||
}));
|
||||
this._streams.forEach(stream => stream.destroy());
|
||||
this._userIgnored = undefined;
|
||||
this._readyCount = 0;
|
||||
this._readyEmitted = false;
|
||||
this._watched.forEach(dirent => dirent.dispose());
|
||||
['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => {
|
||||
this[`_${key}`].clear();
|
||||
});
|
||||
|
||||
this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve();
|
||||
return this._closePromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose list of watched paths
|
||||
* @returns {Object} for chaining
|
||||
*/
|
||||
getWatched() {
|
||||
const watchList = {};
|
||||
this._watched.forEach((entry, dir) => {
|
||||
const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
|
||||
watchList[key || ONE_DOT] = entry.getChildren().sort();
|
||||
});
|
||||
return watchList;
|
||||
}
|
||||
|
||||
emitWithAll(event, args) {
|
||||
this.emit(...args);
|
||||
if (event !== EV_ERROR) this.emit(EV_ALL, ...args);
|
||||
}
|
||||
|
||||
// Common helpers
|
||||
// --------------
|
||||
|
||||
/**
|
||||
* Normalize and emit events.
|
||||
* Calling _emit DOES NOT MEAN emit() would be called!
|
||||
* @param {EventName} event Type of event
|
||||
* @param {Path} path File or directory path
|
||||
* @param {*=} val1 arguments to be passed with event
|
||||
* @param {*=} val2
|
||||
* @param {*=} val3
|
||||
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
||||
*/
|
||||
async _emit(event, path, val1, val2, val3) {
|
||||
if (this.closed) return;
|
||||
|
||||
const opts = this.options;
|
||||
if (isWindows) path = sysPath.normalize(path);
|
||||
if (opts.cwd) path = sysPath.relative(opts.cwd, path);
|
||||
/** @type Array<any> */
|
||||
const args = [event, path];
|
||||
if (val3 !== undefined) args.push(val1, val2, val3);
|
||||
else if (val2 !== undefined) args.push(val1, val2);
|
||||
else if (val1 !== undefined) args.push(val1);
|
||||
|
||||
const awf = opts.awaitWriteFinish;
|
||||
let pw;
|
||||
if (awf && (pw = this._pendingWrites.get(path))) {
|
||||
pw.lastChange = new Date();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (opts.atomic) {
|
||||
if (event === EV_UNLINK) {
|
||||
this._pendingUnlinks.set(path, args);
|
||||
setTimeout(() => {
|
||||
this._pendingUnlinks.forEach((entry, path) => {
|
||||
this.emit(...entry);
|
||||
this.emit(EV_ALL, ...entry);
|
||||
this._pendingUnlinks.delete(path);
|
||||
});
|
||||
}, typeof opts.atomic === 'number' ? opts.atomic : 100);
|
||||
return this;
|
||||
}
|
||||
if (event === EV_ADD && this._pendingUnlinks.has(path)) {
|
||||
event = args[0] = EV_CHANGE;
|
||||
this._pendingUnlinks.delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
|
||||
const awfEmit = (err, stats) => {
|
||||
if (err) {
|
||||
event = args[0] = EV_ERROR;
|
||||
args[1] = err;
|
||||
this.emitWithAll(event, args);
|
||||
} else if (stats) {
|
||||
// if stats doesn't exist the file must have been deleted
|
||||
if (args.length > 2) {
|
||||
args[2] = stats;
|
||||
} else {
|
||||
args.push(stats);
|
||||
}
|
||||
this.emitWithAll(event, args);
|
||||
}
|
||||
};
|
||||
|
||||
this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (event === EV_CHANGE) {
|
||||
const isThrottled = !this._throttle(EV_CHANGE, path, 50);
|
||||
if (isThrottled) return this;
|
||||
}
|
||||
|
||||
if (opts.alwaysStat && val1 === undefined &&
|
||||
(event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)
|
||||
) {
|
||||
const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path;
|
||||
let stats;
|
||||
try {
|
||||
stats = await stat(fullPath);
|
||||
} catch (err) {}
|
||||
// Suppress event when fs_stat fails, to avoid sending undefined 'stat'
|
||||
if (!stats || this.closed) return;
|
||||
args.push(stats);
|
||||
}
|
||||
this.emitWithAll(event, args);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common handler for errors
|
||||
* @param {Error} error
|
||||
* @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
||||
*/
|
||||
_handleError(error) {
|
||||
const code = error && error.code;
|
||||
if (error && code !== 'ENOENT' && code !== 'ENOTDIR' &&
|
||||
(!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))
|
||||
) {
|
||||
this.emit(EV_ERROR, error);
|
||||
}
|
||||
return error || this.closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper utility for throttling
|
||||
* @param {ThrottleType} actionType type being throttled
|
||||
* @param {Path} path being acted upon
|
||||
* @param {Number} timeout duration of time to suppress duplicate actions
|
||||
* @returns {Object|false} tracking object or false if action should be suppressed
|
||||
*/
|
||||
_throttle(actionType, path, timeout) {
|
||||
if (!this._throttled.has(actionType)) {
|
||||
this._throttled.set(actionType, new Map());
|
||||
}
|
||||
|
||||
/** @type {Map<Path, Object>} */
|
||||
const action = this._throttled.get(actionType);
|
||||
/** @type {Object} */
|
||||
const actionPath = action.get(path);
|
||||
|
||||
if (actionPath) {
|
||||
actionPath.count++;
|
||||
return false;
|
||||
}
|
||||
|
||||
let timeoutObject;
|
||||
const clear = () => {
|
||||
const item = action.get(path);
|
||||
const count = item ? item.count : 0;
|
||||
action.delete(path);
|
||||
clearTimeout(timeoutObject);
|
||||
if (item) clearTimeout(item.timeoutObject);
|
||||
return count;
|
||||
};
|
||||
timeoutObject = setTimeout(clear, timeout);
|
||||
const thr = {timeoutObject, clear, count: 0};
|
||||
action.set(path, thr);
|
||||
return thr;
|
||||
}
|
||||
|
||||
_incrReadyCount() {
|
||||
return this._readyCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Awaits write operation to finish.
|
||||
* Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
|
||||
* @param {Path} path being acted upon
|
||||
* @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
|
||||
* @param {EventName} event
|
||||
* @param {Function} awfEmit Callback to be called when ready for event to be emitted.
|
||||
*/
|
||||
_awaitWriteFinish(path, threshold, event, awfEmit) {
|
||||
let timeoutHandler;
|
||||
|
||||
let fullPath = path;
|
||||
if (this.options.cwd && !sysPath.isAbsolute(path)) {
|
||||
fullPath = sysPath.join(this.options.cwd, path);
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
|
||||
const awaitWriteFinish = (prevStat) => {
|
||||
fs.stat(fullPath, (err, curStat) => {
|
||||
if (err || !this._pendingWrites.has(path)) {
|
||||
if (err && err.code !== 'ENOENT') awfEmit(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Number(new Date());
|
||||
|
||||
if (prevStat && curStat.size !== prevStat.size) {
|
||||
this._pendingWrites.get(path).lastChange = now;
|
||||
}
|
||||
const pw = this._pendingWrites.get(path);
|
||||
const df = now - pw.lastChange;
|
||||
|
||||
if (df >= threshold) {
|
||||
this._pendingWrites.delete(path);
|
||||
awfEmit(undefined, curStat);
|
||||
} else {
|
||||
timeoutHandler = setTimeout(
|
||||
awaitWriteFinish,
|
||||
this.options.awaitWriteFinish.pollInterval,
|
||||
curStat
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (!this._pendingWrites.has(path)) {
|
||||
this._pendingWrites.set(path, {
|
||||
lastChange: now,
|
||||
cancelWait: () => {
|
||||
this._pendingWrites.delete(path);
|
||||
clearTimeout(timeoutHandler);
|
||||
return event;
|
||||
}
|
||||
});
|
||||
timeoutHandler = setTimeout(
|
||||
awaitWriteFinish,
|
||||
this.options.awaitWriteFinish.pollInterval
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_getGlobIgnored() {
|
||||
return [...this._ignoredPaths.values()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether user has asked to ignore this path.
|
||||
* @param {Path} path filepath or dir
|
||||
* @param {fs.Stats=} stats result of fs.stat
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
_isIgnored(path, stats) {
|
||||
if (this.options.atomic && DOT_RE.test(path)) return true;
|
||||
if (!this._userIgnored) {
|
||||
const {cwd} = this.options;
|
||||
const ign = this.options.ignored;
|
||||
|
||||
const ignored = ign && ign.map(normalizeIgnored(cwd));
|
||||
const paths = arrify(ignored)
|
||||
.filter((path) => typeof path === STRING_TYPE && !isGlob(path))
|
||||
.map((path) => path + SLASH_GLOBSTAR);
|
||||
const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
|
||||
this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
|
||||
}
|
||||
|
||||
return this._userIgnored([path, stats]);
|
||||
}
|
||||
|
||||
_isntIgnored(path, stat) {
|
||||
return !this._isIgnored(path, stat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of common helpers and properties relating to symlink and glob handling.
|
||||
* @param {Path} path file, directory, or glob pattern being watched
|
||||
* @param {Number=} depth at any depth > 0, this isn't a glob
|
||||
* @returns {WatchHelper} object containing helpers for this path
|
||||
*/
|
||||
_getWatchHelpers(path, depth) {
|
||||
const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
|
||||
const follow = this.options.followSymlinks;
|
||||
|
||||
return new WatchHelper(path, watchPath, follow, this);
|
||||
}
|
||||
|
||||
// Directory helpers
|
||||
// -----------------
|
||||
|
||||
/**
|
||||
* Provides directory tracking objects
|
||||
* @param {String} directory path of the directory
|
||||
* @returns {DirEntry} the directory's tracking object
|
||||
*/
|
||||
_getWatchedDir(directory) {
|
||||
if (!this._boundRemove) this._boundRemove = this._remove.bind(this);
|
||||
const dir = sysPath.resolve(directory);
|
||||
if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove));
|
||||
return this._watched.get(dir);
|
||||
}
|
||||
|
||||
// File helpers
|
||||
// ------------
|
||||
|
||||
/**
|
||||
* Check for read permissions.
|
||||
* Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405
|
||||
* @param {fs.Stats} stats - object, result of fs_stat
|
||||
* @returns {Boolean} indicates whether the file can be read
|
||||
*/
|
||||
_hasReadPermissions(stats) {
|
||||
if (this.options.ignorePermissionErrors) return true;
|
||||
|
||||
// stats.mode may be bigint
|
||||
const md = stats && Number.parseInt(stats.mode, 10);
|
||||
const st = md & 0o777;
|
||||
const it = Number.parseInt(st.toString(8)[0], 10);
|
||||
return Boolean(4 & it);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles emitting unlink events for
|
||||
* files and directories, and via recursion, for
|
||||
* files and directories within directories that are unlinked
|
||||
* @param {String} directory within which the following item is located
|
||||
* @param {String} item base path of item/directory
|
||||
* @returns {void}
|
||||
*/
|
||||
_remove(directory, item, isDirectory) {
|
||||
// if what is being deleted is a directory, get that directory's paths
|
||||
// for recursive deleting and cleaning of watched object
|
||||
// if it is not a directory, nestedDirectoryChildren will be empty array
|
||||
const path = sysPath.join(directory, item);
|
||||
const fullPath = sysPath.resolve(path);
|
||||
isDirectory = isDirectory != null
|
||||
? isDirectory
|
||||
: this._watched.has(path) || this._watched.has(fullPath);
|
||||
|
||||
// prevent duplicate handling in case of arriving here nearly simultaneously
|
||||
// via multiple paths (such as _handleFile and _handleDir)
|
||||
if (!this._throttle('remove', path, 100)) return;
|
||||
|
||||
// if the only watched file is removed, watch for its return
|
||||
if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
|
||||
this.add(directory, item, true);
|
||||
}
|
||||
|
||||
// This will create a new entry in the watched object in either case
|
||||
// so we got to do the directory check beforehand
|
||||
const wp = this._getWatchedDir(path);
|
||||
const nestedDirectoryChildren = wp.getChildren();
|
||||
|
||||
// Recursively remove children directories / files.
|
||||
nestedDirectoryChildren.forEach(nested => this._remove(path, nested));
|
||||
|
||||
// Check if item was on the watched list and remove it
|
||||
const parent = this._getWatchedDir(directory);
|
||||
const wasTracked = parent.has(item);
|
||||
parent.remove(item);
|
||||
|
||||
// Fixes issue #1042 -> Relative paths were detected and added as symlinks
|
||||
// (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612),
|
||||
// but never removed from the map in case the path was deleted.
|
||||
// This leads to an incorrect state if the path was recreated:
|
||||
// https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553
|
||||
if (this._symlinkPaths.has(fullPath)) {
|
||||
this._symlinkPaths.delete(fullPath);
|
||||
}
|
||||
|
||||
// If we wait for this file to be fully written, cancel the wait.
|
||||
let relPath = path;
|
||||
if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
|
||||
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
||||
const event = this._pendingWrites.get(relPath).cancelWait();
|
||||
if (event === EV_ADD) return;
|
||||
}
|
||||
|
||||
// The Entry will either be a directory that just got removed
|
||||
// or a bogus entry to a file, in either case we have to remove it
|
||||
this._watched.delete(path);
|
||||
this._watched.delete(fullPath);
|
||||
const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
|
||||
if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
|
||||
|
||||
// Avoid conflicts if we later create another file with the same name
|
||||
if (!this.options.useFsEvents) {
|
||||
this._closePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all watchers for a path
|
||||
* @param {Path} path
|
||||
*/
|
||||
_closePath(path) {
|
||||
this._closeFile(path)
|
||||
const dir = sysPath.dirname(path);
|
||||
this._getWatchedDir(dir).remove(sysPath.basename(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes only file-specific watchers
|
||||
* @param {Path} path
|
||||
*/
|
||||
_closeFile(path) {
|
||||
const closers = this._closers.get(path);
|
||||
if (!closers) return;
|
||||
closers.forEach(closer => closer());
|
||||
this._closers.delete(path);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Path} path
|
||||
* @param {Function} closer
|
||||
*/
|
||||
_addPathCloser(path, closer) {
|
||||
if (!closer) return;
|
||||
let list = this._closers.get(path);
|
||||
if (!list) {
|
||||
list = [];
|
||||
this._closers.set(path, list);
|
||||
}
|
||||
list.push(closer);
|
||||
}
|
||||
|
||||
_readdirp(root, opts) {
|
||||
if (this.closed) return;
|
||||
const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts};
|
||||
let stream = readdirp(root, options);
|
||||
this._streams.add(stream);
|
||||
stream.once(STR_CLOSE, () => {
|
||||
stream = undefined;
|
||||
});
|
||||
stream.once(STR_END, () => {
|
||||
if (stream) {
|
||||
this._streams.delete(stream);
|
||||
stream = undefined;
|
||||
}
|
||||
});
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Export FSWatcher class
|
||||
exports.FSWatcher = FSWatcher;
|
||||
|
||||
/**
|
||||
* Instantiates watcher with paths to be tracked.
|
||||
* @param {String|Array<String>} paths file/directory paths and/or globs
|
||||
* @param {Object=} options chokidar opts
|
||||
* @returns an instance of FSWatcher for chaining.
|
||||
*/
|
||||
const watch = (paths, options) => {
|
||||
const watcher = new FSWatcher(options);
|
||||
watcher.add(paths);
|
||||
return watcher;
|
||||
};
|
||||
|
||||
exports.watch = watch;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user