1
0
forked from dyf/APP

Compare commits

..

259 Commits

Author SHA1 Message Date
9b6a5e095c merge upstream 2026-02-07 13:53:33 +08:00
3fecf3380a 100J续航时间显示优化 2026-02-07 09:54:38 +08:00
943d98dd40 1 2026-02-06 13:44:35 +08:00
7d657d4429 100J功能部分功能修改 2026-02-06 13:42:22 +08:00
1fc02b5f5a 100J页面功能完成 2026-02-05 11:40:56 +08:00
d62d3f734a 100J功能开发 2026-02-04 15:27:43 +08:00
7735abc2a1 merge upstream 2026-02-04 09:05:49 +08:00
e3f5ef4c91 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2026-02-03 18:56:26 +08:00
6e83056687 100J语音上传功能 2026-02-03 18:55:48 +08:00
dyf
2dc9c401dc Merge pull request 'new-20250827 修改安卓蓝牙未开启定位服务的问题' (#32) from liubiao/APP:new-20250827 into main
Reviewed-on: dyf/APP#32
2026-02-03 18:55:02 +08:00
73c24d08ca Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2026-02-03 13:08:59 +08:00
b1eab86ba6 修改安卓蓝牙未开启定位服务的问题 2026-02-03 13:08:49 +08:00
c626f3766e merge upstream 2026-02-03 13:07:11 +08:00
d67cc5b213 merge upstream 2026-02-03 13:07:04 +08:00
79a03a782b 100J页面 2026-02-02 18:11:52 +08:00
fcea5b1dba Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2026-02-02 10:14:48 +08:00
f3d502b00e 修复部分机型蓝牙报错的问题 2026-02-02 10:12:48 +08:00
dyf
184e395d1c Merge pull request 'new-20250827 蓝牙设备添加分享功能' (#31) from liubiao/APP:new-20250827 into main
Reviewed-on: dyf/APP#31
2026-01-30 13:35:03 +08:00
88111fb3f5 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2026-01-30 13:29:15 +08:00
ace473930b 6075调整 2026-01-30 13:29:11 +08:00
5399ecf359 调整一下底部小样式 2026-01-30 11:51:29 +08:00
23fe40902b 蓝牙设备添加分享功能 2026-01-29 16:52:52 +08:00
dae3561235 蓝牙配对模式优化,提示信息不正确,loading关闭时机不对的问题
蓝牙配对模式,修复提示不正确,loading关闭太早的问题
2026-01-29 15:08:08 +08:00
3745e5dc13 Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2026-01-29 14:40:33 +08:00
1e971292cd 6155添加分享 2026-01-29 14:40:20 +08:00
dyf
5fb4dd7386 Merge pull request 'new-20250827 完成102添加联机日志,报警日志' (#30) from liubiao/APP:new-20250827 into main
Reviewed-on: dyf/APP#30
2026-01-28 16:36:55 +08:00
d6ca84170f 完成102添加联机日志,报警日志 2026-01-28 16:31:34 +08:00
1b48751944 完成6107静态页面 2026-01-19 13:10:10 +08:00
d16fd893b6 修改import的方式 2026-01-14 11:09:13 +08:00
7fe5ae633c 删除一些没有使用的文件和代码 2026-01-14 09:42:12 +08:00
eb246ae12c 修复一些小问题,删除一些不需要的node_modules 2026-01-13 10:26:22 +08:00
90e0ee2271 修复类型页面图片全都显示一样的问题。 2026-01-13 09:58:42 +08:00
779017919b 修复从类型跳转至首页时,首页数据按类型筛选 2026-01-12 17:29:49 +08:00
98162ca214 加入6107设备页面、蓝牙配对模式修复首次进入找不到设备的问题 2026-01-12 16:18:27 +08:00
78adc0bfed 首页更新,添加蓝牙电量显示 2026-01-06 16:13:28 +08:00
d08d109fd1 首页优化加蒙板 2025-12-24 17:04:52 +08:00
830288e107 修复首页蓝牙连接断开时更新状态,修复670 SOS报警时红色提示 2025-12-24 14:47:21 +08:00
fce2f2ebcf 首页修改,删除、重命名成功后,前端直接修改数据源 2025-12-24 11:40:36 +08:00
637658a762 优化首页的下拉刷新、数据排序、绑定后刷新 2025-12-24 10:52:28 +08:00
425b7b9cfd 修复6155蓝牙上报数据灯光状态不跟随变化的问题。 2025-12-19 13:37:14 +08:00
bf615de600 Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-12-19 09:33:24 +08:00
d3bdc0f358 merge upstream 2025-12-17 14:08:08 +08:00
4c48f0efec 日常小bug修复 2025-12-17 09:00:14 +08:00
5fdeb88103 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-12-15 17:32:50 +08:00
666cbfba6d 7305,充电中,字体颜色修改 2025-12-15 17:32:46 +08:00
8a9a35b2bd 7305要13*13字体 2025-12-15 17:31:43 +08:00
80f0ec15b3 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-12-15 16:03:22 +08:00
b7b080a976 提交 2025-12-15 16:03:19 +08:00
6fcf9c814b 7305充电状态修复 2025-12-15 16:00:29 +08:00
2cf02932e5 018A UI部分完成了 2025-12-15 10:22:05 +08:00
8ad20ad7fc Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-12-09 15:23:23 +08:00
5a558f1ed8 修改服务协议和隐私政策,添加注销账号功能 2025-12-09 15:23:07 +08:00
dyf
a6f7d066c7 Merge pull request 'new-20250827' (#26) from liubiao/APP:new-20250827 into main
Reviewed-on: dyf/APP#26
2025-12-03 16:50:58 +08:00
0f49f2fb19 提交210历史记录 2025-12-03 16:45:52 +08:00
6414bf3d7a 4877保存已选的配组 2025-12-03 11:42:05 +08:00
e2d07e984f 修复670灯光问题 2025-12-03 10:20:11 +08:00
cd6d529523 修复一个Uniapp蓝牙的坑,App首页蓝牙状态功能添加 2025-12-02 11:32:56 +08:00
5fec8eff30 102完成真机实测 2025-12-01 16:37:21 +08:00
9ca14b1f32 Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-12-01 16:25:52 +08:00
d265e8a1ab merge upstream 2025-12-01 16:25:01 +08:00
6a2688caf4 102真机测试完成 2025-12-01 16:24:22 +08:00
07bd22e848 删除多余图标文件 2025-11-29 15:24:47 +08:00
052a7116c5 蓝牙搜索页面修改,添加名称筛选,从设备详情进入时自动带上蓝牙名筛选 2025-11-27 10:53:22 +08:00
d01abf267e 合并主分支版本,修复从设备页去搜索无法响应验证设备的问题 2025-11-27 08:44:42 +08:00
8ccc37cb93 强跟泛光指令修改 2025-11-26 16:06:34 +08:00
ebbac4232a Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-26 15:57:54 +08:00
362b752087 6155添加强泛光指令 2025-11-26 15:57:52 +08:00
5c69e32c2d 修复6155使用加号添加设备没有监听的问题 2025-11-26 15:56:55 +08:00
e247acdd5e 6155人员信息合成一个06格式头发送 2025-11-26 11:12:05 +08:00
b01ad9d698 删除测试App的部分文件,修复loading有时不显示的问题 2025-11-25 16:08:45 +08:00
2ba53fcf92 merge upstream 2025-11-24 08:20:45 +08:00
97b6825420 修复6155人员信息第一个字体缺失问题,画布取值加载预热机制 2025-11-22 18:28:43 +08:00
14d6fa7ccb 修改区分图片,动画协议 2025-11-21 18:47:20 +08:00
8270cc77d7 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP into new-20250827
# Conflicts:
#	pages/6155/deviceDetail.vue
2025-11-21 16:30:13 +08:00
ec6deab32a 合并主分支
# Conflicts:
#	pages/210/deviceControl/index.vue
#	pages/650/HBY650.vue
#	pages/common/index/index.vue
#	unpackage/dist/dev/app-plus/static/tabs/device-HL.png
#	unpackage/dist/dev/app-plus/static/tabs/device.png
#	unpackage/dist/dev/app-plus/static/tabs/my-HL.png
#	unpackage/dist/dev/app-plus/static/tabs/my.png
#	utils/BleReceive.js
#	utils/loading.js
2025-11-21 16:27:32 +08:00
1558045882 102主从机告警 2025-11-21 16:22:35 +08:00
27308e0ed1 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-21 16:12:57 +08:00
76d40bc096 修改人员信息时间前后 2025-11-21 16:12:55 +08:00
31b189dd72 关闭压塑保证ios正常6155 2025-11-21 15:59:58 +08:00
fc1fad0579 ios 2025-11-21 14:43:23 +08:00
864dd59b4c Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827
# Conflicts:
#	pages/6155/deviceDetail.vue
2025-11-21 14:21:10 +08:00
4790892a24 merge upstream 2025-11-21 14:18:55 +08:00
a8ce1d9680 6155发送视频修改,方便随时切换切片大小 2025-11-21 14:18:36 +08:00
5b62fd176f Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-21 13:25:41 +08:00
ad85c922e1 6155解决 iOS 上的分辨率检查问题 2025-11-21 13:25:38 +08:00
a7f09dfbc2 修改设备电量低,重复弹框提示两个弹框 2025-11-21 11:24:04 +08:00
7b2b7ea34c Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-21 11:10:49 +08:00
eea68b5276 6155限制人员信息,文字不能超过7个字 2025-11-21 11:10:47 +08:00
ac7e1873cd 修复6155电量同步显示问题 2025-11-21 11:07:10 +08:00
a28d4921a0 修复6155蓝牙数据问题 2025-11-20 17:51:26 +08:00
dyf
401e78cd8b Merge branch 'main' into new-20250827 2025-11-20 17:00:00 +08:00
516cc8324c Merge branch 'liubiao-new-20250827' 2025-11-20 16:44:34 +08:00
d0047907c1 210页面完成 2025-11-20 16:40:33 +08:00
294d854867 670加入用户确认收到消息 2025-11-20 16:40:14 +08:00
3a75d4df2b merge upstream 2025-11-19 11:34:56 +08:00
2a14d77f17 210主机联机页面代码修改 2025-11-19 11:12:54 +08:00
ea565276ee 4877小优化一下 2025-11-18 10:02:14 +08:00
c13cd92f8c 6155发图片修改 2025-11-17 16:37:37 +08:00
547ec3f94b 完成HBY102 2025-11-17 15:31:44 +08:00
f2e5e7c1f3 Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-11-17 15:31:14 +08:00
18fd446b07 完成HBY102 2025-11-17 15:30:57 +08:00
674f758b39 merge upstream 2025-11-17 15:29:11 +08:00
1ba22c7aae 210自动报警,手动报警 2025-11-17 10:20:54 +08:00
230ee5eb77 merge upstream 2025-11-17 09:38:17 +08:00
c8ea753b8e 恢复7305代码冲突 2025-11-17 09:29:05 +08:00
b24d34d32d Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-17 09:06:24 +08:00
04083446e7 1 2025-11-17 09:06:03 +08:00
1f3dfab4d2 merge upstream 2025-11-17 08:55:19 +08:00
cb9ed0b1da 添加102 2025-11-14 17:28:20 +08:00
dadad6ed19 添加token过期,跳转到登录页 2025-11-12 09:51:35 +08:00
c8f5567285 merge upstream 2025-11-10 17:28:29 +08:00
1ad1ae0ac9 4877V1完成 2025-11-10 17:27:37 +08:00
426fdeddee Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-08 10:33:20 +08:00
968d7a613d 6075页面功能开发 2025-11-08 10:33:00 +08:00
dyf
f835e25bbb Merge pull request 'new-20250827 一些小优化' (#22) from liubiao/APP:new-20250827 into main
Reviewed-on: dyf/APP#22
2025-11-08 10:32:38 +08:00
012eca6985 Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827
# Conflicts:
#	pages.json
#	pages/100/HBY100.vue
#	pages/6075/BJQ6075.vue
#	pages/7305/BJQ7305.vue
#	utils/BleReceive.js
2025-11-07 13:08:05 +08:00
623a47466a 合并线上代码 2025-11-07 12:16:10 +08:00
2493bb7113 完成100 2025-11-07 11:57:35 +08:00
b8ce1621b4 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-06 08:47:45 +08:00
c81a4d1903 6075设备控制页 2025-11-06 08:46:27 +08:00
27d212e7dc 继续优化7305 2025-11-05 19:18:05 +08:00
9037ef6ac3 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-05 11:17:11 +08:00
a30a631ea6 改成13*13符合设备端 2025-11-05 11:17:08 +08:00
2b72cc1a5c Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-05 11:13:35 +08:00
77be45f1f3 6075 2025-11-05 11:13:32 +08:00
a0c883f4e3 优化蓝牙连接7305同步状态 2025-11-05 10:22:17 +08:00
9313ec0106 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-11-05 08:48:15 +08:00
ca6345ee3e 6075页面开发 2025-11-05 08:48:13 +08:00
d06cd6cdfd 修复复杂字体渲染设备端乱序问题 2025-11-04 19:30:47 +08:00
2218ca0650 修改输入框文本 2025-11-01 17:32:03 +08:00
500b461bdd 修复7305设备上报问题 2025-11-01 17:21:45 +08:00
3526f28d06 修复蓝牙传输数据 2025-10-31 15:35:03 +08:00
3eeffdb62c Merge branch 'liubiao-new-20250827' 2025-10-31 11:15:39 +08:00
317c762edc 7305文件报错 2025-10-31 11:13:07 +08:00
c39cbcb34d 蓝牙开始、结束搜索添加状态判定 2025-10-30 11:10:57 +08:00
bd56ca997b 修复7305标签未闭合问题 2025-10-27 13:00:34 +08:00
cf60414d76 蓝牙断开连接变成异步操作 2025-10-27 11:51:38 +08:00
61ed91695f 蓝牙模块添加在web平台默认成功方便调试功能,4877功能完成 2025-10-27 10:52:17 +08:00
d37ccfeabc 完成BJQ4877功能开发 2025-10-24 17:21:18 +08:00
0909d9f023 merge upstream 2025-10-24 11:46:02 +08:00
b20a93dd28 修复传输时序问题 2025-10-24 11:42:56 +08:00
1d8b3b4a9a 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题
# Conflicts:
#	pages/7305/BJQ7305.vue
2025-10-24 11:08:32 +08:00
a5c6faa9da * 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题
* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

* 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题

修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题
2025-10-24 11:04:36 +08:00
15ba241317 修复蓝牙设备6155/7305全局弹窗与详情弹窗重复出现的问题 2025-10-24 11:00:35 +08:00
fa64e7f1fc merge upstream 2025-10-24 10:57:08 +08:00
45328120c1 修复6155/7305全局订阅与详情订阅重复弹窗 2025-10-24 10:56:37 +08:00
1de958df20 修复优化7305设备屏幕点阵取模兼容设备端填坑 2025-10-24 10:29:46 +08:00
0033649677 修改蓝牙接收数据处理逻辑,改成配置式,避免if无限增多 2025-10-23 16:36:48 +08:00
738ce209a6 跟朱工合并7305的功能
# Conflicts:
#	utils/BleHelper.js
#	utils/BleReceive.js
2025-10-23 16:10:53 +08:00
1ac41b3ed5 蓝牙接收数据统一处理修改 2025-10-23 15:40:17 +08:00
8487a4303a 解决安卓数据包问题,拆成小包发送,增加电量,续航时间,充电检测 2025-10-23 15:28:47 +08:00
f51b6c5a85 一点小优化,从设备详情去绑定蓝牙设备,成功后更新设备详情的连接状态 2025-10-23 14:54:12 +08:00
2339c1c8d0 蓝牙发现服务重试时间逐步增加 2025-10-23 10:42:30 +08:00
2d3b896243 7305点阵优化后组件 2025-10-23 08:51:34 +08:00
61433fca05 7305修改人员信息的点阵方式 2025-10-23 08:46:44 +08:00
c6ed8635c7 添加录音的权限 2025-10-21 12:13:55 +08:00
90cee62df1 6331前端功能初步完成,扩展msgPop支持自定义插槽 2025-10-17 17:29:08 +08:00
b114f6690d 蓝牙添加连接、断开、可用、不可用控制 2025-10-17 11:52:26 +08:00
0ce4f4bef0 7305添加文字发送、图片发送。蓝牙通用模块增加连接/断开订阅 2025-10-16 11:07:04 +08:00
fe87727e2d 图片裁剪页面加入自定义尺寸,7305修改发送文字和图片的方式 2025-10-15 16:40:02 +08:00
8689781e17 优化蓝牙搜索页面的动画闪烁感,优化从设备页面去匹配蓝牙时给出目标设备的提示 2025-10-13 10:57:03 +08:00
e3a2624509 修改670人员信息重复发送的问题/修改版本更新的方式/加入检查更新的连接 2025-10-10 17:31:33 +08:00
4c3999251e Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-10-09 14:40:02 +08:00
f629a08385 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP into new-20250827
# Conflicts:
#	pages/common/login/index.vue
2025-10-09 14:39:35 +08:00
4f3a8bb3ec 670人员登记调整,蓝牙成功不再走后端 2025-10-09 14:34:22 +08:00
e042436c5b 首页,下拉加载问题优化修改 2025-10-08 14:08:45 +08:00
7c2e68bca2 merge upstream 2025-09-30 13:35:18 +08:00
abd1753111 判断离线故障状态 2025-09-29 14:26:50 +08:00
c556b802e4 修复650、670长度字段00的异常,配置文件全部修改为生产环境 2025-09-29 10:01:39 +08:00
d9e45becff 一点小优化 2025-09-26 16:31:56 +08:00
fd3a046ab3 修复动画效果在某些机型上显示问题 2025-09-26 15:50:12 +08:00
195b9df67c Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-09-26 13:50:56 +08:00
3ac113de3f 修改蓝牙发现逻辑自动连接过的不再被发现的问题,上架驳回问题处理 2025-09-26 13:50:29 +08:00
cb86f0b7d8 首页部分代码优化 2025-09-26 13:43:55 +08:00
21e468c79f merge upstream 2025-09-25 17:16:47 +08:00
bccba815cb 首页无数据时 2025-09-25 17:15:17 +08:00
bc86bed03d 解决冲突 2025-09-25 16:16:49 +08:00
457197ca54 修改mainfest解决打包报错 2025-09-25 15:58:33 +08:00
511caa60d1 细节优化 2025-09-25 15:07:40 +08:00
67cfda12aa 首页下拉刷新修改 2025-09-25 15:04:52 +08:00
15d99211a0 mainfast.json中去掉广告标识 2025-09-25 11:01:42 +08:00
17e76f9fa8 670增加去连接蓝牙,其它体验问题小调整 2025-09-25 09:59:37 +08:00
497cce1e45 670 SOS转到服务端进行 2025-09-24 11:34:15 +08:00
8a54aa85d1 670增加跳转至地图,修改mqtt.js,使用request中的环境配置 2025-09-24 10:18:31 +08:00
2adc73cdab 尝试解决主分支冲突 2025-09-24 08:35:34 +08:00
ab696c3076 670小问题修复 2025-09-23 16:57:31 +08:00
2546287bb4 所有分享列表动态跳转 2025-09-23 14:10:08 +08:00
97cbb25753 670添加分享的权限 2025-09-23 13:54:38 +08:00
f3c21c2e1b Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827
# Conflicts:
#	pages/670/HBY670.vue
2025-09-23 12:00:43 +08:00
f8f199ad32 670控制页加入从分享进入时的权限控制 2025-09-23 11:56:35 +08:00
ed49622f1a 分享跳转动态修改,文件移到共用组件 2025-09-23 11:51:25 +08:00
50373f407d 650/670增加关闭探测功能,删除一些跟供应商调试的页面 2025-09-23 08:36:21 +08:00
1cd9853f2f 自动更新,从多个接口更新,避免单一的接口挂掉了无法更新 2025-09-19 13:46:33 +08:00
482a47bd4f 蓝牙增加断开重连、换设备后可以去再次绑定 2025-09-19 12:01:06 +08:00
b83df1cfbf 修改mqtt,根据http 或者http动态修改ws wss访问地址 2025-09-19 10:33:42 +08:00
ff5e363ccc Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-09-19 08:25:37 +08:00
cb44810c6b 670加入机器状态、设备详情加接口请求 2025-09-18 17:31:40 +08:00
9be161d8aa 注销账户功能页面开发 2025-09-18 16:46:32 +08:00
4123e7a869 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-09-18 14:20:11 +08:00
5116ae4ff7 注销账号,账号安全页面功能开发 2025-09-18 14:20:08 +08:00
404e42a7d8 Merge branch 'liubiao-new-20250827'
# Conflicts:
#	pages.json
2025-09-18 11:48:39 +08:00
dcecf07ecc 670发送紧急通知调整,与PC端一致的处理方案 2025-09-18 11:32:22 +08:00
d8f281a891 新增注册,找回密码功能页面 2025-09-17 16:05:50 +08:00
da9a9f4874 完成7305,添加在详情页去绑定蓝牙设备 2025-09-17 15:21:20 +08:00
ed8f02fb39 解决订阅消息有时候会永远pending的问题 2025-09-16 17:30:46 +08:00
6331190f0d 增加蓝牙设备人员信息登记上传 2025-09-16 14:51:23 +08:00
778594574b 修改App图标、名称、蓝牙加入断线重连 2025-09-16 11:37:06 +08:00
52b3bd796c Merge branch 'new-20250827' of http://47.107.152.87:3000/liubiao/APP into new-20250827 2025-09-15 11:56:15 +08:00
9c9c684ab6 650添加应答,app图标添加 2025-09-15 11:55:44 +08:00
48da6d0e1c 6170上传加裁剪功能 2025-09-11 14:21:16 +08:00
55620449e4 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-09-10 10:47:08 +08:00
d7a91a6df2 适配灯光弹框 2025-09-10 10:47:04 +08:00
07064b4b85 修复扫码绑定完成返回键,首页未刷新问题 2025-09-10 10:42:11 +08:00
6ee45f6868 修改bug 2025-09-05 18:48:46 +08:00
8108744d56 Merge branch 'liubiao-new-20250827' 2025-08-30 14:37:40 +08:00
c537e17780 修改设备实时状态参数,同后端一起修改 2025-08-30 14:34:44 +08:00
2f437e16b6 排除unpackge冲突 2025-08-28 15:05:34 +08:00
8460aa1be2 670分享功能 2025-08-28 14:55:07 +08:00
c4cd556bd4 670分享功能 2025-08-28 14:46:04 +08:00
9846fe2315 添加报警功能 2025-08-28 14:05:06 +08:00
82ca470b2d Merge branch 'main' of http://47.107.152.87:3000/dyf/APP 2025-08-27 16:27:42 +08:00
49834be90d 报警 2025-08-27 16:26:57 +08:00
cd912b861e 670完成 2025-08-27 09:08:59 +08:00
dfb6f29683 670完成 2025-08-26 15:42:26 +08:00
c9996748eb Revert "提交"
This reverts commit 8d97dcf121.
2025-08-26 15:09:14 +08:00
b1ba355cb2 Merge branch 'liubiao-main' 2025-08-26 08:39:27 +08:00
2c2a75aa02 650完成,并解决了冲突 2025-08-25 17:31:14 +08:00
295f904b10 650完成 2025-08-25 17:28:41 +08:00
7f4fd00937 650完成 2025-08-25 17:15:06 +08:00
bbf55c58f0 650完成,670完成部分 2025-08-25 17:13:13 +08:00
793fe7132b 添加全局蓝牙监听 2025-08-18 16:33:06 +08:00
585bd76a0a 添加全局蓝牙监听 2025-08-18 16:32:25 +08:00
96acaa5d94 添加全局蓝牙监听 2025-08-18 16:31:41 +08:00
5e5bde6934 添加全局蓝牙消息监听 2025-08-18 16:30:44 +08:00
76329756c9 解决版本冲突 2025-08-18 08:49:46 +08:00
535f4728ea 添加全局消息监听 2025-08-18 08:38:28 +08:00
e95b2466e1 6155完成部分协议对接 2025-08-15 16:39:00 +08:00
6ef2bb08b9 合并版本 2025-08-15 11:09:06 +08:00
4df8330738 添加类型路由后,合并版本 2025-08-15 10:52:29 +08:00
84c0a6ae18 跟主分支合并 2025-08-15 09:10:11 +08:00
ceafd10b72 650小bug修复 2025-08-15 09:04:27 +08:00
6b4d47828e 修改main.js,去除原有的蓝牙插件 2025-08-15 09:03:48 +08:00
6650334525 增加6155、650跳转 2025-08-14 17:27:10 +08:00
958a74101e 650全局蓝牙优化 2025-08-14 17:25:53 +08:00
1ed6ca4828 修复650id大小写错误 2025-08-13 14:56:24 +08:00
e39356bbe0 增加绑定蓝牙页面 2025-08-13 14:39:29 +08:00
5eea3a0fff 增加650的跳转 2025-08-13 14:38:57 +08:00
d9a28d0345 添加全局蓝牙 2025-08-12 15:27:14 +08:00
47a9dace85 Merge branch 'main' of http://47.107.152.87:3000/dyf/APP
# Conflicts:
#	pages.json
#	unpackage/dist/dev/app-plus/app-config-service.js
#	unpackage/dist/dev/app-plus/app-service.js
#	unpackage/dist/dev/app-plus/app-view.js
#	unpackage/dist/dev/app-plus/manifest.json
#	utils/request.js
2025-08-11 15:21:37 +08:00
4ab10bb251 BLE发送数据添加安卓苹果不同的逻辑 2025-08-11 14:51:09 +08:00
ca844723fa 6155点阵插件完成。 2025-08-07 08:48:02 +08:00
b3c0b74628 650蓝牙协议更新 2025-08-05 13:14:22 +08:00
a3865e2f26 添加文本行转点阵的插件 2025-07-31 13:54:20 +08:00
4ebdec8dac Merge remote-tracking branch 'upstream/main'
# Conflicts:
#	pages/common/index/index.vue
2025-07-31 13:35:07 +08:00
e5e2aca0c4 Merge branch 'main' of http://47.107.152.87:3000/liubiao/APP
# Conflicts:
#	.gitignore
#	pages/common/index/index.vue
#	unpackage/dist/dev/app-plus/app-config-service.js
#	unpackage/dist/dev/app-plus/app-service.js
#	unpackage/dist/dev/app-plus/app-view.js
#	unpackage/dist/dev/app-plus/manifest.json
#	utils/request.js
2025-07-29 09:40:01 +08:00
40639d2bad 蓝牙握手提交 2025-07-29 09:36:54 +08:00
3c0bf2f770 添加蓝牙通讯握手 2025-07-29 09:34:15 +08:00
0ac0d1998a Merge branch 'main' of http://47.107.152.87:3000/liubiao/APP
# Conflicts:
#	unpackage/dist/dev/app-plus/app-config-service.js
#	unpackage/dist/dev/app-plus/app-service.js
#	unpackage/dist/dev/app-plus/app-view.js
2025-07-15 13:18:13 +08:00
e470726fbd 添加几个函数 2025-07-14 11:42:35 +08:00
466 changed files with 54102 additions and 377030 deletions

6
.gitignore vendored
View File

@ -1,5 +1 @@
*node_modules/*
*dist/*
*unpackage/*
unpackage/

View File

@ -6,6 +6,7 @@
"type" : "uni-app:app-ios"
},
{
"customPlaygroundType" : "local",
"playground" : "standard",
"type" : "uni-app:app-android"
}

179
App.vue
View File

@ -1,23 +1,74 @@
<script>
import bleTool from '@/utils/BleHelper.js'
import upgrade from '@/utils/update.js'
export default {
onLaunch: function() {
//以下代码仅在开发时使用,否则会出现不可预知的问题。
//清除登陆之外的所有信息;
// let store=uni.getStorageInfoSync();
// store.keys.forEach((val,index,array)=>{
// if(val=="tokenTime"){
// let time=uni.getStorageSync(val);
// if(!time){
// time=0;
// }
// let currTime=new Date().getTime();
// if(currTime>=time){
// uni.removeStorageSync(val);
// uni.removeStorageSync("token");
// uni.removeStorageSync("clientID");
// }
// }
// else if(val=="token" || val=="clientID" || val=='phone'){
// console.log("忽略登陆信息");
// }else{
// uni.removeStorageSync(val);
// }
// });
// uni.clearStorageSync();
//以上代码仅在开发时使用,否则会出现不可预知的问题。
// #ifdef APP-PLUS
var appid = plus.runtime.appid;
console.log('应用的 appid 为:' + appid);
// #endif
},
onShow: function() {
console.log('App Show')
console.log('App Show');
//将检查更新换到onshow,因为苹果用户喜欢一直挂着
uni.getSystemInfo({
success: function(res) {
if (res.uniPlatform == 'app') {
bleTool.getBleTool();
let appid = plus.runtime.appid;
if (appid !== 'HBuilder') {
console.log("appid=", appid);
upgrade.checkAndUpdateWgt();
}
}
}
});
},
onHide: function() {
console.log('App Hide')
console.log('App Hide');
},
onError(ex) {
console.error("出现了未知的异常",ex);
}
}
</script>
<style lang="scss">
@import 'vk-uview-ui/index.scss';
/* #ifdef APP-ANDROID */
//苹果应用以下样式后Slider不可拖动
uni-slider .uni-slider-handle-wrapper {
border-radius: 20rpx;
}
uni-slider .uni-slider-thumb {
width: 66rpx !important;
height: 80rpx !important;
@ -26,32 +77,102 @@
margin-left: -72rpx !important;
}
uni-slider .uni-slider-handle-wrapper {
height: 88rpx;
position: relative;
}
.custom-file-picker .file-picker__box-content {
background: rgba(26, 26, 26, 1);
border: none !important;
border-radius: 45rpx;
width: 180rpx;
height: 180rpx;
}
.uni-file-picker.custom-file-picker {
overflow: inherit !important;
}
.custom-file-picker .icon-add {
height: 5rpx !important;
width: 70rpx !important;
}
.uni-picker-view-mask{
background: rgba(42, 42, 42, 1);
z-index: -1;
}
.uni-picker-view-content{
position: inherit;
}
.uni-picker-view-wrapper{
background: rgba(42, 42, 42, 1);
}
</style>
// }
/* #endif */
.custom-file-picker .file-picker__box-content {
background: rgba(26, 26, 26, 1);
border: none !important;
border-radius: 45rpx;
width: 180rpx;
height: 180rpx;
}
.uni-file-picker.custom-file-picker {
overflow: inherit !important;
}
.custom-file-picker .icon-add {
height: 5rpx !important;
width: 70rpx !important;
}
.uni-picker-view-mask {
background: rgba(42, 42, 42, 1);
z-index: -1;
}
.uni-picker-view-content {
position: inherit;
}
.uni-picker-view-wrapper {
background: rgba(42, 42, 42, 1);
}
.green {
color: #aed600 !important;
}
.red {
color: #FF0000 !important;
}
.maincontent {
width: 100%;
min-height: 100vh;
height: auto;
padding: 30rpx;
box-sizing: border-box;
}
.contentBg {
background-color: #121212;
color: #ffffffde;
}
.fleft {
float: left;
}
.fright {
float: right;
}
.clear {
clear: both;
}
.displayNone {
display: none !important;
}
.visibilityHidden{
visibility: hidden !important;
}
.center {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
justify-content: center;
align-items: center;
}
@font-face {
font-family: "PingFang SC";
src: url("~@/static/fonts/PingFangSC.ttf") format("opentype");
}
@font-face {
font-family: "PingFangBold";
src: url("~@/static/fonts/PingFangBold.ttf") format("opentype");
}
</style>

View File

@ -1,3 +1,29 @@
{
"prompt" : "template"
"version" : "1",
"prompt" : "template",
"title" : "服务协议和隐私政策",
"message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://dmsapp.skf.com.cn/HummerService/Resource/Template/1765175615670.html\">《服务协议》</a>和<a href=\"https://dmsapp.skf.com.cn/HummerService/Resource/Template/1765176086420.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept" : "同意并接受",
"buttonRefuse" : "暂不同意",
"hrefLoader" : "system",
"backToExit" : "false",
"disagreeMode" : {
"support" : false,
"loadNativePlugins" : false,
"visitorEntry" : false,
"showAlways" : true
},
"styles" : {
"backgroundColor" : "#FFFFFF",
"borderRadius" : "5px",
"title" : {
"color" : "#FFFFFF"
},
"buttonAccept" : {
"color" : "#b9e203"
},
"buttonRefuse" : {
"color" : "#555555"
}
}
}

91
api/100J/HBY100-J.js Normal file
View File

@ -0,0 +1,91 @@
import request from '@/utils/request'
// 获取语音管理列表
export function deviceVoliceList(params) {
return request({
url: `/app/video/queryAudioFileList`,
method: 'get',
data:params
})
}
// 重命名
export function videRenameAudioFile(data) {
return request({
url: `/app/video/renameAudioFile`,
method: 'post',
data:data
})
}
// 删除语音文件列表
export function deviceDeleteAudioFile(params) {
return request({
url: `/app/video/deleteAudioFile`,
method: 'get',
data:params
})
}
// 更新语音,使用语音
export function deviceUpdateVoice(data) {
return request({
url: `/app/hby100j/device/updateVoice`,
method: 'post',
data:data
})
}
// 100J信息
export function deviceDetail(id) {
return request({
url: `/app/hby100j/device/${id}`,
method: 'get',
})
}
// 爆闪模式
export function deviceStrobeMode(data) {
return request({
url: `/app/hby100j/device/strobeMode`,
method: 'post',
data:data
})
}
// 强制报警
export function deviceForceAlarmActivation(data) {
return request({
url: `/app/hby100j/device/forceAlarmActivation`,
method: 'post',
data:data
})
}
// 爆闪频率
export function deviceStrobeFrequency(data) {
return request({
url: `/app/hby100j/device/strobeFrequency`,
method: 'post',
data:data
})
}
// 灯光调节亮度
export function deviceLightAdjustment(data) {
return request({
url: `/app/hby100j/device/lightAdjustment`,
method: 'post',
data:data
})
}
// 调节音量
export function deviceUpdateVolume(data) {
return request({
url: `/app/hby100j/device/updateVolume`,
method: 'post',
data:data
})
}
// 语音播放
export function deviceVoiceBroadcast(data) {
return request({
url: `/app/hby100j/device/voiceBroadcast`,
method: 'post',
data:data
})
}

110
api/4877/BJQ4877.js Normal file
View File

@ -0,0 +1,110 @@
export const colors=[
{
r: 255,
g: 0,
b: 0,
name: '红色',
hex: '#FF0000',
check: false,
id: 1
},
{
r: 0,
g: 0,
b: 255,
name: '蓝色',
hex: '#0000FF',
check: false,
id: 2
},
{
r: 0,
g: 255,
b: 0,
name: '绿色',
hex: '#00FF00',
check: false,
id: 3
},
{
r: 255,
g: 255,
b: 0,
name: '黄色',
hex: '#FFFF00',
check: false,
id: 4
},
{
r: 0,
g: 255,
b: 255,
name: '青色',
hex: '#00FFFF',
check: false,
id: 5
},
{
r: 255,
g: 0,
b: 255,
name: '紫红色',
hex: '#FF00FF',
check: false,
id: 6
},
{
r: 51,
g: 255,
b: 153,
name: '薄荷绿',
hex: '#33FF99',
check: false,
id: 7
},
{
r: 255,
g: 102,
b: 102,
name: '珊瑚红',
hex: '#FF6666',
check: false,
id: 8
},
{
r: 153,
g: 255,
b: 0,
name: '柠绿',
hex: '#99FF00',
check: false,
id: 9
},
{
r: 128,
g: 0,
b: 128,
name: '紫色',
hex: '#800080',
check: false,
id: 10
},
{
r: 204,
g: 102,
b: 255,
name: '淡紫',
hex: '#CC66FF',
check: false,
id: 11
},
{
r: 102,
g: 204,
b: 255,
name: '浅蓝',
hex: '#66CCFF',
check: false,
id: 12
}
]

78
api/6075/6075.js Normal file
View File

@ -0,0 +1,78 @@
import request from '@/utils/request'
export function deviceDetail(id) {
return request({
url: `/app/bjq6075/device/${id}`,
method: 'get',
})
}
// 获取设备分享详细信息
export function deviceShareId (id) {
return request({
url: `/app/bjq6075/device/getShareInfo/${id}`,
method: 'get',
})
}
// 人员信息登记
export function registerPersonInfo(data) {
return request({
url: `/app/bjq6075/device/registerPersonInfo`,
method: 'post',
data: data
})
}
// 发送信息
export function deviceSendMessage(data) {
return request({
url: `/app/bjq6075/device/sendMessage`,
method: 'post',
data: data
})
}
// 主灯光模式设置
export function lightModeSettings(data) {
return request({
url: `/app/bjq6075/device/lightModeSettings`,
method: 'post',
data: data
})
}
// 辅灯模式设置
export function auxiliaryLightModeSettings(data) {
return request({
url: `/app/bjq6075/device/auxiliaryLightModeSettings`,
method: 'post',
data: data
})
}
// 激光模式设置
export function laserModeSettings(data) {
return request({
url: `/app/bjq6075/device/laserModeSettings`,
method: 'post',
data: data
})
}
// 灯光亮度设置
export function lightBrightnessSettings(data) {
return request({
url: `/app/bjq6075/device/lightBrightnessSettings`,
method: 'post',
data: data
})
}
// 声光报警
export function salaModeSettings(data) {
return request({
url: `/app/bjq6075/device/salaModeSettings`,
method: 'post',
data: data
})
}
// 地图逆解析
export function mapReverseGeocoding(data) {
return request({
url: `/app/bjq6075/device/mapReverseGeocoding`,
method: 'post',
data: data
})
}

View File

@ -63,11 +63,6 @@ export function mapReverseGeocoding(data) {
})
}
// 或者设备状态
export function deviceRealTimeStatus(params) {
return request({
url: `/app/device/realTimeStatus`,
method: 'get',
data:params
})
}
export function deviceRealTimeStatus(){
return Promise.resolve({code:500});
}

View File

@ -1,4 +1,4 @@
import {request,baseURL} from '@/utils/request'
import request, { baseURL } from '@/utils/request'
function getdata(data,url,method){
return new Promise((resolve,reject)=>{
@ -9,13 +9,17 @@ function getdata(data,url,method){
if(!method){
method='POST';
}
request({
let cfg={
url: url,
method: method,
data:data
}).then((res)=>{
};
request(cfg).then((res)=>{
console.log("res=",res);
resolve(res);
}).catch(ex=>{
console.log("ex=",ex);
reject(ex);
});
});
@ -81,10 +85,29 @@ function sendPic(data){
});
}
//设备详情
function getDetail(id){
return request({
url: '/api/xinghan/device/'+id,
method: 'get',
})
}
//发送SOS
function sendSos(data){
return request({
url: '/app/xinghan/device/SOSGradeSettings',
method: 'post',
data:data
})
}
export default{
sendUsr:sendUsr,
warnMsg:warnMsg,
sendPic:sendPic
sendPic:sendPic,
getDetail:getDetail,
sendSos:sendSos,
getdata:getdata
}

55
api/670/History.js Normal file
View File

@ -0,0 +1,55 @@
import request, { baseURL } from '@/utils/request'
function getdata(data,url,method){
return new Promise((resolve,reject)=>{
if(!url){
reject('url为空');
return;
}
if(!method){
method='POST';
}
request({
url: url,
method: method,
data:data
}).then((res)=>{
console.log("res=",res);
resolve(res);
}).catch(ex=>{
console.log("ex=",ex);
reject(ex);
});
});
}
//获取开关机数据
function getSwithData(data){
let url="";
return getdata(data,url,"POST");
}
//报警信息
function getWarnData(data){
let url=""
return getdata(data,url,"POST");
}
//故障信息
function getFaulData(data){
let url=""
return getdata(data,url,"POST");
}
export default{
getSwithData:getSwithData,
getWarnData:getWarnData,
getFaulData:getFaulData
}

View File

@ -1,5 +1,5 @@
import request from '@/utils/request'
import qs from 'qs'
// 设备列表
export function deviceInfo(params) {
return request({
@ -17,6 +17,13 @@ export function deviceTypeList(params) {
})
}
export function typeAll(){
return request({
url: '/app/xinghan/device/typeAll',
method: 'get'
});
}
// 删除设备列表接口
export function deviceUnbind(id) {
return request({

View File

@ -4,7 +4,8 @@ export function login(data) {
return request({
url: '/app/auth/login',
method: 'POST',
data: data
data: data,
isAuthen:false
})
}
// 注册发送验证码
@ -15,16 +16,65 @@ export function resourceSmsCode(params) {
data: params
})
}
// 退出登录
export function Logout(data) {
return request({
url: '/app/auth/logout',
url: '/app/userCenter/logout',
method: 'POST',
data: data
})
}
// 注册
export function register(data) {
return request({
url: '/app/auth/register',
method: 'POST',
data: data
})
}
// 用户注册短信验证码
export function registerSmsCode(data) {
return request({
url: '/app/auth/registerSmsCode',
method: 'GET',
data: data
})
}
// 忘记密码短信验证码
export function forgetPasswordSmsCode(data) {
return request({
url: '/app/auth/forgetPasswordSmsCode',
method: 'GET',
data: data
})
}
// 找回密码登录
export function forgetPassword(data) {
return request({
url: '/app/auth/forgetPassword',
method: 'POST',
data: data
})
}
// 修改密码
export function updatePassword(data) {
return request({
url: '/app/userCenter/updatePassword',
method: 'POST',
data: data
})
}
// 用户注销
export function cancelAccount(data) {
return request({
url: '/app/userCenter/cancelAccount',
method: 'POST',
data: data
})
}

View File

@ -1,5 +1,5 @@
import request from '@/utils/request'
import qs from 'qs'
// 查询列表
export function fileInfo(params) {
return request({

View File

@ -26,7 +26,7 @@
<view class="p100" :style="{backgroundColor:config.activeIndex==index?config.itemBgColor:'',
justifyContent:config.textAlign
}">
<view class="imgContent" :style="{
<view class="imgContent" v-if="item.icon" :style="{
height:config.itemHeight,
width:config.itemHeight
}">

View File

@ -17,6 +17,7 @@
:style="{color:textColor || getTypeStyle('textColor')}"
@click="closeClick"
>x</view>
<view v-if="!visiblePrompt">
<image
v-if="iconUrl"
@ -25,7 +26,10 @@
class="popup-icon"
:style="{ tintColor: textColor || getTypeStyle('textColor') }"
></image>
<view class="popup-message">{{ message }}</view>
<view class="popup-message" :class="showSlot?'displayNone':''">{{ message }}</view>
<view class="popup-message" :class="showSlot?'':'displayNone'">
<slot></slot>
</view>
</view>
@ -40,16 +44,18 @@
/>
</view>
<view class="popBtnContent">
<view class="popBtnContent" v-show="showCancel || buttonText">
<view
class="popup-button-cancel"
:style="{display:showCancel?'block':'none'}"
@click="handleCancelClick"
>{{ buttonCancelText?buttonCancelText:'取消' }}</view>
<view
class="popup-button"
:class="buttonText?'':'displayNone'"
:style="{
backgroundColor: buttonBgColor || getTypeStyle('buttonBgColor'),
color: buttonTextColor || getTypeStyle('buttonTextColor')
@ -125,6 +131,10 @@ export default {
headerTxt:{
type:String,
default:""
},
showSlot:{
type:Boolean,
default:false
}
},
data() {
@ -177,17 +187,19 @@ export default {
return styles[this.type][styleType]
},
handleButtonClick() {
console.log('[MessagePopup] Button clicked with value:', this.inputValue)
this.$emit('buttonClick', this.inputValue)
},
handleMaskClick() {
console.log('[MessagePopup] Mask clicked')
this.$emit('maskClick')
},
closeClick(){
this.$emit('closePop')
},
handleCancelClick(){
this.$emit('cancelPop');
},
handleInput(e) {
@ -200,6 +212,9 @@ export default {
</script>
<style>
.displayNone{
display: none !important
}
.message-popup {
position: fixed;
top: 0;
@ -378,4 +393,6 @@ padding-top: 40rpx;
}
</style>

View File

@ -1,194 +1,254 @@
<template>
<view>
<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "TextToHexV1",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * this.fontSize;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
let convertCharToMatrix=function(imageData) {
// console.log("imgData=",imageData)
let matrix = [];
// 逐行处理
for (let y = 0; y < 16; y++) {
let byte1 = 0,
byte2 = 0;
// 每行16个像素分为两个字节
for (let x = 0; x < 16; x++) {
// 计算像素在imageData中的索引 (RGBA格式)
let index = (y * 16 + x) * 4;
let red = imageData[index];
// 黑色像素R值较低视为1白色视为0
let isBlack = red < 128;
if (x < 8) {
// 第一个字节左8位
if (isBlack) {
byte1 |= 0x80 >> x; // 从左到右设置位
}
} else {
// 第二个字节右8位
if (isBlack) {
byte2 |= 0x80 >> (x - 8);
}
}
}
// 将字节转换为两位十六进制字符串
matrix.push('0x' + byte1.toString(16).padStart(2, '0').toUpperCase());
matrix.push('0x' + byte2.toString(16).padStart(2, '0').toUpperCase());
}
return matrix;
}
let drawTxt=async (textLine)=> {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = this.calcLineWidth(textLine);
this.currentCanvasHeight = this.fontSize;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFang SC", PingFang SC, Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
result={
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
console.log("item=",item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData));
}
console.log("hexs=",linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
visibility: hidden;
}
<template>
<view>
<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "TextToHexV1",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null,
// 标记是否已经预热过画布
canvasWarmed: false
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * 16;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 预热画布确保画布和字体完全准备好解决APP重新打开后第一次获取数据不完整的问题
*/
async warmupCanvas() {
if (this.canvasWarmed) {
return;
}
try {
// 设置画布尺寸
this.currentCanvasWidth = 16;
this.currentCanvasHeight = 16;
// 清空画布
this.clearCanvas();
// 绘制一个测试字符来预热字体和画布
this.ctx.setFillStyle(this.color);
this.ctx.setFontSize(this.fontSize);
this.ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
this.ctx.setTextBaseline('middle');
this.ctx.fillText('测', 0, 8);
// 等待画布绘制完成
await new Promise((resolve) => {
this.ctx.draw(false, () => {
// 获取一次测试数据确保canvasGetImageData API已准备好
setTimeout(() => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: 16,
height: 16,
success: () => {
this.canvasWarmed = true;
resolve();
},
fail: () => {
this.canvasWarmed = true;
resolve();
}
});
}, 100);
});
});
// 额外等待确保字体完全加载
await new Promise(resolve => setTimeout(resolve, 200));
} catch (ex) {
console.log("画布预热异常:", ex);
this.canvasWarmed = true; // 即使失败也标记为已预热,避免重复尝试
}
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
// 第一次调用时先预热画布解决APP重新打开后第一次获取数据不完整的问题
await this.warmupCanvas();
let convertCharToMatrix=function(imageData) {
// console.log("imgData=",imageData)
let matrix = [];
// 逐行处理
for (let y = 0; y < 16; y++) {
let byte1 = 0,
byte2 = 0;
// 每行16个像素分为两个字节
for (let x = 0; x < 16; x++) {
// 计算像素在imageData中的索引 (RGBA格式)
let index = (y * 16 + x) * 4;
let red = imageData[index];
// 黑色像素R值较低视为1白色视为0
let isBlack = red < 128;
if (x < 8) {
// 第一个字节左8位
if (isBlack) {
byte1 |= 0x80 >> x; // 从左到右设置位
}
} else {
// 第二个字节右8位
if (isBlack) {
byte2 |= 0x80 >> (x - 8);
}
}
}
// 将字节转换为两位十六进制字符串
matrix.push('0x' + byte1.toString(16).padStart(2, '0').toUpperCase());
matrix.push('0x' + byte2.toString(16).padStart(2, '0').toUpperCase());
}
return matrix;
}
let drawTxt=async (textLine)=> {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = this.calcLineWidth(textLine);
this.currentCanvasHeight = 16;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
// ctx.setTextAlign('center')
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
result={
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData));
}
// console.log("hexs=",linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
visibility: hidden;
}
</style>

View File

@ -0,0 +1,231 @@
<template>
<view>
<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "textToDotMatrix",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * 16;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
let binaryToHex = (binaryArray) => {
if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
throw new Error("输入必须是包含8个元素的二进制数组");
}
// 检查每个元素是否为0或1
if (!binaryArray.every(bit => bit === 0 || bit === 1)) {
throw new Error("数组元素必须只能是0或1");
}
// 将二进制数组转换为十进制数
let decimalValue = 0;
for (let i = 0; i < 8; i++) {
// 计算每个位的权重并累加
decimalValue += binaryArray[i] * Math.pow(2, 7 - i);
}
// 将十进制转换为十六进制字符串并添加0x前缀
const hexString = "0x" + decimalValue.toString(16).padStart(2, '0').toUpperCase();
return hexString;
}
let convertCharToMatrix = (imageData, item) => {
// console.log("imgOldData=", imageData)
let matrix = [];
let arr = [];
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
// 计算像素在imageData中的索引 (RGBA格式)
let index = (y * 16 + x) * 4;
let red = imageData[index];
// 黑色像素R值较低视为1白色视为0
let isBlack = red < 128 ? 1 : 0;
arr.push(isBlack);
}
}
let firstHalf = arr.slice(0, arr.length / 2); // [1, 2, ..., 128]
let secondHalf = arr.slice(arr.length / 2); // [129, 130, ..., 256]
for (let i = 0; i < 16; i++) {
let tmp = [];
for (let index = i; index < firstHalf.length; index += 16) {
tmp.push(firstHalf[index]);
}
tmp = tmp.reverse();
matrix.push(binaryToHex(tmp));
}
for (let i = 0; i < 16; i++) {
let tmp = [];
for (let index = i; index < secondHalf.length; index += 16) {
tmp.push(secondHalf[index]);
}
tmp = tmp.reverse();
matrix.push(binaryToHex(tmp));
}
console.log("matrix=", matrix);
return matrix;
}
let drawTxt = async (textLine) => {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = this.calcLineWidth(textLine);
this.currentCanvasHeight = 16;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
// ctx.setTextAlign('center')
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
result = {
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
console.log("item=", item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData, item));
}
console.log("hexs=", linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
visibility: hidden;
}
</style>

View File

@ -0,0 +1,262 @@
<template>
<view>
<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "textToDotMatrixFor7305",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null,
// 标记画布是否已预热(解决首次发送像素不完整问题)
canvasWarmed: false
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * this.fontSize;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 预热画布,防止 APP 首次调用时获取到的像素数据不完整
*/
async warmupCanvas() {
if (this.canvasWarmed) {
return;
}
try {
// 先用一个最小画布绘制测试字形,触发字体和 canvas 初始化
this.currentCanvasWidth = 16;
this.currentCanvasHeight = 16;
this.clearCanvas();
this.ctx.setFillStyle(this.color);
this.ctx.setFontSize(this.fontSize);
this.ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
this.ctx.setTextBaseline('middle');
this.ctx.fillText('测', 0, 8);
await new Promise((resolve) => {
this.ctx.draw(false, () => {
// 读取一次数据,确保 canvasGetImageData 就绪
setTimeout(() => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: 16,
height: 16,
success: () => {
this.canvasWarmed = true;
resolve();
},
fail: () => {
// 即便失败也认为已尝试过,避免反复预热阻塞流程
this.canvasWarmed = true;
resolve();
}
});
}, 100);
});
});
// 额外等待,确保字体完全加载
await new Promise(resolve => setTimeout(resolve, 200));
} catch (ex) {
console.log("画布预热异常:", ex);
this.canvasWarmed = true;
}
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
// 首次调用先做预热,避免第一次上报缺字
await this.warmupCanvas();
let binaryToHex = (binaryArray) => {
if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
throw new Error("输入必须是包含8个元素的二进制数组");
}
// 检查每个元素是否为0或1
if (!binaryArray.every(bit => bit === 0 || bit === 1)) {
throw new Error("数组元素必须只能是0或1");
}
// 将二进制数组转换为十进制数
let decimalValue = 0;
for (let i = 0; i < 8; i++) {
// 计算每个位的权重并累加
decimalValue += binaryArray[i] * Math.pow(2, 7 - i);
}
// 将十进制转换为十六进制字符串并添加0x前缀
const hexString = "0x" + decimalValue.toString(16).padStart(2, '0').toUpperCase();
return hexString;
}
let convertCharToMatrix = (imageData, item) => {
const charWidth = 13;
const charHeight = 13;
const pixels = [];
for (let i = 0; i < imageData.length; i += 4) {
const R = imageData[i];
pixels.push(R < 128 ? 1 : 0);
}
const lowBytes = new Array(charWidth).fill(0);
const highBytes = new Array(charWidth).fill(0);
for (let col = 0; col < charWidth; col++) {
for (let row = 0; row < charHeight; row++) {
const pixel = pixels[row * charWidth + col];
if (pixel === 1) {
if (row < 8) {
lowBytes[col] |= (1 << row);
} else {
highBytes[col] |= (1 << (row - 8));
}
}
}
}
return [...lowBytes, ...highBytes];
}
let drawTxt = async (textLine) => {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = 13;
this.currentCanvasHeight = 13;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
// ctx.setTextAlign('center')
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2 + 1;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
setTimeout(() => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
result = {
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
}, 100);
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
// console.log("item=", item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData, item));
}
// console.log("hexs=", linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
visibility: hidden;
}
</style>

View File

@ -0,0 +1,236 @@
<template>
<view>
<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "textToDotMatrix",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * this.fontSize;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
let binaryToHex = (binaryArray) => {
if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
throw new Error("输入必须是包含8个元素的二进制数组");
}
// 检查每个元素是否为0或1
if (!binaryArray.every(bit => bit === 0 || bit === 1)) {
throw new Error("数组元素必须只能是0或1");
}
// 将二进制数组转换为十进制数
let decimalValue = 0;
for (let i = 0; i < 8; i++) {
// 计算每个位的权重并累加
decimalValue += binaryArray[i] * Math.pow(2, 7 - i);
}
// 将十进制转换为十六进制字符串并添加0x前缀
const hexString = "0x" + decimalValue.toString(16).padStart(2, '0').toUpperCase();
return hexString;
}
let convertCharToMatrix = (imageData, item) => {
// console.log("imgOldData=", imageData)
let matrix = [];
let arr = [];
for (let y = 0; y < this.fontSize; y++) {
for (let x = 0; x < 16; x++) {
// 计算像素在imageData中的索引 (RGBA格式)
let index = (y * 16 + x) * 4;
let R = imageData[index];
let G = imageData[index+1];
let B = imageData[index]+2;
// 黑色像素R值较低视为1白色视为0
let isBlack = R < 128 ? 1 : 0;
arr.push(isBlack);
}
}
let firstHalf = arr.slice(0, arr.length / 2); // [1, 2, ..., 128]
let secondHalf = arr.slice(arr.length / 2); // [129, 130, ..., 256]
for (let i = 0; i < this.fontSize; i++) {
let tmp = [];
for (let index = i; index < firstHalf.length; index += this.fontSize) {
tmp.push(firstHalf[index]);
}
tmp = tmp.reverse();
// console.log("tmp=",tmp.join(""));
matrix.push(binaryToHex(tmp));
}
for (let i = 0; i < this.fontSize; i++) {
let tmp = [];
for (let index = i; index < secondHalf.length; index += this.fontSize) {
tmp.push(secondHalf[index]);
}
tmp = tmp.reverse();
matrix.push(binaryToHex(tmp));
}
// console.log("matrix=", matrix);
return matrix;
}
let drawTxt = async (textLine) => {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = this.calcLineWidth(textLine);
this.currentCanvasHeight = 16;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
// ctx.setTextAlign('center')
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
console.log("获取到像素数据,",res.data.length/4)
result = {
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
// console.log("item=", item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData, item));
}
// console.log("hexs=", linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
visibility: hidden;
}
</style>

View File

@ -81,7 +81,8 @@
}
},
created() {
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
},
methods: {
handleBack() {

View File

@ -100,6 +100,7 @@
if (options.dotColors) {
this.colorIndex = 0
}
this.visible = true;
},
// 阻止触摸移动事件

View File

@ -2,21 +2,21 @@
const config = {
// 开发环境
development: {
BASE_URL: 'http://192.168.110.54:8000',
BASE_URL: 'http://192.168.2.34:8000',//http://139.224.253.23:8000
API_PREFIX: '',
// MQTT 配置
MQTT_HOST: '47.120.79.150',
MQTT_PORT: 8083,
MQTT_PORT: 9083,
MQTT_USERNAME: 'admin',
MQTT_PASSWORD: '#YtvpSfCNG'
MQTT_PASSWORD: '#YtvpSfCNG'
},
// 生产环境
production: {
BASE_URL: 'http://47.120.79.150/backend', // https://fuyuanshen.com/backend
BASE_URL: 'https://www.cnxhyc.com/jq',
API_PREFIX: '',
// MQTT 配置
MQTT_HOST: '47.120.79.150',
MQTT_PORT: 8083,
MQTT_HOST: 'www.cnxhyc.com',
MQTT_PORT: 9084,
MQTT_USERNAME: 'admin',
MQTT_PASSWORD: '#YtvpSfCNG'
}

10
main.js
View File

@ -2,17 +2,17 @@ import App from './App'
//// 引入 uView UI
import uView from 'vk-uview-ui';
import bleTool from '@/store/BLETools.js';
// #ifndef VUE3
import Vue from 'vue'
import store from './store/store';
import './uni.promisify.adaptor'
Vue.config.productionTip = false
Vue.prototype.$bleTool = bleTool;
App.mpType = 'app'
const app = new Vue({
store,
...App
})
Vue.use(uView)
@ -25,7 +25,7 @@ import {
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.config.globalProperties.$bleTool = bleTool;
// 使用 uView UI
app.use(uView)
return {

View File

@ -1,12 +1,15 @@
{
"name" : "JingQuan",
"name" : "星汉物联",
"appid" : "__UNI__A21EF43",
"description" : "设备管控",
"versionName" : "1.0.0",
"versionName" : "1.0.15",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"compatible" : {
"ignoreVersion" : true
},
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
@ -18,12 +21,13 @@
},
/* */
"modules" : {
"Bluetooth" : {},
"Barcode" : {},
"Bluetooth" : {},
"Camera" : {},
"Geolocation" : {},
"Maps" : {},
"OAuth" : {},
"Geolocation" : {}
"Record" : {},
"VideoPlayer" : {}
},
/* */
"distribute" : {
@ -54,20 +58,27 @@
"<uses-permission android:name=\"android.permission.a\"/>",
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\"/>"
],
"minSdkVersion" : 21,
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
"minSdkVersion" : 21
"schemes" : "",
"targetSdkVersion" : 30
},
/* ios */
"ios" : {
"appid" : "uni.app.UNIA21EF43",
"dSYMs" : false,
"privacyDescription" : {
"NSBluetoothPeripheralUsageDescription" : "需要蓝牙访问权限,用于设备通信",
"NSBluetoothAlwaysUsageDescription" : "需要蓝牙访问权限,用于设备通信",
"NSLocationWhenInUseUsageDescription" : "App需要您的同意,才能在使用期间访问位置",
"NSLocationAlwaysUsageDescription" : "App需要您的同意,才能始终访问位置",
"NSLocationAlwaysAndWhenInUseUsageDescription" : "App需要您的同意,才能始终访问位置"
"NSLocationWhenInUseUsageDescription" : "App需要您的同意,访问位置,用于判定装备位置是否异常",
"NSLocationAlwaysUsageDescription" : "App需要您的同意,访问位置,用于判定装备位置是否异常",
"NSLocationAlwaysAndWhenInUseUsageDescription" : "App需要您的同意,访问位置,用于判定装备位置是否异常",
"NSBluetoothPeripheralUsageDescription" : "App需要您的同意访问蓝牙访问权限,用于设备通信与反向控制",
"NSBluetoothAlwaysUsageDescription" : "App需要您的同意访问蓝牙访问权限,用于设备通信与反向控制",
"NSPhotoLibraryUsageDescription" : "App需要您的同意访问相册,用于上传头像,设备开机画面",
"NSPhotoLibraryAddUsageDescription" : "App需要您的同意访问相册,用于上传头像,设备开机画面",
"NSCameraUsageDescription" : "App需要您的同意访问相机,用于上传头像,设备开机画面",
"NSMicrophoneUsageDescription" : "App需要您的同意访问麦克风,用于上传语音包"
},
"dSYMs" : false
"idfa" : false,
"urltypes" : ""
},
/* SDK */
"sdkConfigs" : {
@ -84,20 +95,12 @@
"name" : "amapHG8nIFW5",
"appkey_ios" : "065c43f02c7b627a74ad7dd23b16bb4f",
"appkey_android" : "d7d852dbda2b95f6f796fb9a711a9fee"
},
"customStyle": true
}
},
"oauth" : {},
"push" : {}
},
"splashscreen" : {
"useOriginalMsgbox" : true,
"androidStyle" : "common",
"iosStyle" : "common",
"android" : {
"hdpi" : "static/images/biao.png",
"xhdpi" : "static/images/biao.png",
"xxhdpi" : "static/images/biao.png"
"push" : {
"unipush" : {
"offline" : false
}
}
},
"icons" : {
@ -131,6 +134,10 @@
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"useOriginalMsgbox" : true,
"androidStyle" : "common"
}
}
},
@ -138,7 +145,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"appid" : "wxe16dcf57e925a6b5",
"setting" : {
"urlCheck" : false
},
@ -157,5 +164,8 @@
"enable" : false
},
"vueVersion" : "2",
"locale" : "auto"
"locale" : "zh-Hans",
"fallbackLocale" : "zh-Hans"
}
/* 5+App */

306
node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,306 @@
{
"name": "APP",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/blueimp-md5": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
"license": "MIT"
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/paho-mqtt": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/paho-mqtt/-/paho-mqtt-1.1.0.tgz",
"integrity": "sha512-KPbL9KAB0ASvhSDbOrZBaccXS+/s7/LIofbPyERww8hM5Ko71GUJQ6Nmg0BWqj8phAIT8zdf/Sd/RftHU9i2HA==",
"license": "EPL-1.0"
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/vk-uview-ui": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/vk-uview-ui/-/vk-uview-ui-1.5.2.tgz",
"integrity": "sha512-RRZgiEAc8qaUerSi7lSbrkCoLBgRUwFQHwP1V44pJO7Js+7HeHFEkkpPrtkOi14hl4CntR4qIhIDvaKmIJqVsw==",
"engines": {
"HBuilderX": "^3.1.0"
}
}
}
}

163
node_modules/axios/CHANGELOG.md generated vendored
View File

@ -1,5 +1,167 @@
# Changelog
## [1.13.2](https://github.com/axios/axios/compare/v1.13.1...v1.13.2) (2025-11-04)
### Bug Fixes
* **http:** fix 'socket hang up' bug for keep-alive requests when using timeouts; ([#7206](https://github.com/axios/axios/issues/7206)) ([8d37233](https://github.com/axios/axios/commit/8d372335f5c50ecd01e8615f2468a9eb19703117))
* **http:** use default export for http2 module to support stubs; ([#7196](https://github.com/axios/axios/issues/7196)) ([0588880](https://github.com/axios/axios/commit/0588880ac7ddba7594ef179930493884b7e90bf5))
### Performance Improvements
* **http:** fix early loop exit; ([#7202](https://github.com/axios/axios/issues/7202)) ([12c314b](https://github.com/axios/axios/commit/12c314b603e7852a157e93e47edb626a471ba6c5))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+28/-9 (#7206 #7202 )")
- <img src="https://avatars.githubusercontent.com/u/1174718?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Kasper Isager Dalsgarð](https://github.com/kasperisager "+9/-9 (#7196 )")
## [1.13.1](https://github.com/axios/axios/compare/v1.13.0...v1.13.1) (2025-10-28)
### Bug Fixes
* **http:** fixed a regression that caused the data stream to be interrupted for responses with non-OK HTTP statuses; ([#7193](https://github.com/axios/axios/issues/7193)) ([bcd5581](https://github.com/axios/axios/commit/bcd5581d208cd372055afdcb2fd10b68ca40613c))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/128113546?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Anchal Singh](https://github.com/imanchalsingh "+220/-111 (#7173 )")
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+18/-1 (#7193 )")
# [1.13.0](https://github.com/axios/axios/compare/v1.12.2...v1.13.0) (2025-10-27)
### Bug Fixes
* **fetch:** prevent TypeError when config.env is undefined ([#7155](https://github.com/axios/axios/issues/7155)) ([015faec](https://github.com/axios/axios/commit/015faeca9f26db76f9562760f04bb9f8229f4db1))
* resolve issue [#7131](https://github.com/axios/axios/issues/7131) (added spacing in mergeConfig.js) ([#7133](https://github.com/axios/axios/issues/7133)) ([9b9ec98](https://github.com/axios/axios/commit/9b9ec98548d93e9f2204deea10a5f1528bf3ce62))
### Features
* **http:** add HTTP2 support; ([#7150](https://github.com/axios/axios/issues/7150)) ([d676df7](https://github.com/axios/axios/commit/d676df772244726533ca320f42e967f5af056bac))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+794/-180 (#7186 #7150 #7039 )")
- <img src="https://avatars.githubusercontent.com/u/189505037?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Noritaka Kobayashi](https://github.com/noritaka1166 "+24/-509 (#7032 )")
- <img src="https://avatars.githubusercontent.com/u/195581631?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Aviraj2929](https://github.com/Aviraj2929 "+211/-93 (#7136 #7135 #7134 #7112 )")
- <img src="https://avatars.githubusercontent.com/u/181717941?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [prasoon patel](https://github.com/Prasoon52 "+167/-6 (#7099 )")
- <img src="https://avatars.githubusercontent.com/u/141911040?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Samyak Dandge](https://github.com/Samy-in "+134/-0 (#7171 )")
- <img src="https://avatars.githubusercontent.com/u/128113546?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Anchal Singh](https://github.com/imanchalsingh "+53/-56 (#7170 )")
- <img src="https://avatars.githubusercontent.com/u/146073621?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Rahul Kumar](https://github.com/jaiyankargupta "+28/-28 (#7073 )")
- <img src="https://avatars.githubusercontent.com/u/148716794?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Amit Verma](https://github.com/Amitverma0509 "+24/-13 (#7129 )")
- <img src="https://avatars.githubusercontent.com/u/141427581?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Abhishek3880](https://github.com/abhishekmaniy "+23/-4 (#7119 #7117 #7116 #7115 )")
- <img src="https://avatars.githubusercontent.com/u/91522146?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dhvani Maktuporia](https://github.com/Dhvani365 "+14/-5 (#7175 )")
- <img src="https://avatars.githubusercontent.com/u/41838423?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Usama Ayoub](https://github.com/sam3690 "+4/-4 (#7133 )")
- <img src="https://avatars.githubusercontent.com/u/79366821?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [ikuy1203](https://github.com/ikuy1203 "+3/-3 (#7166 )")
- <img src="https://avatars.githubusercontent.com/u/74639234?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Nikhil Simon Toppo](https://github.com/Kirito-Excalibur "+1/-1 (#7172 )")
- <img src="https://avatars.githubusercontent.com/u/200562195?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Jane Wangari](https://github.com/Wangarijane "+1/-1 (#7155 )")
- <img src="https://avatars.githubusercontent.com/u/78318848?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Supakorn Ieamgomol](https://github.com/Supakornn "+1/-1 (#7065 )")
- <img src="https://avatars.githubusercontent.com/u/134518?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Kian-Meng Ang](https://github.com/kianmeng "+1/-1 (#7046 )")
- <img src="https://avatars.githubusercontent.com/u/13148112?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [UTSUMI Keiji](https://github.com/k-utsumi "+1/-1 (#7037 )")
## [1.12.2](https://github.com/axios/axios/compare/v1.12.1...v1.12.2) (2025-09-14)
### Bug Fixes
* **fetch:** use current global fetch instead of cached one when env fetch is not specified to keep MSW support; ([#7030](https://github.com/axios/axios/issues/7030)) ([cf78825](https://github.com/axios/axios/commit/cf78825e1229b60d1629ad0bbc8a752ff43c3f53))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+247/-16 (#7030 #7022 #7024 )")
- <img src="https://avatars.githubusercontent.com/u/189505037?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Noritaka Kobayashi](https://github.com/noritaka1166 "+2/-6 (#7028 #7029 )")
## [1.12.1](https://github.com/axios/axios/compare/v1.12.0...v1.12.1) (2025-09-12)
### Bug Fixes
* **types:** fixed env config types; ([#7020](https://github.com/axios/axios/issues/7020)) ([b5f26b7](https://github.com/axios/axios/commit/b5f26b75bdd9afa95016fb67d0cab15fc74cbf05))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+10/-4 (#7020 )")
# [1.12.0](https://github.com/axios/axios/compare/v1.11.0...v1.12.0) (2025-09-11)
### Bug Fixes
* adding build artifacts ([9ec86de](https://github.com/axios/axios/commit/9ec86de257bfa33856571036279169f385ed92bd))
* dont add dist on release ([a2edc36](https://github.com/axios/axios/commit/a2edc3606a4f775d868a67bb3461ff18ce7ecd11))
* **fetch-adapter:** set correct Content-Type for Node FormData ([#6998](https://github.com/axios/axios/issues/6998)) ([a9f47af](https://github.com/axios/axios/commit/a9f47afbf3224d2ca987dbd8188789c7ea853c5d))
* **node:** enforce maxContentLength for data: URLs ([#7011](https://github.com/axios/axios/issues/7011)) ([945435f](https://github.com/axios/axios/commit/945435fc51467303768202250debb8d4ae892593))
* package exports ([#5627](https://github.com/axios/axios/issues/5627)) ([aa78ac2](https://github.com/axios/axios/commit/aa78ac23fc9036163308c0f6bd2bb885e7af3f36))
* **params:** removing '[' and ']' from URL encode exclude characters ([#3316](https://github.com/axios/axios/issues/3316)) ([#5715](https://github.com/axios/axios/issues/5715)) ([6d84189](https://github.com/axios/axios/commit/6d84189349c43b1dcdd977b522610660cc4c7042))
* release pr run ([fd7f404](https://github.com/axios/axios/commit/fd7f404488b2c4f238c2fbe635b58026a634bfd2))
* **types:** change the type guard on isCancel ([#5595](https://github.com/axios/axios/issues/5595)) ([0dbb7fd](https://github.com/axios/axios/commit/0dbb7fd4f61dc568498cd13a681fa7f907d6ec7e))
### Features
* **adapter:** surface lowlevel network error details; attach original error via cause ([#6982](https://github.com/axios/axios/issues/6982)) ([78b290c](https://github.com/axios/axios/commit/78b290c57c978ed2ab420b90d97350231c9e5d74))
* **fetch:** add fetch, Request, Response env config variables for the adapter; ([#7003](https://github.com/axios/axios/issues/7003)) ([c959ff2](https://github.com/axios/axios/commit/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b))
* support reviver on JSON.parse ([#5926](https://github.com/axios/axios/issues/5926)) ([2a97634](https://github.com/axios/axios/commit/2a9763426e43d996fd60d01afe63fa6e1f5b4fca)), closes [#5924](https://github.com/axios/axios/issues/5924)
* **types:** extend AxiosResponse interface to include custom headers type ([#6782](https://github.com/axios/axios/issues/6782)) ([7960d34](https://github.com/axios/axios/commit/7960d34eded2de66ffd30b4687f8da0e46c4903e))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/22686401?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Willian Agostini](https://github.com/WillianAgostini "+132/-16760 (#7002 #5926 #6782 )")
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+4263/-293 (#7006 #7003 )")
- <img src="https://avatars.githubusercontent.com/u/53833811?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [khani](https://github.com/mkhani01 "+111/-15 (#6982 )")
- <img src="https://avatars.githubusercontent.com/u/7712804?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Ameer Assadi](https://github.com/AmeerAssadi "+123/-0 (#7011 )")
- <img src="https://avatars.githubusercontent.com/u/70265727?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Emiedonmokumo Dick-Boro](https://github.com/emiedonmokumo "+55/-35 (#6998 )")
- <img src="https://avatars.githubusercontent.com/u/47859767?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Zeroday BYTE](https://github.com/opsysdebug "+8/-8 (#6980 )")
- <img src="https://avatars.githubusercontent.com/u/4814473?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Jason Saayman](https://github.com/jasonsaayman "+7/-7 (#6985 #6985 )")
- <img src="https://avatars.githubusercontent.com/u/13010755?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [최예찬](https://github.com/HealGaren "+5/-7 (#5715 )")
- <img src="https://avatars.githubusercontent.com/u/7002604?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Gligor Kotushevski](https://github.com/gligorkot "+3/-1 (#5627 )")
- <img src="https://avatars.githubusercontent.com/u/15893?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Aleksandar Dimitrov](https://github.com/adimit "+2/-1 (#5595 )")
# [1.11.0](https://github.com/axios/axios/compare/v1.10.0...v1.11.0) (2025-07-22)
### Bug Fixes
* form-data npm pakcage ([#6970](https://github.com/axios/axios/issues/6970)) ([e72c193](https://github.com/axios/axios/commit/e72c193722530db538b19e5ddaaa4544d226b253))
* prevent RangeError when using large Buffers ([#6961](https://github.com/axios/axios/issues/6961)) ([a2214ca](https://github.com/axios/axios/commit/a2214ca1bc60540baf2c80573cea3a0ff91ba9d1))
* **types:** resolve type discrepancies between ESM and CJS TypeScript declaration files ([#6956](https://github.com/axios/axios/issues/6956)) ([8517aa1](https://github.com/axios/axios/commit/8517aa16f8d082fc1d5309c642220fa736159110))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12534341?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [izzy goldman](https://github.com/izzygld "+186/-93 (#6970 )")
- <img src="https://avatars.githubusercontent.com/u/142807367?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Manish Sahani](https://github.com/manishsahanidev "+70/-0 (#6961 )")
- <img src="https://avatars.githubusercontent.com/u/189505037?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Noritaka Kobayashi](https://github.com/noritaka1166 "+12/-10 (#6938 #6939 )")
- <img src="https://avatars.githubusercontent.com/u/392612?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [James Nail](https://github.com/jrnail23 "+13/-2 (#6956 )")
- <img src="https://avatars.githubusercontent.com/u/163745239?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Tejaswi1305](https://github.com/Tejaswi1305 "+1/-1 (#6894 )")
# [1.10.0](https://github.com/axios/axios/compare/v1.9.0...v1.10.0) (2025-06-14)
### Bug Fixes
* **adapter:** pass fetchOptions to fetch function ([#6883](https://github.com/axios/axios/issues/6883)) ([0f50af8](https://github.com/axios/axios/commit/0f50af8e076b7fb403844789bd5e812dedcaf4ed))
* **form-data:** convert boolean values to strings in FormData serialization ([#6917](https://github.com/axios/axios/issues/6917)) ([5064b10](https://github.com/axios/axios/commit/5064b108de336ff34862650709761b8a96d26be0))
* **package:** add module entry point for React Native; ([#6933](https://github.com/axios/axios/issues/6933)) ([3d343b8](https://github.com/axios/axios/commit/3d343b86dc4fd0eea0987059c5af04327c7ae304))
### Features
* **types:** improved fetchOptions interface ([#6867](https://github.com/axios/axios/issues/6867)) ([63f1fce](https://github.com/axios/axios/commit/63f1fce233009f5db1abf2586c145825ac98c3d7))
### Contributors to this release
- <img src="https://avatars.githubusercontent.com/u/12586868?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+30/-19 (#6933 #6920 #6893 #6892 )")
- <img src="https://avatars.githubusercontent.com/u/189505037?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Noritaka Kobayashi](https://github.com/noritaka1166 "+2/-6 (#6922 #6923 )")
- <img src="https://avatars.githubusercontent.com/u/48370490?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Dimitrios Lazanas](https://github.com/dimitry-lzs "+4/-0 (#6917 )")
- <img src="https://avatars.githubusercontent.com/u/71047946?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Adrian Knapp](https://github.com/AdrianKnapp "+2/-2 (#6867 )")
- <img src="https://avatars.githubusercontent.com/u/16129206?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Howie Zhao](https://github.com/howiezhao "+3/-1 (#6872 )")
- <img src="https://avatars.githubusercontent.com/u/6788611?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Uhyeon Park](https://github.com/warpdev "+1/-1 (#6883 )")
- <img src="https://avatars.githubusercontent.com/u/20028934?v&#x3D;4&amp;s&#x3D;18" alt="avatar" width="18"/> [Sampo Silvennoinen](https://github.com/stscoundrel "+1/-1 (#6913 )")
# [1.9.0](https://github.com/axios/axios/compare/v1.8.4...v1.9.0) (2025-04-24)
@ -1193,4 +1355,5 @@ This functionality is considered as a fix.
- [Marco Weber](https://github.com/mrcwbr)
- [Luca Pizzini](https://github.com/lpizzinidev)
- [Willian Agostini](https://github.com/WillianAgostini)
- [Huyen Nguyen](https://github.com/huyenltnguyen)

243
node_modules/axios/README.md generated vendored
View File

@ -1,22 +1,19 @@
<h3 align="center"> 🥇 Gold sponsors <br> </h3> <table align="center" width="100%"><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://stytch.com/?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;website-link&amp;utm_campaign&#x3D;axios-http" style="padding: 10px; display: inline-block"> <picture> <source width="200px" height="38px" media="(prefers-color-scheme: dark)" srcset="https://axios-http.com/assets/sponsors/stytch_white.png"> <img width="200px" height="38px" src="https://axios-http.com/assets/sponsors/stytch.png" alt="Stytch"/> </picture> </a> <p align="center" title="API-first authentication, authorization, and fraud prevention">API-first authentication, authorization, and fraud prevention</p> <p align="center"> <a href="https://stytch.com/?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;website-link&amp;utm_campaign&#x3D;axios-http"><b>Website</b></a> | <a href="https://stytch.com/docs?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;docs-link&amp;utm_campaign&#x3D;axios-http"><b>Documentation</b></a> | <a href="https://github.com/stytchauth/stytch-node?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;node-sdk&amp;utm_campaign&#x3D;axios-http"><b>Node.js</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://www.principal.com/about-us?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="133px" height="43px" src="https://axios-http.com/assets/sponsors/principal.svg" alt="Principal Financial Group"/> </a> <p align="center" title="Were bound by one common purpose: to give you the financial tools, resources and information you need to live your best life.">Were bound by one common purpose: to give you the financial tools, resources and information you ne...</p> <p align="center"> <a href="https://www.principal.com/about-us?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>www.principal.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://twicsy.com/buy-instagram-followers?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="85px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/buy-instagram-followers-twicsy.png" alt="Buy Instagram Followers Twicsy"/> </a> <p align="center" title="Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site to buy followers from the likes of US Magazine.">Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site...</p> <p align="center"> <a href="https://twicsy.com/buy-instagram-followers?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>twicsy.com</b></a> </p>
</td></tr><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://www.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship" style="padding: 10px; display: inline-block"> <picture> <source width="200px" height="52px" media="(prefers-color-scheme: dark)" srcset="https://axios-http.com/assets/sponsors/descope_white.png"> <img width="200px" height="52px" src="https://axios-http.com/assets/sponsors/descope.png" alt="Descope"/> </picture> </a> <p align="center" title="Hi, we&#x27;re Descope! We are building something in the authentication space for app developers and cant wait to place it in your hands.">Hi, we&#x27;re Descope! We are building something in the authentication space for app developers and...</p> <p align="center"> <a href="https://www.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship"><b>Website</b></a> | <a href="https://docs.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship"><b>Docs</b></a> | <a href="https://www.descope.com/community?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship"><b>Community</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://buzzoid.com/buy-instagram-followers/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="62px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/buzzoid-buy-instagram-followers.png" alt="Buzzoid - Buy Instagram Followers"/> </a> <p align="center" title="At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rated world&#x27;s #1 IG service since 2012.">At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rate...</p> <p align="center"> <a href="https://buzzoid.com/buy-instagram-followers/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>buzzoid.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://www.famety.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="70px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/famety-buy-instagram-followers.png" alt="Famety - Buy Instagram Followers"/> </a> <p align="center" title="At Famety, you can grow your social media following quickly, safely, and easily with just a few clicks. Rated the worlds #1 social media service since 2013.">At Famety, you can grow your social media following quickly, safely, and easily with just a few clic...</p> <p align="center"> <a href="https://www.famety.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>www.famety.com</b></a> </p>
</td></tr><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://poprey.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="70px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/instagram-likes.png" alt="Poprey - Buy Instagram Likes"/> </a> <p align="center" title="Buy Instagram Likes">Buy Instagram Likes</p> <p align="center"> <a href="https://poprey.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>poprey.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://betking.com.ua/sports-book/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="70px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/bukmeker.jpeg" alt="Букмекер"/> </a> <p align="center" title="Ставки на спорт, БК в Україні">Ставки на спорт, БК в Україні</p> <p align="center"> <a href="https://betking.com.ua/sports-book/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>betking.com.ua</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://ssmarket.net/buy-youtube-subscribers?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block"> <img width="70px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/youtube-subscribers-ssmarket.png" alt="Buy Youtube Subscribers"/> </a> <p align="center" title="SS Market offers professional social media services that rapidly increase your YouTube subscriber count, elevating your channel to a powerful position.">SS Market offers professional social media services that rapidly increase your YouTube subscriber co...</p> <p align="center"> <a href="https://ssmarket.net/buy-youtube-subscribers?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship"><b>ssmarket.net</b></a> </p>
</td></tr><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://opencollective.com/axios/contribute">💜 Become a sponsor</a>
</td><td align="center" width="33.333333333333336%"> <a href="https://opencollective.com/axios/contribute">💜 Become a sponsor</a>
</td><td align="center" width="33.333333333333336%"> <a href="https://opencollective.com/axios/contribute">💜 Become a sponsor</a>
<h3 align="center"> 🥇 Gold sponsors <br> </h3> <table align="center" width="100%"><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://stytch.com/?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;website-link&amp;utm_campaign&#x3D;axios-http" style="padding: 10px; display: inline-block" target="_blank"> <picture> <source width="200px" height="38px" media="(prefers-color-scheme: dark)" srcset="https://axios-http.com/assets/sponsors/stytch_white.png"> <img width="200px" height="38px" src="https://axios-http.com/assets/sponsors/stytch.png" alt="Stytch"/> </picture> </a> <p align="center" title="API-first authentication, authorization, and fraud prevention">API-first authentication, authorization, and fraud prevention</p> <p align="center"> <a href="https://stytch.com/?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;website-link&amp;utm_campaign&#x3D;axios-http" target="_blank"><b>Website</b></a> | <a href="https://stytch.com/docs?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;docs-link&amp;utm_campaign&#x3D;axios-http" target="_blank"><b>Documentation</b></a> | <a href="https://github.com/stytchauth/stytch-node?utm_source&#x3D;oss-sponsorship&amp;utm_medium&#x3D;paid_sponsorship&amp;utm_content&#x3D;node-sdk&amp;utm_campaign&#x3D;axios-http" target="_blank"><b>Node.js</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://www.principal.com/about-us?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="133px" height="43px" src="https://axios-http.com/assets/sponsors/principal.svg" alt="Principal Financial Group"/> </a> <p align="center" title="Were bound by one common purpose: to give you the financial tools, resources and information you need to live your best life.">Were bound by one common purpose: to give you the financial tools, resources and information you ne...</p> <p align="center"> <a href="https://www.principal.com/about-us?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>www.principal.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://twicsy.com/buy-instagram-followers?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="85px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/dfa9670ad5e66eea17315332453c7f4e3a3b5905.png" alt="Buy Instagram Followers Twicsy"/> </a> <p align="center" title="Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site to buy followers from the likes of US Magazine.">Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site...</p> <p align="center"> <a href="https://twicsy.com/buy-instagram-followers?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>twicsy.com</b></a> </p>
</td></tr><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://www.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <picture> <source width="200px" height="52px" media="(prefers-color-scheme: dark)" srcset="https://axios-http.com/assets/sponsors/descope_white.png"> <img width="200px" height="52px" src="https://axios-http.com/assets/sponsors/descope.png" alt="Descope"/> </picture> </a> <p align="center" title="Hi, we&#x27;re Descope! We are building something in the authentication space for app developers and cant wait to place it in your hands.">Hi, we&#x27;re Descope! We are building something in the authentication space for app developers and...</p> <p align="center"> <a href="https://www.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship" target="_blank"><b>Website</b></a> | <a href="https://docs.descope.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship" target="_blank"><b>Docs</b></a> | <a href="https://www.descope.com/community?utm_source&#x3D;axios&amp;utm_medium&#x3D;referral&amp;utm_campaign&#x3D;axios-oss-sponsorship" target="_blank"><b>Community</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://route4me.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <picture> <source width="200px" height="51px" media="(prefers-color-scheme: dark)" srcset="https://axios-http.com/assets/sponsors/route4me_white.png"> <img width="200px" height="51px" src="https://axios-http.com/assets/sponsors/route4me.png" alt="Route4Me"/> </picture> </a> <p align="center" title="Best Route Planning And Route Optimization Software">Best Route Planning And Route Optimization Software</p> <p align="center"> <a href="https://route4me.com/platform/route-optimization-software?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>Explore</b></a> | <a href="https://route4me.com/platform/marketplace/pricing?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>Free Trial</b></a> | <a href="https://route4me.com/contact?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>Contact</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://buzzoid.com/buy-instagram-followers/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="62px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/e1625cb54e10ee40180c99d1495a462e9d6664a4.png" alt="Buzzoid - Buy Instagram Followers"/> </a> <p align="center" title="At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rated world&#x27;s #1 IG service since 2012.">At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rate...</p> <p align="center"> <a href="https://buzzoid.com/buy-instagram-followers/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>buzzoid.com</b></a> </p>
</td></tr><tr width="33.333333333333336%"><td align="center" width="33.333333333333336%"> <a href="https://poprey.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="70px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/e699ec99f7df3a203ddbc49d3c7712a907e628ea.png" alt="Poprey - Buy Instagram Likes"/> </a> <p align="center" title="Buy Instagram Likes">Buy Instagram Likes</p> <p align="center"> <a href="https://poprey.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>poprey.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://requestly.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;sponsorlist&amp;utm_campaign&#x3D;sponsorship" style="padding: 10px; display: inline-block" target="_blank"> <img width="71px" height="70px" src="https://axios-http.com/assets/sponsors/opencollective/16450b4dc0deb9dab5a511bf2bc8b8b4ac33412f.png" alt="Requestly"/> </a> <p align="center" title="A lightweight open-source API Development, Testing &amp; Mocking platform">A lightweight open-source API Development, Testing &amp; Mocking platform</p> <p align="center"> <a href="https://requestly.com/?utm_source&#x3D;axios&amp;utm_medium&#x3D;readme_sponsorlist&amp;utm_campaign&#x3D;sponsorship" target="_blank"><b>requestly.com</b></a> </p>
</td><td align="center" width="33.333333333333336%"> <a href="https://opencollective.com/axios/contribute" target="_blank" >💜 Become a sponsor</a>
</td></tr></table>
<!--<div>marker</div>-->
<br><br>
<div align="center">
<a href="https://axios-http.com"><img src="https://axios-http.com/assets/logo.svg" /></a><br>
<a href="https://axios-http.com"><img src="https://axios-http.com/assets/logo.svg" alt="Axios" /></a><br>
</div>
<p align="center">Promise based HTTP client for the browser and node.js</p>
@ -39,6 +36,7 @@
[![gitter chat](https://img.shields.io/gitter/room/mzabriskie/axios.svg?style=flat-square)](https://gitter.im/mzabriskie/axios)
[![code helpers](https://www.codetriage.com/axios/axios/badges/users.svg)](https://www.codetriage.com/axios/axios)
[![Known Vulnerabilities](https://snyk.io/test/npm/axios/badge.svg)](https://snyk.io/test/npm/axios)
[![Contributors](https://img.shields.io/github/contributors/axios/axios.svg?style=flat-square)](CONTRIBUTORS.md)
@ -80,9 +78,13 @@
- [Files Posting](#files-posting)
- [HTML Form Posting](#-html-form-posting-browser)
- [🆕 Progress capturing](#-progress-capturing)
- [🆕 Rate limiting](#-progress-capturing)
- [🆕 Rate limiting](#-rate-limiting)
- [🆕 AxiosHeaders](#-axiosheaders)
- [🔥 Fetch adapter](#-fetch-adapter)
- [🔥 Custom fetch](#-custom-fetch)
- [🔥 Using with Tauri](#-using-with-tauri)
- [🔥 Using with SvelteKit](#-using-with-sveltekit-)
- [🔥 HTTP2](#-http2)
- [Semver](#semver)
- [Promises](#promises)
- [TypeScript](#typescript)
@ -92,21 +94,22 @@
## Features
- Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) from the browser
- Make [http](https://nodejs.org/api/http.html) requests from node.js
- Supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API
- Intercept request and response
- Transform request and response data
- Cancel requests
- Automatic transforms for [JSON](https://www.json.org/json-en.html) data
- 🆕 Automatic data object serialization to `multipart/form-data` and `x-www-form-urlencoded` body encodings
- Client side support for protecting against [XSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
- **Browser Requests:** Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) directly from the browser.
- **Node.js Requests:** Make [http](https://nodejs.org/api/http.html) requests from Node.js environments.
- **Promise-based:** Fully supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API for easier asynchronous code.
- **Interceptors:** Intercept requests and responses to add custom logic or transform data.
- **Data Transformation:** Transform request and response data automatically.
- **Request Cancellation:** Cancel requests using built-in mechanisms.
- **Automatic JSON Handling:** Automatically serializes and parses [JSON](https://www.json.org/json-en.html) data.
- **Form Serialization:** 🆕 Automatically serializes data objects to `multipart/form-data` or `x-www-form-urlencoded` formats.
- **XSRF Protection:** Client-side support to protect against [Cross-Site Request Forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery).
## Browser Support
![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_48x48.png) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari_48x48.png) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera_48x48.png) | ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_48x48.png) |
--- | --- | --- | --- | --- |
Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | 11 ✔ |
| Chrome | Firefox | Safari | Opera | Edge |
|:------:|:-------:|:------:|:-----:|:----:|
| ![Chrome browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_48x48.png) | ![Firefox browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_48x48.png) | ![Safari browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari_48x48.png) | ![Opera browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera_48x48.png) | ![Edge browser logo](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_48x48.png) |
| Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |
[![Browser Matrix](https://saucelabs.com/open_sauce/build_matrix/axios.svg)](https://saucelabs.com/u/axios)
@ -196,7 +199,7 @@ Using unpkg CDN:
## Example
> **Note**: CommonJS usage
> **Note**: CommonJS usage
> In order to gain the TypeScript typings (for intellisense / autocomplete) while using CommonJS imports with `require()`, use the following approach:
```js
@ -418,18 +421,18 @@ These are the available config options for making requests. Only the `url` is re
params: {
ID: 12345
},
// `paramsSerializer` is an optional config that allows you to customize serializing `params`.
// `paramsSerializer` is an optional config that allows you to customize serializing `params`.
paramsSerializer: {
// Custom encoder function which sends key/value pairs in an iterative fashion.
encode?: (param: string): string => { /* Do custom operations here and return transformed string */ },
encode?: (param: string): string => { /* Do custom operations here and return transformed string */ },
// Custom serializer function for the entire parameter. Allows user to mimic pre 1.x behaviour.
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ),
// Configuration for formatting array indexes in the params.
indexes: false // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes).
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ),
// Configuration for formatting array indexes in the params.
indexes: false // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes).
},
// `data` is the data to be sent as the request body
@ -491,7 +494,7 @@ These are the available config options for making requests. Only the `url` is re
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
xsrfHeaderName: 'X-XSRF-TOKEN', // default
// `undefined` (default) - set XSRF header only for the same origin requests
withXSRFToken: boolean | undefined | ((config: InternalAxiosRequestConfig) => boolean | undefined),
@ -541,7 +544,7 @@ These are the available config options for making requests. Only the `url` is re
// Only either `socketPath` or `proxy` can be specified.
// If both are specified, `socketPath` is used.
socketPath: null, // default
// `transport` determines the transport method that will be used to make the request.
// If defined, it will be used. Otherwise, if `maxRedirects` is 0,
// the default `http` or `https` library will be used, depending on the protocol specified in `protocol`.
@ -551,7 +554,9 @@ These are the available config options for making requests. Only the `url` is re
// `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
// and https requests, respectively, in node.js. This allows options to be added like
// `keepAlive` that are not enabled by default.
// `keepAlive` that are not enabled by default before Node.js v19.0.0. After Node.js
// v19.0.0, you no longer need to customize the agent to enable `keepAlive` because
// `http.globalAgent` has `keepAlive` enabled by default.
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
@ -832,26 +837,27 @@ The general structure of axios errors is as follows:
| -------- | ---------- |
| message | A quick summary of the error message and the status it failed with. |
| name | This defines where the error originated from. For axios, it will always be an 'AxiosError'. |
| stack | Provides the stack trace of the error. |
| stack | Provides the stack trace of the error. |
| config | An axios config object with specific instance configurations defined by the user from when the request was made |
| code | Represents an axios identified error. The table below lists out specific definitions for internal axios error. |
| status | HTTP response status code. See [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for common HTTP response status code meanings.
| status | HTTP response status code. See [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for common HTTP response status code meanings.
Below is a list of potential axios identified error:
| Code | Definition |
| -------- | ---------- |
| ERR_BAD_OPTION_VALUE | Invalid or unsupported value provided in axios configuration. |
| ERR_BAD_OPTION | Invalid option provided in axios configuration. |
| ECONNABORTED | Request timed out due to exceeding timeout specified in axios configuration. |
| ETIMEDOUT | Request timed out due to exceeding default axios timelimit. |
| ERR_NETWORK | Network-related issue.
| ERR_FR_TOO_MANY_REDIRECTS | Request is redirected too many times; exceeds max redirects specified in axios configuration.
| ERR_DEPRECATED | Deprecated feature or method used in axios.
| ERR_BAD_RESPONSE | Response cannot be parsed properly or is in an unexpected format.
| ERR_BAD_REQUEST | Requested has unexpected format or missing required parameters. |
| ERR_CANCELED | Feature or method is canceled explicitly by the user.
| ERR_NOT_SUPPORT | Feature or method not supported in the current axios environment.
| ERR_INVALID_URL | Invalid URL provided for axios request.
| Code | Definition |
| --- | --- |
| ERR_BAD_OPTION_VALUE | Invalid value provided in axios configuration. |
| ERR_BAD_OPTION | Invalid option provided in axios configuration. |
| ERR_NOT_SUPPORT | Feature or method not supported in the current axios environment. |
| ERR_DEPRECATED | Deprecated feature or method used in axios. |
| ERR_INVALID_URL | Invalid URL provided for axios request. |
| ECONNABORTED | Typically indicates that the request has been timed out (unless `transitional.clarifyTimeoutError` is set) or aborted by the browser or its plugin. |
| ERR_CANCELED | Feature or method is canceled explicitly by the user using an AbortSignal (or a CancelToken). |
| ETIMEDOUT | Request timed out due to exceeding default axios timelimit. `transitional.clarifyTimeoutError` must be set to `true`, otherwise a generic `ECONNABORTED` error will be thrown instead. |
| ERR_NETWORK | Network-related issue. In the browser, this error can also be caused by a [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) or [Mixed Content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) policy violation. The browser does not allow the JS code to clarify the real reason for the error caused by security issues, so please check the console. |
| ERR_FR_TOO_MANY_REDIRECTS | Request is redirected too many times; exceeds max redirects specified in axios configuration. |
| ERR_BAD_RESPONSE | Response cannot be parsed properly or is in an unexpected format. Usually related to a response with `5xx` status code. |
| ERR_BAD_REQUEST | The request has an unexpected format or is missing required parameters. Usually related to a response with `4xx` status code. |
## Handling Errors
@ -1279,7 +1285,7 @@ Sending `Blobs`/`Files` as JSON (`base64`) is not currently supported.
Axios supports both browser and node environments to capture request upload/download progress.
The frequency of progress events is forced to be limited to `3` times per second.
```js
```js
await axios.post(url, data, {
onUploadProgress: function (axiosProgressEvent) {
/*{
@ -1298,13 +1304,13 @@ await axios.post(url, data, {
loaded: number;
total?: number;
progress?: number;
bytes: number;
bytes: number;
estimated?: number;
rate?: number; // download speed in bytes
download: true; // download sign
}*/
}
});
});
```
You can also track stream upload/download progress in node.js:
@ -1314,7 +1320,7 @@ const {data} = await axios.post(SERVER_URL, readableStream, {
onUploadProgress: ({progress}) => {
console.log((progress * 100).toFixed(2));
},
headers: {
'Content-Length': contentLength
},
@ -1340,7 +1346,7 @@ const {data} = await axios.post(LOCAL_SERVER_URL, myBuffer, {
onUploadProgress: ({progress, rate}) => {
console.log(`Upload [${(progress*100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`)
},
maxRate: [100 * 1024], // 100KB/s limit
});
```
@ -1378,13 +1384,13 @@ The headers object is always initialized inside interceptors and transformers:
"My-set-header1": "my-set-value1",
"My-set-header2": "my-set-value2"
});
request.headers.set('User-Agent', false); // disable subsequent setting the header by Axios
request.headers.setContentType('text/plain');
request.headers['My-set-header2'] = 'newValue' // direct access is deprecated
return request;
}
);
@ -1410,7 +1416,7 @@ for(const [header, value] of headers) {
### new AxiosHeaders(headers?)
Constructs a new `AxiosHeaders` instance.
Constructs a new `AxiosHeaders` instance.
```
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);
@ -1465,7 +1471,7 @@ const headers = new AxiosHeaders({
'Content-Type': 'multipart/form-data; boundary=Asrf456BGe4h'
});
console.log(headers.get('Content-Type'));
console.log(headers.get('Content-Type'));
// multipart/form-data; boundary=Asrf456BGe4h
console.log(headers.get('Content-Type', true)); // parse key-value pairs from a string separated with \s,;= delimiters:
@ -1509,7 +1515,7 @@ Returns `true` if at least one header has been removed.
clear(matcher?: AxiosHeaderMatcher): boolean;
```
Removes all headers.
Removes all headers.
Unlike the `delete` method matcher, this optional matcher will be used to match against the header name rather than the value.
```ts
@ -1564,7 +1570,7 @@ Returns a new `AxiosHeaders` instance.
toJSON(asStrings?: boolean): RawAxiosHeaders;
````
Resolve all internal headers values into a new null prototype object.
Resolve all internal headers values into a new null prototype object.
Set `asStrings` to true to resolve arrays as a string containing all elements, separated by commas.
### AxiosHeaders.from(thing?)
@ -1620,12 +1626,111 @@ const fetchAxios = axios.create({
const {data} = fetchAxios.get(url);
```
The adapter supports the same functionality as `xhr` adapter, **including upload and download progress capturing**.
The adapter supports the same functionality as `xhr` adapter, **including upload and download progress capturing**.
Also, it supports additional response types such as `stream` and `formdata` (if supported by the environment).
### 🔥 Custom fetch
Starting from `v1.12.0`, you can customize the fetch adapter to use a custom fetch API instead of environment globals.
You can pass a custom `fetch` function, `Request`, and `Response` constructors via env config.
This can be helpful in case of custom environments & app frameworks.
Also, when using a custom fetch, you may need to set custom Request and Response too. If you don't set them, global objects will be used.
If your custom fetch api does not have these objects, and the globals are incompatible with a custom fetch,
you must disable their use inside the fetch adapter by passing null.
> Note: Setting `Request` & `Response` to `null` will make it impossible for the fetch adapter to capture the upload & download progress.
Basic example:
```js
import customFetchFunction from 'customFetchModule';
const instance = axios.create({
adapter: 'fetch',
onDownloadProgress(e) {
console.log('downloadProgress', e);
},
env: {
fetch: customFetchFunction,
Request: null, // undefined -> use the global constructor
Response: null
}
});
```
#### 🔥 Using with Tauri
A minimal example of setting up Axios for use in a [Tauri](https://tauri.app/plugin/http-client/) app with a platform fetch function that ignores CORS policy for requests.
```js
import { fetch } from "@tauri-apps/plugin-http";
import axios from "axios";
const instance = axios.create({
adapter: 'fetch',
onDownloadProgress(e) {
console.log('downloadProgress', e);
},
env: {
fetch
}
});
const {data} = await instance.get("https://google.com");
```
#### 🔥 Using with SvelteKit
[SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) framework has a custom implementation of the fetch function for server rendering (so called `load` functions), and also uses relative paths,
which makes it incompatible with the standard URL API. So, Axios must be configured to use the custom fetch API:
```js
export async function load({ fetch }) {
const {data: post} = await axios.get('https://jsonplaceholder.typicode.com/posts/1', {
adapter: 'fetch',
env: {
fetch,
Request: null,
Response: null
}
});
return { post };
}
```
## 🔥 HTTP2
In version `1.13.0`, experimental `HTTP2` support was added to the `http` adapter.
The `httpVersion` option is now available to select the protocol version used.
Additional native options for the internal `session.request()` call can be passed via the `http2Options` config.
This config also includes the custom `sessionTimeout` parameter, which defaults to `1000ms`.
```js
const form = new FormData();
form.append('foo', '123');
const {data, headers, status} = await axios.post('https://httpbin.org/post', form, {
httpVersion: 2,
http2Options: {
// rejectUnauthorized: false,
// sessionTimeout: 1000
},
onUploadProgress(e) {
console.log('upload progress', e);
},
onDownloadProgress(e) {
console.log('download progress', e);
},
responseType: 'arraybuffer'
});
```
## Semver
Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes.
Since Axios has reached a `v.1.0.0` we will fully embrace semver as per the spec [here](https://semver.org/)
## Promises
@ -1676,4 +1781,4 @@ axios is heavily inspired by the [$http service](https://docs.angularjs.org/api/
## License
[MIT](LICENSE)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

852
node_modules/axios/dist/axios.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

757
node_modules/axios/dist/esm/axios.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1119
node_modules/axios/dist/node/axios.cjs generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

38
node_modules/axios/index.d.cts generated vendored
View File

@ -6,7 +6,7 @@ type MethodsHeaders = Partial<{
[Key in axios.Method as Lowercase<Key>]: AxiosHeaders;
} & {common: AxiosHeaders}>;
type AxiosHeaderMatcher = (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean;
type AxiosHeaderMatcher = string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean);
type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any;
@ -16,6 +16,8 @@ type ContentType = axios.AxiosHeaderValue | 'text/html' | 'text/plain' | 'multip
type CommonResponseHeadersList = 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control'| 'Content-Encoding';
type BrowserProgressEvent = any;
declare class AxiosHeaders {
constructor(
headers?: RawAxiosHeaders | AxiosHeaders | string
@ -77,6 +79,8 @@ declare class AxiosHeaders {
getAuthorization(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue;
hasAuthorization(matcher?: AxiosHeaderMatcher): boolean;
getSetCookie(): string[];
[Symbol.iterator](): IterableIterator<[string, axios.AxiosHeaderValue]>;
}
@ -96,7 +100,16 @@ declare class AxiosError<T = unknown, D = any> extends Error {
isAxiosError: boolean;
status?: number;
toJSON: () => object;
cause?: Error;
cause?: unknown;
event?: BrowserProgressEvent;
static from<T = unknown, D = any>(
error: Error | unknown,
code?: string,
config?: axios.InternalAxiosRequestConfig<D>,
request?: any,
response?: axios.AxiosResponse<T, D>,
customProps?: object,
): AxiosError<T, D>;
static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION";
@ -342,8 +355,6 @@ declare namespace axios {
type MaxDownloadRate = number;
type BrowserProgressEvent = any;
interface AxiosProgressEvent {
loaded: number;
total?: number;
@ -412,19 +423,29 @@ declare namespace axios {
insecureHTTPParser?: boolean;
env?: {
FormData?: new (...args: any[]) => object;
fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
Request?: new (input: URL | Request | string, init?: RequestInit) => Request;
Response?: new (
body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null,
init?: ResponseInit
) => Response;
};
formSerializer?: FormSerializerOptions;
family?: AddressFamily;
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
fetchOptions?: Record<string, any>;
fetchOptions?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'> | Record<string, any>;
httpVersion?: 1 | 2;
http2Options?: Record<string, any> & {
sessionTimeout?: number;
};
}
// Alias
type RawAxiosRequestConfig<D = any> = AxiosRequestConfig<D>;
interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig {
interface InternalAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
headers: AxiosRequestHeaders;
}
@ -450,11 +471,11 @@ declare namespace axios {
headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
}
interface AxiosResponse<T = any, D = any> {
interface AxiosResponse<T = any, D = any, H = {}> {
data: T;
status: number;
statusText: string;
headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders;
config: InternalAxiosRequestConfig<D>;
request?: any;
}
@ -542,6 +563,7 @@ declare namespace axios {
formToJSON(form: GenericFormData|GenericHTMLFormElement): object;
getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter;
AxiosHeaders: typeof AxiosHeaders;
mergeConfig<D = any>(config1: AxiosRequestConfig<D>, config2: AxiosRequestConfig<D>): AxiosRequestConfig<D>;
}
}

23
node_modules/axios/index.d.ts generated vendored
View File

@ -355,13 +355,24 @@ export interface AxiosRequestConfig<D = any> {
insecureHTTPParser?: boolean;
env?: {
FormData?: new (...args: any[]) => object;
fetch?: (input: URL | Request | string, init?: RequestInit) => Promise<Response>;
Request?: new (input: URL | Request | string, init?: RequestInit) => Request;
Response?: new (
body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null,
init?: ResponseInit
) => Response;
};
formSerializer?: FormSerializerOptions;
family?: AddressFamily;
lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) |
((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>);
withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined);
fetchOptions?: Record<string, any>;
parseReviver?: (this: any, key: string, value: any) => any;
fetchOptions?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'> | Record<string, any>;
httpVersion?: 1 | 2;
http2Options?: Record<string, any> & {
sessionTimeout?: number;
};
}
// Alias
@ -393,11 +404,11 @@ export interface CreateAxiosDefaults<D = any> extends Omit<AxiosRequestConfig<D>
headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial<HeadersDefaults>;
}
export interface AxiosResponse<T = any, D = any> {
export interface AxiosResponse<T = any, D = any, H = {}> {
data: T;
status: number;
statusText: string;
headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders;
config: InternalAxiosRequestConfig<D>;
request?: any;
}
@ -418,7 +429,8 @@ export class AxiosError<T = unknown, D = any> extends Error {
isAxiosError: boolean;
status?: number;
toJSON: () => object;
cause?: Error;
cause?: unknown;
event?: BrowserProgressEvent;
static from<T = unknown, D = any>(
error: Error | unknown,
code?: string,
@ -442,6 +454,7 @@ export class AxiosError<T = unknown, D = any> extends Error {
}
export class CanceledError<T> extends AxiosError<T> {
readonly name: "CanceledError";
}
export type AxiosPromise<T = any> = Promise<AxiosResponse<T>>;
@ -542,7 +555,7 @@ export function isAxiosError<T = any, D = any>(payload: any): payload is AxiosEr
export function spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
export function isCancel(value: any): value is Cancel;
export function isCancel<T = any>(value: any): value is CanceledError<T>;
export function all<T>(values: Array<T | Promise<T>>): Promise<T[]>;

View File

@ -1,79 +1,126 @@
import utils from '../utils.js';
import httpAdapter from './http.js';
import xhrAdapter from './xhr.js';
import fetchAdapter from './fetch.js';
import * as fetchAdapter from './fetch.js';
import AxiosError from "../core/AxiosError.js";
/**
* Known adapters mapping.
* Provides environment-specific adapters for Axios:
* - `http` for Node.js
* - `xhr` for browsers
* - `fetch` for fetch API-based requests
*
* @type {Object<string, Function|Object>}
*/
const knownAdapters = {
http: httpAdapter,
xhr: xhrAdapter,
fetch: fetchAdapter
}
fetch: {
get: fetchAdapter.getFetch,
}
};
// Assign adapter names for easier debugging and identification
utils.forEach(knownAdapters, (fn, value) => {
if (fn) {
try {
Object.defineProperty(fn, 'name', {value});
Object.defineProperty(fn, 'name', { value });
} catch (e) {
// eslint-disable-next-line no-empty
}
Object.defineProperty(fn, 'adapterName', {value});
Object.defineProperty(fn, 'adapterName', { value });
}
});
/**
* Render a rejection reason string for unknown or unsupported adapters
*
* @param {string} reason
* @returns {string}
*/
const renderReason = (reason) => `- ${reason}`;
/**
* Check if the adapter is resolved (function, null, or false)
*
* @param {Function|null|false} adapter
* @returns {boolean}
*/
const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;
export default {
getAdapter: (adapters) => {
adapters = utils.isArray(adapters) ? adapters : [adapters];
/**
* Get the first suitable adapter from the provided list.
* Tries each adapter in order until a supported one is found.
* Throws an AxiosError if no adapter is suitable.
*
* @param {Array<string|Function>|string|Function} adapters - Adapter(s) by name or function.
* @param {Object} config - Axios request configuration
* @throws {AxiosError} If no suitable adapter is available
* @returns {Function} The resolved adapter function
*/
function getAdapter(adapters, config) {
adapters = utils.isArray(adapters) ? adapters : [adapters];
const {length} = adapters;
let nameOrAdapter;
let adapter;
const { length } = adapters;
let nameOrAdapter;
let adapter;
const rejectedReasons = {};
const rejectedReasons = {};
for (let i = 0; i < length; i++) {
nameOrAdapter = adapters[i];
let id;
for (let i = 0; i < length; i++) {
nameOrAdapter = adapters[i];
let id;
adapter = nameOrAdapter;
adapter = nameOrAdapter;
if (!isResolvedHandle(nameOrAdapter)) {
adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
if (!isResolvedHandle(nameOrAdapter)) {
adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
if (adapter === undefined) {
throw new AxiosError(`Unknown adapter '${id}'`);
}
if (adapter === undefined) {
throw new AxiosError(`Unknown adapter '${id}'`);
}
if (adapter) {
break;
}
rejectedReasons[id || '#' + i] = adapter;
}
if (!adapter) {
if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {
break;
}
const reasons = Object.entries(rejectedReasons)
.map(([id, state]) => `adapter ${id} ` +
(state === false ? 'is not supported by the environment' : 'is not available in the build')
);
rejectedReasons[id || '#' + i] = adapter;
}
let s = length ?
(reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
'as no adapter specified';
throw new AxiosError(
`There is no suitable adapter to dispatch the request ` + s,
'ERR_NOT_SUPPORT'
if (!adapter) {
const reasons = Object.entries(rejectedReasons)
.map(([id, state]) => `adapter ${id} ` +
(state === false ? 'is not supported by the environment' : 'is not available in the build')
);
}
return adapter;
},
adapters: knownAdapters
let s = length ?
(reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
'as no adapter specified';
throw new AxiosError(
`There is no suitable adapter to dispatch the request ` + s,
'ERR_NOT_SUPPORT'
);
}
return adapter;
}
/**
* Exports Axios adapters and utility to resolve an adapter
*/
export default {
/**
* Resolve an adapter from a list of adapter names or functions.
* @type {Function}
*/
getAdapter,
/**
* Exposes all known adapters
* @type {Object<string, Function|Object>}
*/
adapters: knownAdapters
};

View File

@ -8,14 +8,18 @@ import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../h
import resolveConfig from "../helpers/resolveConfig.js";
import settle from "../core/settle.js";
const isFetchSupported = typeof fetch === 'function' && typeof Request === 'function' && typeof Response === 'function';
const isReadableStreamSupported = isFetchSupported && typeof ReadableStream === 'function';
const DEFAULT_CHUNK_SIZE = 64 * 1024;
const {isFunction} = utils;
const globalFetchAPI = (({Request, Response}) => ({
Request, Response
}))(utils.global);
const {
ReadableStream, TextEncoder
} = utils.global;
// used only inside the fetch adapter
const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
async (str) => new Uint8Array(await new Response(str).arrayBuffer())
);
const test = (fn, ...args) => {
try {
@ -25,205 +29,260 @@ const test = (fn, ...args) => {
}
}
const supportsRequestStream = isReadableStreamSupported && test(() => {
let duplexAccessed = false;
const factory = (env) => {
env = utils.merge.call({
skipUndefined: true
}, globalFetchAPI, env);
const hasContentType = new Request(platform.origin, {
body: new ReadableStream(),
method: 'POST',
get duplex() {
duplexAccessed = true;
return 'half';
},
}).headers.has('Content-Type');
const {fetch: envFetch, Request, Response} = env;
const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';
const isRequestSupported = isFunction(Request);
const isResponseSupported = isFunction(Response);
return duplexAccessed && !hasContentType;
});
if (!isFetchSupported) {
return false;
}
const DEFAULT_CHUNK_SIZE = 64 * 1024;
const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);
const supportsResponseStream = isReadableStreamSupported &&
test(() => utils.isReadableStream(new Response('').body));
const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
async (str) => new Uint8Array(await new Request(str).arrayBuffer())
);
const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
let duplexAccessed = false;
const resolvers = {
stream: supportsResponseStream && ((res) => res.body)
};
const hasContentType = new Request(platform.origin, {
body: new ReadableStream(),
method: 'POST',
get duplex() {
duplexAccessed = true;
return 'half';
},
}).headers.has('Content-Type');
return duplexAccessed && !hasContentType;
});
const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&
test(() => utils.isReadableStream(new Response('').body));
const resolvers = {
stream: supportsResponseStream && ((res) => res.body)
};
isFetchSupported && ((() => {
['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
!resolvers[type] && (resolvers[type] = (res, config) => {
let method = res && res[type];
if (method) {
return method.call(res);
}
isFetchSupported && (((res) => {
['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
!resolvers[type] && (resolvers[type] = utils.isFunction(res[type]) ? (res) => res[type]() :
(_, config) => {
throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);
})
});
})(new Response));
const getBodyLength = async (body) => {
if (body == null) {
return 0;
}
if(utils.isBlob(body)) {
return body.size;
}
if(utils.isSpecCompliantForm(body)) {
const _request = new Request(platform.origin, {
method: 'POST',
body,
});
return (await _request.arrayBuffer()).byteLength;
}
})());
if(utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
return body.byteLength;
}
const getBodyLength = async (body) => {
if (body == null) {
return 0;
}
if(utils.isURLSearchParams(body)) {
body = body + '';
}
if (utils.isBlob(body)) {
return body.size;
}
if(utils.isString(body)) {
return (await encodeText(body)).byteLength;
}
}
const resolveBodyLength = async (headers, body) => {
const length = utils.toFiniteNumber(headers.getContentLength());
return length == null ? getBodyLength(body) : length;
}
export default isFetchSupported && (async (config) => {
let {
url,
method,
data,
signal,
cancelToken,
timeout,
onDownloadProgress,
onUploadProgress,
responseType,
headers,
withCredentials = 'same-origin',
fetchOptions
} = resolveConfig(config);
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
let request;
const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
composedSignal.unsubscribe();
});
let requestContentLength;
try {
if (
onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&
(requestContentLength = await resolveBodyLength(headers, data)) !== 0
) {
let _request = new Request(url, {
if (utils.isSpecCompliantForm(body)) {
const _request = new Request(platform.origin, {
method: 'POST',
body: data,
duplex: "half"
body,
});
let contentTypeHeader;
if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
headers.setContentType(contentTypeHeader)
}
if (_request.body) {
const [onProgress, flush] = progressEventDecorator(
requestContentLength,
progressEventReducer(asyncDecorator(onUploadProgress))
);
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
}
return (await _request.arrayBuffer()).byteLength;
}
if (!utils.isString(withCredentials)) {
withCredentials = withCredentials ? 'include' : 'omit';
if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
return body.byteLength;
}
// Cloudflare Workers throws when credentials are defined
// see https://github.com/cloudflare/workerd/issues/902
const isCredentialsSupported = "credentials" in Request.prototype;
request = new Request(url, {
...fetchOptions,
signal: composedSignal,
method: method.toUpperCase(),
headers: headers.normalize().toJSON(),
body: data,
duplex: "half",
credentials: isCredentialsSupported ? withCredentials : undefined
if (utils.isURLSearchParams(body)) {
body = body + '';
}
if (utils.isString(body)) {
return (await encodeText(body)).byteLength;
}
}
const resolveBodyLength = async (headers, body) => {
const length = utils.toFiniteNumber(headers.getContentLength());
return length == null ? getBodyLength(body) : length;
}
return async (config) => {
let {
url,
method,
data,
signal,
cancelToken,
timeout,
onDownloadProgress,
onUploadProgress,
responseType,
headers,
withCredentials = 'same-origin',
fetchOptions
} = resolveConfig(config);
let _fetch = envFetch || fetch;
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
let request = null;
const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
composedSignal.unsubscribe();
});
let response = await fetch(request);
let requestContentLength;
const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
try {
if (
onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&
(requestContentLength = await resolveBodyLength(headers, data)) !== 0
) {
let _request = new Request(url, {
method: 'POST',
body: data,
duplex: "half"
});
if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
const options = {};
let contentTypeHeader;
['status', 'statusText', 'headers'].forEach(prop => {
options[prop] = response[prop];
});
const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
responseContentLength,
progressEventReducer(asyncDecorator(onDownloadProgress), true)
) || [];
response = new Response(
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
flush && flush();
unsubscribe && unsubscribe();
}),
options
);
}
responseType = responseType || 'text';
let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
!isStreamResponse && unsubscribe && unsubscribe();
return await new Promise((resolve, reject) => {
settle(resolve, reject, {
data: responseData,
headers: AxiosHeaders.from(response.headers),
status: response.status,
statusText: response.statusText,
config,
request
})
})
} catch (err) {
unsubscribe && unsubscribe();
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
throw Object.assign(
new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),
{
cause: err.cause || err
if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
headers.setContentType(contentTypeHeader)
}
)
if (_request.body) {
const [onProgress, flush] = progressEventDecorator(
requestContentLength,
progressEventReducer(asyncDecorator(onUploadProgress))
);
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
}
}
if (!utils.isString(withCredentials)) {
withCredentials = withCredentials ? 'include' : 'omit';
}
// Cloudflare Workers throws when credentials are defined
// see https://github.com/cloudflare/workerd/issues/902
const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype;
const resolvedOptions = {
...fetchOptions,
signal: composedSignal,
method: method.toUpperCase(),
headers: headers.normalize().toJSON(),
body: data,
duplex: "half",
credentials: isCredentialsSupported ? withCredentials : undefined
};
request = isRequestSupported && new Request(url, resolvedOptions);
let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));
const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
const options = {};
['status', 'statusText', 'headers'].forEach(prop => {
options[prop] = response[prop];
});
const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
responseContentLength,
progressEventReducer(asyncDecorator(onDownloadProgress), true)
) || [];
response = new Response(
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
flush && flush();
unsubscribe && unsubscribe();
}),
options
);
}
responseType = responseType || 'text';
let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
!isStreamResponse && unsubscribe && unsubscribe();
return await new Promise((resolve, reject) => {
settle(resolve, reject, {
data: responseData,
headers: AxiosHeaders.from(response.headers),
status: response.status,
statusText: response.statusText,
config,
request
})
})
} catch (err) {
unsubscribe && unsubscribe();
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
throw Object.assign(
new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),
{
cause: err.cause || err
}
)
}
throw AxiosError.from(err, err && err.code, config, request);
}
throw AxiosError.from(err, err && err.code, config, request);
}
});
}
const seedCache = new Map();
export const getFetch = (config) => {
let env = (config && config.env) || {};
const {fetch, Request, Response} = env;
const seeds = [
Request, Response, fetch
];
let len = seeds.length, i = len,
seed, target, map = seedCache;
while (i--) {
seed = seeds[i];
target = map.get(seed);
target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))
map = target;
}
return target;
};
const adapter = getFetch();
export default adapter;

View File

@ -1,5 +1,3 @@
'use strict';
import utils from './../utils.js';
import settle from './../core/settle.js';
import buildFullPath from '../core/buildFullPath.js';
@ -7,6 +5,7 @@ import buildURL from './../helpers/buildURL.js';
import proxyFromEnv from 'proxy-from-env';
import http from 'http';
import https from 'https';
import http2 from 'http2';
import util from 'util';
import followRedirects from 'follow-redirects';
import zlib from 'zlib';
@ -25,6 +24,7 @@ import readBlob from "../helpers/readBlob.js";
import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
import callbackify from "../helpers/callbackify.js";
import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js";
import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';
const zlibOptions = {
flush: zlib.constants.Z_SYNC_FLUSH,
@ -46,6 +46,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
return protocol + ':';
});
const flushOnFinish = (stream, [throttled, flush]) => {
stream
.on('end', flush)
@ -54,6 +55,102 @@ const flushOnFinish = (stream, [throttled, flush]) => {
return throttled;
}
class Http2Sessions {
constructor() {
this.sessions = Object.create(null);
}
getSession(authority, options) {
options = Object.assign({
sessionTimeout: 1000
}, options);
let authoritySessions = this.sessions[authority];
if (authoritySessions) {
let len = authoritySessions.length;
for (let i = 0; i < len; i++) {
const [sessionHandle, sessionOptions] = authoritySessions[i];
if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
return sessionHandle;
}
}
}
const session = http2.connect(authority, options);
let removed;
const removeSession = () => {
if (removed) {
return;
}
removed = true;
let entries = authoritySessions, len = entries.length, i = len;
while (i--) {
if (entries[i][0] === session) {
if (len === 1) {
delete this.sessions[authority];
} else {
entries.splice(i, 1);
}
return;
}
}
};
const originalRequestFn = session.request;
const {sessionTimeout} = options;
if(sessionTimeout != null) {
let timer;
let streamsCount = 0;
session.request = function () {
const stream = originalRequestFn.apply(this, arguments);
streamsCount++;
if (timer) {
clearTimeout(timer);
timer = null;
}
stream.once('close', () => {
if (!--streamsCount) {
timer = setTimeout(() => {
timer = null;
removeSession();
}, sessionTimeout);
}
});
return stream;
}
}
session.once('close', removeSession);
let entry = [
session,
options
];
authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
return session;
}
}
const http2Sessions = new Http2Sessions();
/**
* If the proxy or config beforeRedirects functions are defined, call them with the options
* object.
@ -165,16 +262,75 @@ const resolveFamily = ({address, family}) => {
const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
const http2Transport = {
request(options, cb) {
const authority = options.protocol + '//' + options.hostname + ':' + (options.port || 80);
const {http2Options, headers} = options;
const session = http2Sessions.getSession(authority, http2Options);
const {
HTTP2_HEADER_SCHEME,
HTTP2_HEADER_METHOD,
HTTP2_HEADER_PATH,
HTTP2_HEADER_STATUS
} = http2.constants;
const http2Headers = {
[HTTP2_HEADER_SCHEME]: options.protocol.replace(':', ''),
[HTTP2_HEADER_METHOD]: options.method,
[HTTP2_HEADER_PATH]: options.path,
}
utils.forEach(headers, (header, name) => {
name.charAt(0) !== ':' && (http2Headers[name] = header);
});
const req = session.request(http2Headers);
req.once('response', (responseHeaders) => {
const response = req; //duplex
responseHeaders = Object.assign({}, responseHeaders);
const status = responseHeaders[HTTP2_HEADER_STATUS];
delete responseHeaders[HTTP2_HEADER_STATUS];
response.headers = responseHeaders;
response.statusCode = +status;
cb(response);
})
return req;
}
}
/*eslint consistent-return:0*/
export default isHttpAdapterSupported && function httpAdapter(config) {
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
let {data, lookup, family} = config;
let {data, lookup, family, httpVersion = 1, http2Options} = config;
const {responseType, responseEncoding} = config;
const method = config.method.toUpperCase();
let isDone;
let rejected = false;
let req;
httpVersion = +httpVersion;
if (Number.isNaN(httpVersion)) {
throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`);
}
if (httpVersion !== 1 && httpVersion !== 2) {
throw TypeError(`Unsupported protocol version '${httpVersion}'`);
}
const isHttp2 = httpVersion === 2;
if (lookup) {
const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);
// hotfix to support opt.all option which is required for node 20.x
@ -191,8 +347,17 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
}
}
// temporary internal emitter until the AxiosRequest class will be implemented
const emitter = new EventEmitter();
const abortEmitter = new EventEmitter();
function abort(reason) {
try {
abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
} catch(err) {
console.warn('emit error', err);
}
}
abortEmitter.once('abort', reject);
const onFinished = () => {
if (config.cancelToken) {
@ -203,23 +368,9 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
config.signal.removeEventListener('abort', abort);
}
emitter.removeAllListeners();
abortEmitter.removeAllListeners();
}
onDone((value, isRejected) => {
isDone = true;
if (isRejected) {
rejected = true;
onFinished();
}
});
function abort(reason) {
emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
}
emitter.once('abort', reject);
if (config.cancelToken || config.signal) {
config.cancelToken && config.cancelToken.subscribe(abort);
if (config.signal) {
@ -227,12 +378,52 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
}
}
onDone((response, isRejected) => {
isDone = true;
if (isRejected) {
rejected = true;
onFinished();
return;
}
const {data} = response;
if (data instanceof stream.Readable || data instanceof stream.Duplex) {
const offListeners = stream.finished(data, () => {
offListeners();
onFinished();
});
} else {
onFinished();
}
});
// Parse url
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
const protocol = parsed.protocol || supportedProtocols[0];
if (protocol === 'data:') {
// Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
if (config.maxContentLength > -1) {
// Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
const dataUrl = String(config.url || fullPath || '');
const estimated = estimateDataURLDecodedBytes(dataUrl);
if (estimated > config.maxContentLength) {
return reject(new AxiosError(
'maxContentLength size of ' + config.maxContentLength + ' exceeded',
AxiosError.ERR_BAD_RESPONSE,
config
));
}
}
let convertedData;
if (method !== 'GET') {
@ -418,7 +609,8 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
protocol,
family,
beforeRedirect: dispatchBeforeRedirect,
beforeRedirects: {}
beforeRedirects: {},
http2Options
};
// cacheable-lookup integration hotfix
@ -435,18 +627,23 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
let transport;
const isHttpsRequest = isHttps.test(options.protocol);
options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
if (config.transport) {
transport = config.transport;
} else if (config.maxRedirects === 0) {
transport = isHttpsRequest ? https : http;
if (isHttp2) {
transport = http2Transport;
} else {
if (config.maxRedirects) {
options.maxRedirects = config.maxRedirects;
if (config.transport) {
transport = config.transport;
} else if (config.maxRedirects === 0) {
transport = isHttpsRequest ? https : http;
} else {
if (config.maxRedirects) {
options.maxRedirects = config.maxRedirects;
}
if (config.beforeRedirect) {
options.beforeRedirects.config = config.beforeRedirect;
}
transport = isHttpsRequest ? httpsFollow : httpFollow;
}
if (config.beforeRedirect) {
options.beforeRedirects.config = config.beforeRedirect;
}
transport = isHttpsRequest ? httpsFollow : httpFollow;
}
if (config.maxBodyLength > -1) {
@ -466,7 +663,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
const streams = [res];
const responseLength = +res.headers['content-length'];
const responseLength = utils.toFiniteNumber(res.headers['content-length']);
if (onDownloadProgress || maxDownloadRate) {
const transformStream = new AxiosTransformStream({
@ -529,10 +726,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
const offListeners = stream.finished(responseStream, () => {
offListeners();
onFinished();
});
const response = {
status: res.statusCode,
@ -558,7 +752,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
// stream.destroy() emit aborted event before calling reject() on Node.js v16
rejected = true;
responseStream.destroy();
reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
abort(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
}
});
@ -600,7 +794,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
});
}
emitter.once('abort', err => {
abortEmitter.once('abort', err => {
if (!responseStream.destroyed) {
responseStream.emit('error', err);
responseStream.destroy();
@ -608,9 +802,12 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
});
});
emitter.once('abort', err => {
reject(err);
req.destroy(err);
abortEmitter.once('abort', err => {
if (req.close) {
req.close();
} else {
req.destroy(err);
}
});
// Handle errors
@ -632,7 +829,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
const timeout = parseInt(config.timeout, 10);
if (Number.isNaN(timeout)) {
reject(new AxiosError(
abort(new AxiosError(
'error trying to parse `config.timeout` to int',
AxiosError.ERR_BAD_OPTION_VALUE,
config,
@ -654,14 +851,16 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
if (config.timeoutErrorMessage) {
timeoutErrorMessage = config.timeoutErrorMessage;
}
reject(new AxiosError(
abort(new AxiosError(
timeoutErrorMessage,
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
config,
req
));
abort();
});
} else {
// explicitly reset the socket timeout value for a possible `keep-alive` request
req.setTimeout(0);
}
@ -687,7 +886,8 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
data.pipe(req);
} else {
req.end(data);
data && req.write(data);
req.end();
}
});
}

View File

@ -104,15 +104,18 @@ export default isXHRAdapterSupported && function (config) {
};
// Handle low level network errors
request.onerror = function handleError() {
// Real errors are hidden from us by the browser
// onerror should only fire if it's a network error
reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));
// Clean up request
request = null;
request.onerror = function handleError(event) {
// Browsers deliver a ProgressEvent in XHR onerror
// (message may be empty; when present, surface it)
// See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
const msg = event && event.message ? event.message : 'Network Error';
const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
// attach the underlying event for consumers who want details
err.event = event || null;
reject(err);
request = null;
};
// Handle timeout
request.ontimeout = function handleTimeout() {
let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';

View File

@ -153,8 +153,8 @@ class Axios {
if (!synchronousRequestInterceptors) {
const chain = [dispatchRequest.bind(this), undefined];
chain.unshift.apply(chain, requestInterceptorChain);
chain.push.apply(chain, responseInterceptorChain);
chain.unshift(...requestInterceptorChain);
chain.push(...responseInterceptorChain);
len = chain.length;
promise = Promise.resolve(config);
@ -170,8 +170,6 @@ class Axios {
let newConfig = config;
i = 0;
while (i < len) {
const onFulfilled = requestInterceptorChain[i++];
const onRejected = requestInterceptorChain[i++];

View File

@ -89,11 +89,18 @@ AxiosError.from = (error, code, config, request, response, customProps) => {
return prop !== 'isAxiosError';
});
AxiosError.call(axiosError, error.message, code, config, request, response);
const msg = error && error.message ? error.message : 'Error';
axiosError.cause = error;
// Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)
const errCode = code == null && error ? error.code : code;
AxiosError.call(axiosError, msg, errCode, config, request, response);
axiosError.name = error.name;
// Chain the original error on the standard field; non-enumerable to avoid JSON noise
if (error && axiosError.cause == null) {
Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });
}
axiosError.name = (error && error.name) || 'Error';
customProps && Object.assign(axiosError, customProps);

View File

@ -30,7 +30,7 @@ class InterceptorManager {
*
* @param {Number} id The ID that was returned by `use`
*
* @returns {Boolean} `true` if the interceptor was removed, `false` otherwise
* @returns {void}
*/
eject(id) {
if (this.handlers[id]) {

View File

@ -46,7 +46,7 @@ export default function dispatchRequest(config) {
config.headers.setContentType('application/x-www-form-urlencoded', false);
}
const adapter = adapters.getAdapter(config.adapter || defaults.adapter);
const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);
return adapter(config).then(function onAdapterResolution(response) {
throwIfCancellationRequested(config);

View File

@ -31,11 +31,11 @@ export default function mergeConfig(config1, config2) {
}
// eslint-disable-next-line consistent-return
function mergeDeepProperties(a, b, prop , caseless) {
function mergeDeepProperties(a, b, prop, caseless) {
if (!utils.isUndefined(b)) {
return getMergedValue(a, b, prop , caseless);
return getMergedValue(a, b, prop, caseless);
} else if (!utils.isUndefined(a)) {
return getMergedValue(undefined, a, prop , caseless);
return getMergedValue(undefined, a, prop, caseless);
}
}
@ -93,10 +93,10 @@ export default function mergeConfig(config1, config2) {
socketPath: defaultToConfig2,
responseEncoding: defaultToConfig2,
validateStatus: mergeDirectKeys,
headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
headers: (a, b, prop) => mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true)
};
utils.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {
utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
const merge = mergeMap[prop] || mergeDeepProperties;
const configValue = merge(config1[prop], config2[prop], prop);
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);

View File

@ -111,7 +111,7 @@ const defaults = {
const strictJSONParsing = !silentJSONParsing && JSONRequested;
try {
return JSON.parse(data);
return JSON.parse(data, this.parseReviver);
} catch (e) {
if (strictJSONParsing) {
if (e.name === 'SyntaxError') {

2
node_modules/axios/lib/env/data.js generated vendored
View File

@ -1 +1 @@
export const VERSION = "1.9.0";
export const VERSION = "1.13.2";

View File

@ -62,6 +62,12 @@ const HttpStatusCode = {
LoopDetected: 508,
NotExtended: 510,
NetworkAuthenticationRequired: 511,
WebServerIsDown: 521,
ConnectionTimedOut: 522,
OriginIsUnreachable: 523,
TimeoutOccurred: 524,
SslHandshakeFailed: 525,
InvalidSslCertificate: 526,
};
Object.entries(HttpStatusCode).forEach(([key, value]) => {

View File

@ -1,5 +1,12 @@
'use strict';
/**
* Create a bound version of a function with a specified `this` context
*
* @param {Function} fn - The function to bind
* @param {*} thisArg - The value to be passed as the `this` parameter
* @returns {Function} A new function that will call the original function with the specified `this` context
*/
export default function bind(fn, thisArg) {
return function wrap() {
return fn.apply(thisArg, arguments);

View File

@ -16,9 +16,7 @@ function encode(val) {
replace(/%3A/gi, ':').
replace(/%24/g, '$').
replace(/%2C/gi, ',').
replace(/%20/g, '+').
replace(/%5B/gi, '[').
replace(/%5D/gi, ']');
replace(/%20/g, '+');
}
/**

View File

@ -5,27 +5,38 @@ export default platform.hasStandardBrowserEnv ?
// Standard browser envs support document.cookie
{
write(name, value, expires, path, domain, secure) {
const cookie = [name + '=' + encodeURIComponent(value)];
write(name, value, expires, path, domain, secure, sameSite) {
if (typeof document === 'undefined') return;
utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());
const cookie = [`${name}=${encodeURIComponent(value)}`];
utils.isString(path) && cookie.push('path=' + path);
utils.isString(domain) && cookie.push('domain=' + domain);
secure === true && cookie.push('secure');
if (utils.isNumber(expires)) {
cookie.push(`expires=${new Date(expires).toUTCString()}`);
}
if (utils.isString(path)) {
cookie.push(`path=${path}`);
}
if (utils.isString(domain)) {
cookie.push(`domain=${domain}`);
}
if (secure === true) {
cookie.push('secure');
}
if (utils.isString(sameSite)) {
cookie.push(`SameSite=${sameSite}`);
}
document.cookie = cookie.join('; ');
},
read(name) {
const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
return (match ? decodeURIComponent(match[3]) : null);
if (typeof document === 'undefined') return null;
const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
return match ? decodeURIComponent(match[1]) : null;
},
remove(name) {
this.write(name, '', Date.now() - 86400000);
this.write(name, '', Date.now() - 86400000, '/');
}
}

View File

@ -0,0 +1,73 @@
/**
* Estimate decoded byte length of a data:// URL *without* allocating large buffers.
* - For base64: compute exact decoded size using length and padding;
* handle %XX at the character-count level (no string allocation).
* - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound.
*
* @param {string} url
* @returns {number}
*/
export default function estimateDataURLDecodedBytes(url) {
if (!url || typeof url !== 'string') return 0;
if (!url.startsWith('data:')) return 0;
const comma = url.indexOf(',');
if (comma < 0) return 0;
const meta = url.slice(5, comma);
const body = url.slice(comma + 1);
const isBase64 = /;base64/i.test(meta);
if (isBase64) {
let effectiveLen = body.length;
const len = body.length; // cache length
for (let i = 0; i < len; i++) {
if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {
const a = body.charCodeAt(i + 1);
const b = body.charCodeAt(i + 2);
const isHex =
((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) &&
((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102));
if (isHex) {
effectiveLen -= 2;
i += 2;
}
}
}
let pad = 0;
let idx = len - 1;
const tailIsPct3D = (j) =>
j >= 2 &&
body.charCodeAt(j - 2) === 37 && // '%'
body.charCodeAt(j - 1) === 51 && // '3'
(body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd'
if (idx >= 0) {
if (body.charCodeAt(idx) === 61 /* '=' */) {
pad++;
idx--;
} else if (tailIsPct3D(idx)) {
pad++;
idx -= 3;
}
}
if (pad === 1 && idx >= 0) {
if (body.charCodeAt(idx) === 61 /* '=' */) {
pad++;
} else if (tailIsPct3D(idx)) {
pad++;
}
}
const groups = Math.floor(effectiveLen / 4);
const bytes = groups * 3 - (pad || 0);
return bytes > 0 ? bytes : 0;
}
return Buffer.byteLength(body, 'utf8');
}

View File

@ -10,7 +10,7 @@ import buildURL from "./buildURL.js";
export default (config) => {
const newConfig = mergeConfig({}, config);
let {data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth} = newConfig;
let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;
newConfig.headers = headers = AxiosHeaders.from(headers);
@ -23,17 +23,21 @@ export default (config) => {
);
}
let contentType;
if (utils.isFormData(data)) {
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {
headers.setContentType(undefined); // Let the browser set it
} else if ((contentType = headers.getContentType()) !== false) {
// fix semicolon duplication issue for ReactNative FormData implementation
const [type, ...tokens] = contentType ? contentType.split(';').map(token => token.trim()).filter(Boolean) : [];
headers.setContentType([type || 'multipart/form-data', ...tokens].join('; '));
headers.setContentType(undefined); // browser handles it
} else if (utils.isFunction(data.getHeaders)) {
// Node.js FormData (like form-data package)
const formHeaders = data.getHeaders();
// Only set safe headers to avoid overwriting security headers
const allowedHeaders = ['content-type', 'content-length'];
Object.entries(formHeaders).forEach(([key, val]) => {
if (allowedHeaders.includes(key.toLowerCase())) {
headers.set(key, val);
}
});
}
}
}
// Add xsrf header
// This is only done if running in a standard browser environment.

View File

@ -17,7 +17,7 @@ function throttle(fn, freq) {
clearTimeout(timer);
timer = null;
}
fn.apply(null, args);
fn(...args);
}
const throttled = (...args) => {

View File

@ -120,6 +120,10 @@ function toFormData(obj, formData, options) {
return value.toISOString();
}
if (utils.isBoolean(value)) {
return value.toString();
}
if (!useBlob && utils.isBlob(value)) {
throw new AxiosError('Blob is not supported. Use a Buffer instead.');
}

View File

@ -5,7 +5,7 @@ import toFormData from './toFormData.js';
import platform from '../platform/index.js';
export default function toURLEncodedForm(data, options) {
return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({
return toFormData(data, new platform.classes.URLSearchParams(), {
visitor: function(value, key, path, helpers) {
if (platform.isNode && utils.isBuffer(value)) {
this.append(key, value.toString('base64'));
@ -13,6 +13,7 @@ export default function toURLEncodedForm(data, options) {
}
return helpers.defaultVisitor.apply(this, arguments);
}
}, options));
},
...options
});
}

42
node_modules/axios/lib/utils.js generated vendored
View File

@ -136,6 +136,27 @@ const isPlainObject = (val) => {
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
}
/**
* Determine if a value is an empty object (safely handles Buffers)
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is an empty object, otherwise false
*/
const isEmptyObject = (val) => {
// Early return for non-objects or Buffers to prevent RangeError
if (!isObject(val) || isBuffer(val)) {
return false;
}
try {
return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
} catch (e) {
// Fallback for any other objects that might cause RangeError with Object.keys()
return false;
}
}
/**
* Determine if a value is a Date
*
@ -258,6 +279,11 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
fn.call(null, obj[i], i, obj);
}
} else {
// Buffer check
if (isBuffer(obj)) {
return;
}
// Iterate over object keys
const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
const len = keys.length;
@ -271,6 +297,10 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
}
function findKey(obj, key) {
if (isBuffer(obj)){
return null;
}
key = key.toLowerCase();
const keys = Object.keys(obj);
let i = keys.length;
@ -311,7 +341,7 @@ const isContextDefined = (context) => !isUndefined(context) && context !== _glob
* @returns {Object} Result of all merge properties
*/
function merge(/* obj1, obj2, obj3, ... */) {
const {caseless} = isContextDefined(this) && this || {};
const {caseless, skipUndefined} = isContextDefined(this) && this || {};
const result = {};
const assignValue = (val, key) => {
const targetKey = caseless && findKey(result, key) || key;
@ -321,7 +351,7 @@ function merge(/* obj1, obj2, obj3, ... */) {
result[targetKey] = merge({}, val);
} else if (isArray(val)) {
result[targetKey] = val.slice();
} else {
} else if (!skipUndefined || !isUndefined(val)) {
result[targetKey] = val;
}
}
@ -603,6 +633,8 @@ const toFiniteNumber = (value, defaultValue) => {
return value != null && Number.isFinite(value = +value) ? value : defaultValue;
}
/**
* If the thing is a FormData object, return true, otherwise return false.
*
@ -624,6 +656,11 @@ const toJSONObject = (obj) => {
return;
}
//Buffer check
if (isBuffer(source)) {
return source;
}
if(!('toJSON' in source)) {
stack[i] = source;
const target = isArray(source) ? [] : {};
@ -695,6 +732,7 @@ export default {
isBoolean,
isObject,
isPlainObject,
isEmptyObject,
isReadableStream,
isRequest,
isResponse,

52
node_modules/axios/package.json generated vendored
View File

@ -1,6 +1,6 @@
{
"name": "axios",
"version": "1.9.0",
"version": "1.13.2",
"description": "Promise based HTTP client for the browser and node.js",
"main": "index.js",
"exports": {
@ -9,6 +9,10 @@
"require": "./index.d.cts",
"default": "./index.d.ts"
},
"react-native": {
"require": "./dist/browser/axios.cjs",
"default": "./dist/esm/axios.js"
},
"browser": {
"require": "./dist/browser/axios.cjs",
"default": "./index.js"
@ -29,23 +33,28 @@
"./unsafe/adapters/http.js": "./lib/adapters/http.js",
"./unsafe/adapters/xhr.js": "./lib/adapters/xhr.js",
"./unsafe/utils.js": "./lib/utils.js",
"./package.json": "./package.json"
"./package.json": "./package.json",
"./dist/browser/axios.cjs": "./dist/browser/axios.cjs",
"./dist/node/axios.cjs": "./dist/node/axios.cjs"
},
"type": "module",
"types": "index.d.ts",
"scripts": {
"test": "npm run test:eslint && npm run test:mocha && npm run test:karma && npm run test:dtslint && npm run test:exports",
"test": "npm run test:node && npm run test:browser && npm run test:package",
"test:node": "npm run test:mocha",
"test:browser": "npm run test:karma",
"test:package": "npm run test:eslint && npm run test:dtslint && npm run test:exports",
"test:eslint": "node bin/ssl_hotfix.js eslint lib/**/*.js",
"test:dtslint": "dtslint --localTs node_modules/typescript/lib",
"test:mocha": "node bin/ssl_hotfix.js mocha test/unit/**/*.js --timeout 30000 --exit",
"test:exports": "node bin/ssl_hotfix.js mocha test/module/test.js --timeout 30000 --exit",
"test:karma": "node bin/ssl_hotfix.js cross-env LISTEN_ADDR=:: karma start karma.conf.cjs --single-run",
"test:karma": "node ./bin/run-karma-tests.js",
"test:karma:firefox": "node bin/ssl_hotfix.js cross-env LISTEN_ADDR=:: Browsers=Firefox karma start karma.conf.cjs --single-run",
"test:karma:server": "node bin/ssl_hotfix.js cross-env karma start karma.conf.cjs",
"test:build:version": "node ./bin/check-build-version.js",
"start": "node ./sandbox/server.js",
"preversion": "gulp version",
"version": "npm run build && git add dist && git add package.json",
"version": "npm run build && git add package.json",
"prepublishOnly": "npm run test:build:version",
"postpublish": "git push && git push --tags",
"build": "gulp clear && cross-env NODE_ENV=production rollup -c -m",
@ -71,7 +80,12 @@
"http",
"ajax",
"promise",
"node"
"node",
"browser",
"fetch",
"rest",
"api",
"client"
],
"author": "Matt Zabriskie",
"license": "MIT",
@ -85,6 +99,7 @@
"@commitlint/cli": "^17.8.1",
"@commitlint/config-conventional": "^17.8.1",
"@release-it/conventional-changelog": "^5.1.1",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-json": "^4.1.0",
@ -106,7 +121,6 @@
"fs-extra": "^10.1.0",
"get-stream": "^3.0.0",
"gulp": "^4.0.2",
"gzip-size": "^7.0.0",
"handlebars": "^4.7.8",
"husky": "^8.0.3",
"istanbul-instrumenter-loader": "^3.0.1",
@ -125,30 +139,36 @@
"minimist": "^1.2.8",
"mocha": "^10.3.0",
"multer": "^1.4.4",
"pacote": "^20.0.0",
"pretty-bytes": "^6.1.1",
"release-it": "^15.11.0",
"rollup": "^2.79.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-bundle-size": "^1.0.3",
"rollup-plugin-terser": "^7.0.2",
"selfsigned": "^3.0.1",
"sinon": "^4.5.0",
"stream-throttle": "^0.1.3",
"string-replace-async": "^3.0.2",
"terser-webpack-plugin": "^4.2.3",
"typescript": "^4.9.5",
"@rollup/plugin-alias": "^5.1.0"
"tar-stream": "^3.1.7",
"typescript": "^4.9.5"
},
"browser": {
"./lib/adapters/http.js": "./lib/helpers/null.js",
"./lib/platform/node/index.js": "./lib/platform/browser/index.js",
"./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js"
},
"react-native": {
"./lib/adapters/http.js": "./lib/helpers/null.js",
"./lib/platform/node/index.js": "./lib/platform/browser/index.js",
"./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js"
},
"jsdelivr": "dist/axios.min.js",
"unpkg": "dist/axios.min.js",
"typings": "./index.d.ts",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
},
"bundlesize": [
@ -159,17 +179,17 @@
],
"contributors": [
"Matt Zabriskie (https://github.com/mzabriskie)",
"Nick Uraltsev (https://github.com/nickuraltsev)",
"Dmitriy Mozgovoy (https://github.com/DigitalBrainJS)",
"Nick Uraltsev (https://github.com/nickuraltsev)",
"Jay (https://github.com/jasonsaayman)",
"Emily Morehouse (https://github.com/emilyemorehouse)",
"Rubén Norte (https://github.com/rubennorte)",
"Justin Beckwith (https://github.com/JustinBeckwith)",
"Martti Laine (https://github.com/codeclown)",
"Xianming Zhong (https://github.com/chinesedfan)",
"Rikki Gibson (https://github.com/RikkiGibson)",
"Remco Haszing (https://github.com/remcohaszing)",
"Yasu Flores (https://github.com/yasuf)",
"Rikki Gibson (https://github.com/RikkiGibson)",
"Willian Agostini (https://github.com/WillianAgostini)",
"Ben Carp (https://github.com/carpben)"
],
"sideEffects": false,
@ -199,8 +219,8 @@
},
"hooks": {
"before:init": "npm test",
"after:bump": "gulp version --bump ${version} && npm run build && npm run test:build:version && git add ./dist && git add ./package-lock.json",
"before:release": "npm run release:changelog:fix",
"after:bump": "gulp version --bump ${version} && npm run build && npm run test:build:version",
"before:release": "npm run release:changelog:fix && git add ./package-lock.json",
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
}
},

20
node_modules/blueimp-md5/LICENSE.txt generated vendored Normal file
View File

@ -0,0 +1,20 @@
MIT License
Copyright © 2011 Sebastian Tschan, https://blueimp.net
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.

134
node_modules/blueimp-md5/README.md generated vendored Normal file
View File

@ -0,0 +1,134 @@
# JavaScript MD5
## Contents
- [Demo](https://blueimp.github.io/JavaScript-MD5/)
- [Description](#description)
- [Usage](#usage)
- [Client-side](#client-side)
- [Server-side](#server-side)
- [Requirements](#requirements)
- [API](#api)
- [Tests](#tests)
- [License](#license)
## Description
JavaScript [MD5](https://en.wikipedia.org/wiki/MD5) implementation.
Compatible with server-side environments like [Node.js](https://nodejs.org/),
module loaders like [RequireJS](https://requirejs.org/) or
[webpack](https://webpack.js.org/) and all web browsers.
## Usage
### Client-side
Install the **blueimp-md5** package with [NPM](https://www.npmjs.org/):
```sh
npm install blueimp-md5
```
Include the (minified) JavaScript [MD5](https://en.wikipedia.org/wiki/MD5)
script in your HTML markup:
```html
<script src="js/md5.min.js"></script>
```
In your application code, calculate the
([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded)
[MD5](https://en.wikipedia.org/wiki/MD5) hash of a string by calling the **md5**
method with the string as argument:
```js
var hash = md5('value') // "2063c1608d6e0baf80249c42e2be5804"
```
### Server-side
The following is an example how to use the JavaScript MD5 module on the
server-side with [Node.js](https://nodejs.org/).
Install the **blueimp-md5** package with [NPM](https://www.npmjs.org/):
```sh
npm install blueimp-md5
```
Add a file **server.js** with the following content:
```js
require('http')
.createServer(function (req, res) {
// The md5 module exports the md5() function:
var md5 = require('./md5'),
// Use the following version if you installed the package with npm:
// var md5 = require("blueimp-md5"),
url = require('url'),
query = url.parse(req.url).query
res.writeHead(200, { 'Content-Type': 'text/plain' })
// Calculate and print the MD5 hash of the url query:
res.end(md5(query))
})
.listen(8080, 'localhost')
console.log('Server running at http://localhost:8080/')
```
Run the application with the following command:
```sh
node server.js
```
## Requirements
The JavaScript MD5 script has zero dependencies.
## API
Calculate the ([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded)
[MD5](https://en.wikipedia.org/wiki/MD5) hash of a given string value:
```js
var hash = md5('value') // "2063c1608d6e0baf80249c42e2be5804"
```
Calculate the ([hex](https://en.wikipedia.org/wiki/Hexadecimal)-encoded)
[HMAC](https://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and
key:
```js
var hash = md5('value', 'key') // "01433efd5f16327ea4b31144572c67f6"
```
Calculate the raw [MD5](https://en.wikipedia.org/wiki/MD5) hash of a given
string value:
```js
var hash = md5('value', null, true)
```
Calculate the raw [HMAC](https://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given
string value and key:
```js
var hash = md5('value', 'key', true)
```
## Tests
The JavaScript MD5 project comes with
[Unit Tests](https://en.wikipedia.org/wiki/Unit_testing).
There are two different ways to run the tests:
- Open test/index.html in your browser or
- run `npm test` in the Terminal in the root path of the repository package.
The first one tests the browser integration, the second one the
[Node.js](https://nodejs.org/) integration.
## License
The JavaScript MD5 script is released under the
[MIT license](https://opensource.org/licenses/MIT).

402
node_modules/blueimp-md5/js/md5.js generated vendored Normal file
View File

@ -0,0 +1,402 @@
/*
* JavaScript MD5
* https://github.com/blueimp/JavaScript-MD5
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*
* Based on
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
/* global define */
/* eslint-disable strict */
;(function ($) {
'use strict'
/**
* Add integers, wrapping at 2^32.
* This uses 16-bit operations internally to work around bugs in interpreters.
*
* @param {number} x First integer
* @param {number} y Second integer
* @returns {number} Sum
*/
function safeAdd(x, y) {
var lsw = (x & 0xffff) + (y & 0xffff)
var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
return (msw << 16) | (lsw & 0xffff)
}
/**
* Bitwise rotate a 32-bit number to the left.
*
* @param {number} num 32-bit number
* @param {number} cnt Rotation count
* @returns {number} Rotated number
*/
function bitRotateLeft(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt))
}
/**
* Basic operation the algorithm uses.
*
* @param {number} q q
* @param {number} a a
* @param {number} b b
* @param {number} x x
* @param {number} s s
* @param {number} t t
* @returns {number} Result
*/
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
}
/**
* Basic operation the algorithm uses.
*
* @param {number} a a
* @param {number} b b
* @param {number} c c
* @param {number} d d
* @param {number} x x
* @param {number} s s
* @param {number} t t
* @returns {number} Result
*/
function md5ff(a, b, c, d, x, s, t) {
return md5cmn((b & c) | (~b & d), a, b, x, s, t)
}
/**
* Basic operation the algorithm uses.
*
* @param {number} a a
* @param {number} b b
* @param {number} c c
* @param {number} d d
* @param {number} x x
* @param {number} s s
* @param {number} t t
* @returns {number} Result
*/
function md5gg(a, b, c, d, x, s, t) {
return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
}
/**
* Basic operation the algorithm uses.
*
* @param {number} a a
* @param {number} b b
* @param {number} c c
* @param {number} d d
* @param {number} x x
* @param {number} s s
* @param {number} t t
* @returns {number} Result
*/
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t)
}
/**
* Basic operation the algorithm uses.
*
* @param {number} a a
* @param {number} b b
* @param {number} c c
* @param {number} d d
* @param {number} x x
* @param {number} s s
* @param {number} t t
* @returns {number} Result
*/
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t)
}
/**
* Calculate the MD5 of an array of little-endian words, and a bit length.
*
* @param {Array} x Array of little-endian words
* @param {number} len Bit length
* @returns {Array<number>} MD5 Array
*/
function binlMD5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << len % 32
x[(((len + 64) >>> 9) << 4) + 14] = len
var i
var olda
var oldb
var oldc
var oldd
var a = 1732584193
var b = -271733879
var c = -1732584194
var d = 271733878
for (i = 0; i < x.length; i += 16) {
olda = a
oldb = b
oldc = c
oldd = d
a = md5ff(a, b, c, d, x[i], 7, -680876936)
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
b = md5gg(b, c, d, a, x[i], 20, -373897302)
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)
a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
d = md5hh(d, a, b, c, x[i], 11, -358537222)
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)
a = md5ii(a, b, c, d, x[i], 6, -198630844)
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)
a = safeAdd(a, olda)
b = safeAdd(b, oldb)
c = safeAdd(c, oldc)
d = safeAdd(d, oldd)
}
return [a, b, c, d]
}
/**
* Convert an array of little-endian words to a string
*
* @param {Array<number>} input MD5 Array
* @returns {string} MD5 string
*/
function binl2rstr(input) {
var i
var output = ''
var length32 = input.length * 32
for (i = 0; i < length32; i += 8) {
output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff)
}
return output
}
/**
* Convert a raw string to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*
* @param {string} input Raw input string
* @returns {Array<number>} Array of little-endian words
*/
function rstr2binl(input) {
var i
var output = []
output[(input.length >> 2) - 1] = undefined
for (i = 0; i < output.length; i += 1) {
output[i] = 0
}
var length8 = input.length * 8
for (i = 0; i < length8; i += 8) {
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32
}
return output
}
/**
* Calculate the MD5 of a raw string
*
* @param {string} s Input string
* @returns {string} Raw MD5 string
*/
function rstrMD5(s) {
return binl2rstr(binlMD5(rstr2binl(s), s.length * 8))
}
/**
* Calculates the HMAC-MD5 of a key and some data (raw strings)
*
* @param {string} key HMAC key
* @param {string} data Raw input string
* @returns {string} Raw MD5 string
*/
function rstrHMACMD5(key, data) {
var i
var bkey = rstr2binl(key)
var ipad = []
var opad = []
var hash
ipad[15] = opad[15] = undefined
if (bkey.length > 16) {
bkey = binlMD5(bkey, key.length * 8)
}
for (i = 0; i < 16; i += 1) {
ipad[i] = bkey[i] ^ 0x36363636
opad[i] = bkey[i] ^ 0x5c5c5c5c
}
hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8)
return binl2rstr(binlMD5(opad.concat(hash), 512 + 128))
}
/**
* Convert a raw string to a hex string
*
* @param {string} input Raw input string
* @returns {string} Hex encoded string
*/
function rstr2hex(input) {
var hexTab = '0123456789abcdef'
var output = ''
var x
var i
for (i = 0; i < input.length; i += 1) {
x = input.charCodeAt(i)
output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
}
return output
}
/**
* Encode a string as UTF-8
*
* @param {string} input Input string
* @returns {string} UTF8 string
*/
function str2rstrUTF8(input) {
return unescape(encodeURIComponent(input))
}
/**
* Encodes input string as raw MD5 string
*
* @param {string} s Input string
* @returns {string} Raw MD5 string
*/
function rawMD5(s) {
return rstrMD5(str2rstrUTF8(s))
}
/**
* Encodes input string as Hex encoded string
*
* @param {string} s Input string
* @returns {string} Hex encoded string
*/
function hexMD5(s) {
return rstr2hex(rawMD5(s))
}
/**
* Calculates the raw HMAC-MD5 for the given key and data
*
* @param {string} k HMAC key
* @param {string} d Input string
* @returns {string} Raw MD5 string
*/
function rawHMACMD5(k, d) {
return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))
}
/**
* Calculates the Hex encoded HMAC-MD5 for the given key and data
*
* @param {string} k HMAC key
* @param {string} d Input string
* @returns {string} Raw MD5 string
*/
function hexHMACMD5(k, d) {
return rstr2hex(rawHMACMD5(k, d))
}
/**
* Calculates MD5 value for a given string.
* If a key is provided, calculates the HMAC-MD5 value.
* Returns a Hex encoded string unless the raw argument is given.
*
* @param {string} string Input string
* @param {string} [key] HMAC key
* @param {boolean} [raw] Raw output switch
* @returns {string} MD5 output
*/
function md5(string, key, raw) {
if (!key) {
if (!raw) {
return hexMD5(string)
}
return rawMD5(string)
}
if (!raw) {
return hexHMACMD5(key, string)
}
return rawHMACMD5(key, string)
}
if (typeof define === 'function' && define.amd) {
define(function () {
return md5
})
} else if (typeof module === 'object' && module.exports) {
module.exports = md5
} else {
$.md5 = md5
}
})(this)

2
node_modules/blueimp-md5/js/md5.min.js generated vendored Normal file
View File

@ -0,0 +1,2 @@
!function(n){"use strict";function d(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function f(n,t,r,e,o,u){return d((u=d(d(t,n),d(e,u)))<<o|u>>>32-o,r)}function l(n,t,r,e,o,u,c){return f(t&r|~t&e,n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t&e|r&~e,n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function c(n,t){var r,e,o,u;n[t>>5]|=128<<t%32,n[14+(t+64>>>9<<4)]=t;for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h<n.length;h+=16)c=l(r=c,e=f,o=i,u=a,n[h],7,-680876936),a=l(a,c,f,i,n[h+1],12,-389564586),i=l(i,a,c,f,n[h+2],17,606105819),f=l(f,i,a,c,n[h+3],22,-1044525330),c=l(c,f,i,a,n[h+4],7,-176418897),a=l(a,c,f,i,n[h+5],12,1200080426),i=l(i,a,c,f,n[h+6],17,-1473231341),f=l(f,i,a,c,n[h+7],22,-45705983),c=l(c,f,i,a,n[h+8],7,1770035416),a=l(a,c,f,i,n[h+9],12,-1958414417),i=l(i,a,c,f,n[h+10],17,-42063),f=l(f,i,a,c,n[h+11],22,-1990404162),c=l(c,f,i,a,n[h+12],7,1804603682),a=l(a,c,f,i,n[h+13],12,-40341101),i=l(i,a,c,f,n[h+14],17,-1502002290),c=g(c,f=l(f,i,a,c,n[h+15],22,1236535329),i,a,n[h+1],5,-165796510),a=g(a,c,f,i,n[h+6],9,-1069501632),i=g(i,a,c,f,n[h+11],14,643717713),f=g(f,i,a,c,n[h],20,-373897302),c=g(c,f,i,a,n[h+5],5,-701558691),a=g(a,c,f,i,n[h+10],9,38016083),i=g(i,a,c,f,n[h+15],14,-660478335),f=g(f,i,a,c,n[h+4],20,-405537848),c=g(c,f,i,a,n[h+9],5,568446438),a=g(a,c,f,i,n[h+14],9,-1019803690),i=g(i,a,c,f,n[h+3],14,-187363961),f=g(f,i,a,c,n[h+8],20,1163531501),c=g(c,f,i,a,n[h+13],5,-1444681467),a=g(a,c,f,i,n[h+2],9,-51403784),i=g(i,a,c,f,n[h+7],14,1735328473),c=v(c,f=g(f,i,a,c,n[h+12],20,-1926607734),i,a,n[h+5],4,-378558),a=v(a,c,f,i,n[h+8],11,-2022574463),i=v(i,a,c,f,n[h+11],16,1839030562),f=v(f,i,a,c,n[h+14],23,-35309556),c=v(c,f,i,a,n[h+1],4,-1530992060),a=v(a,c,f,i,n[h+4],11,1272893353),i=v(i,a,c,f,n[h+7],16,-155497632),f=v(f,i,a,c,n[h+10],23,-1094730640),c=v(c,f,i,a,n[h+13],4,681279174),a=v(a,c,f,i,n[h],11,-358537222),i=v(i,a,c,f,n[h+3],16,-722521979),f=v(f,i,a,c,n[h+6],23,76029189),c=v(c,f,i,a,n[h+9],4,-640364487),a=v(a,c,f,i,n[h+12],11,-421815835),i=v(i,a,c,f,n[h+15],16,530742520),c=m(c,f=v(f,i,a,c,n[h+2],23,-995338651),i,a,n[h],6,-198630844),a=m(a,c,f,i,n[h+7],10,1126891415),i=m(i,a,c,f,n[h+14],15,-1416354905),f=m(f,i,a,c,n[h+5],21,-57434055),c=m(c,f,i,a,n[h+12],6,1700485571),a=m(a,c,f,i,n[h+3],10,-1894986606),i=m(i,a,c,f,n[h+10],15,-1051523),f=m(f,i,a,c,n[h+1],21,-2054922799),c=m(c,f,i,a,n[h+8],6,1873313359),a=m(a,c,f,i,n[h+15],10,-30611744),i=m(i,a,c,f,n[h+6],15,-1560198380),f=m(f,i,a,c,n[h+13],21,1309151649),c=m(c,f,i,a,n[h+4],6,-145523070),a=m(a,c,f,i,n[h+11],10,-1120210379),i=m(i,a,c,f,n[h+2],15,718787259),f=m(f,i,a,c,n[h+9],21,-343485551),c=d(c,r),f=d(f,e),i=d(i,o),a=d(a,u);return[c,f,i,a]}function i(n){for(var t="",r=32*n.length,e=0;e<r;e+=8)t+=String.fromCharCode(n[e>>5]>>>e%32&255);return t}function a(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e<t.length;e+=1)t[e]=0;for(var r=8*n.length,e=0;e<r;e+=8)t[e>>5]|=(255&n.charCodeAt(e/8))<<e%32;return t}function e(n){for(var t,r="0123456789abcdef",e="",o=0;o<n.length;o+=1)t=n.charCodeAt(o),e+=r.charAt(t>>>4&15)+r.charAt(15&t);return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return i(c(a(n=r(n)),8*n.length))}function u(n,t){return function(n,t){var r,e=a(n),o=[],u=[];for(o[15]=u[15]=void 0,16<e.length&&(e=c(e,8*n.length)),r=0;r<16;r+=1)o[r]=909522486^e[r],u[r]=1549556828^e[r];return t=c(o.concat(a(t)),512+8*t.length),i(c(u.concat(t),640))}(r(n),r(t))}function t(n,t,r){return t?r?u(t,n):e(u(t,n)):r?o(n):e(o(n))}"function"==typeof define&&define.amd?define(function(){return t}):"object"==typeof module&&module.exports?module.exports=t:n.md5=t}(this);
//# sourceMappingURL=md5.min.js.map

1
node_modules/blueimp-md5/js/md5.min.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

74
node_modules/blueimp-md5/package.json generated vendored Normal file
View File

@ -0,0 +1,74 @@
{
"name": "blueimp-md5",
"version": "2.19.0",
"title": "JavaScript MD5",
"description": "JavaScript MD5 implementation. Compatible with server-side environments like Node.js, module loaders like RequireJS, Browserify or webpack and all web browsers.",
"keywords": [
"javascript",
"md5"
],
"homepage": "https://github.com/blueimp/JavaScript-MD5",
"author": {
"name": "Sebastian Tschan",
"url": "https://blueimp.net"
},
"contributors": [
{
"name": "Paul Johnston",
"url": "http://pajhome.org.uk/crypt/md5"
}
],
"repository": {
"type": "git",
"url": "git://github.com/blueimp/JavaScript-MD5.git"
},
"license": "MIT",
"devDependencies": {
"chai": "4",
"eslint": "7",
"eslint-config-blueimp": "2",
"eslint-config-prettier": "8",
"eslint-plugin-jsdoc": "36",
"eslint-plugin-prettier": "4",
"mocha": "9",
"prettier": "2",
"uglify-js": "3"
},
"eslintConfig": {
"extends": [
"blueimp",
"plugin:jsdoc/recommended",
"plugin:prettier/recommended"
],
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": [
"js/*.min.js",
"test/vendor"
],
"prettier": {
"arrowParens": "avoid",
"proseWrap": "always",
"semi": false,
"singleQuote": true,
"trailingComma": "none"
},
"scripts": {
"lint": "eslint .",
"unit": "mocha",
"test": "npm run lint && npm run unit",
"prebuild": "bin/sync-vendor-libs.sh",
"build": "cd js && uglifyjs md5.js -c -m -o md5.min.js --source-map url=md5.min.js.map",
"preversion": "npm test",
"version": "npm run build && git add -A js",
"postversion": "git push --tags origin master master:gh-pages && npm publish"
},
"files": [
"js/*.js",
"js/*.js.map"
],
"main": "js/md5.js"
}

View File

@ -1,31 +0,0 @@
# Cordova sqlite storage dependencies
**AUTHOR:** Christopher J. Brody
**LICENSE:** MIT (for `sql-asm-memory-growth.js` built from fork of [`sql-js/sql.js`](https://github.com/sql-js/sql.js)); public domain for other artifacts
Contains source and object code built from:
- [`storesafe/sql.js`](https://github.com/storesafe/sql.js) - fork of [`sql-js/sql.js`](https://github.com/sql-js/sql.js) (MIT license)
- SQLite3 from [sqlite.org](http://sqlite.org/) (public domain)
- [`brodybits/android-sqlite-native-ndk-connector`](https://github.com/brodybits/android-sqlite-native-ndk-connector) (Unlicense, public domain)
- [`brodybits/android-sqlite-ndk-native-driver`](https://github.com/brodybits/android-sqlite-ndk-native-driver) (Unlicense, public domain)
This project provides the following dependencies needed to build [`storesafe/cordova-sqlite-storage`](https://github.com/storesafe/cordova-sqlite-storage):
- `sql-asm-memory-growth.js` - built from [`storesafe/sql.js`](https://github.com/storesafe/sql.js) (fork of [`sql-js/sql.js`](https://github.com/sql-js/sql.js)) with SQLite `3.22.3` for `browser` platform
- `sqlite3.h`, `sqlite3.c` - SQLite `3.40.0` amalgamation needed to build iOS, macOS, and Windows platforms
- `libs` - JAR libraries built from [`github:brodybits/android-sqlite-ndk-native-driver` - `sqlite-storage-ndk-native-driver` branch](https://github.com/brodybits/android-sqlite-ndk-native-driver/tree/sqlite-storage-ndk-native-driver) and [`brodybits/android-sqlite-native-ndk-connector`](https://github.com/brodybits/android-sqlite-native-ndk-connector), minimum API level 24 (Android 7.0), built with SQLite amalgamation, with the following flags:
- `-DSQLITE_THREADSAFE=1`
- `-DSQLITE_DEFAULT_SYNCHRONOUS=3`
- `-DSQLITE_DEFAULT_MEMSTATUS=0`
- `-DSQLITE_OMIT_DECLTYPE`
- `-DSQLITE_OMIT_DEPRECATED`
- `-DSQLITE_OMIT_PROGRESS_CALLBACK`
- `-DSQLITE_OMIT_SHARED_CACHE`
- `-DSQLITE_TEMP_STORE=2`
- `-DSQLITE_OMIT_LOAD_EXTENSION`
- `-DSQLITE_ENABLE_FTS3`
- `-DSQLITE_ENABLE_FTS3_PARENTHESIS`
- `-DSQLITE_ENABLE_FTS4`
- `-DSQLITE_ENABLE_RTREE`
- `-DSQLITE_DEFAULT_PAGE_SIZE=4096`
- `-DSQLITE_DEFAULT_CACHE_SIZE=-2000`

View File

@ -1,24 +0,0 @@
{
"name": "cordova-sqlite-storage-dependencies",
"version": "5.0.0",
"description": "Cordova sqlite storage dependencies",
"main": "404.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/brodybits/cordova-sqlite-storage-dependencies.git"
},
"keywords": [
"cordova",
"sqlite",
"amalgamation"
],
"author": "Christopher J. Brody",
"license": "MIT",
"bugs": {
"url": "https://github.com/litehelpers/Cordova-sqlite-storage-dependencies/issues"
},
"homepage": "https://github.com/litehelpers/Cordova-sqlite-storage-dependencies#readme"
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +0,0 @@
language: objective-c
env:
global:
- SPEC_WWW_DIR=${TRAVIS_BUILD_DIR}/spec/www
- TESTS_PATH=${TRAVIS_BUILD_DIR}/tests/tests.js
- CORDOVA_PARAMEDIC_CMD="cordova-paramedic --platform ios --plugin ${TRAVIS_BUILD_DIR} --timeout 3600000"
git:
depth: 2
node_js:
- "4.6"
install:
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- npm install -g cordova-paramedic
- npm install -g cordova
- npm install -g ios-sim
script:
- date && cordova-paramedic --platform ios --plugin ${TRAVIS_BUILD_DIR} || echo error-ignored
- date && cp ${SPEC_WWW_DIR}/spec/self-test.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date && cp ${SPEC_WWW_DIR}/spec/db-tx-string-test.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date && cp ${SPEC_WWW_DIR}/spec/db-tx-sql-select-value-test.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date && cp ${SPEC_WWW_DIR}/spec/basic-db-tx-sql-storage-results.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date && cp ${SPEC_WWW_DIR}/spec/db-sql-operations-test.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date && cp ${SPEC_WWW_DIR}/spec/sql-batch-test.js ${TESTS_PATH} && ${CORDOVA_PARAMEDIC_CMD}
- date

View File

@ -1,35 +0,0 @@
# Authors
## Common Javascript
- Extracted from DroidGap by @brodybits (Christopher J. Brody aka Chris Brody)
- Fail-safe nested transaction support by @ef4 (Edward Faulkner)
- Translated to Coffee-Script using js2coffee tool by @brodybits (Chris Brody)
- API changes by @brodybits (Chris Brody)
- Transaction timing fixes to support PouchDB by @nolanlawson
## browser platform
- Using sql-asm-memory-growth.js built from sql.js by @kripken (Alon Zakai)
## Android version
- Extracted from DroidGap by @brodybits (Chris Brody)
- Transaction batch processing of Android version by @marcucio
- Complex NDK response type enhancements to android-sqlite-native-ndk-connector and android-sqlite-ndk-native-driver by @luissilvaos (Luis Silva) of OutSystems
- Maintained by @brodybits (Chris Brody)
- Fixes to support old Android versions by @nolanlawson
- Thanks to Mark Oppenheim <mark.oppenheim@mnetics.co.uk> for fixes to open/close callbacks and repeated open/close/delete operations
## iOS/macOS version
- Original authors: @davibe (Davide Bertola <dade@dadeb.it>) and @joenoon (Joe Noon <joenoon@gmail.com>)
- Cordova 2.7+ port with background processing by @j3k0 (Jean-Christophe Hoelt <hoelt@fovea.cc>)
- Maintained by @brodybits (Chris Brody)
## Windows version
- SQLiteProxy.js by @vldmrrr (Vladimir Avdonin) and @brodybits (Chris Brody)
- Using SQLite3-WinRT C++ classes and SQLite3JS (Javascript part) by @doo (doo GmbH)
- Visual C++ build files for Windows 8.1, Windows Phone 8.1, and Windows 10 UWP by @brodybits (with some help from Visual Studio Express 2013)
- Thanks to @AllJoyn-Cordova for idea how to integrate Windows 8.1/Windows Phone 8.1 Visual C++ projects in plugin.xml

View File

@ -1,507 +0,0 @@
# Changes
#### cordova-sqlite-storage 7.0.0
- minimum Android API -> 24 (Android 7.0), with 16 KB page alignment update, from cordova-sqlite-storage-dependencies@5.0.0
#### cordova-sqlite-storage 6.1.0
- SQLite 3.40.0 update from cordova-sqlite-storage-dependencies@4.1.0
#### cordova-sqlite-storage 6.0.0
- use cordova-sqlite-storage-dependencies@4.0.0 with Android JARs built from android-sqlite-native-ndk-connector and android-sqlite-ndk-native-driver, with enhancements by Luis Silva of OutSystems needed for some Android 11 devices, drops support for Android pre-5.1
### cordova-sqlite-storage-commoncore 2.0.0
- refactor: clean up imports for Android
- Fix plugin param name for macOS ("osx") - *tested* with Cordova 9 and cordova-osx@5
- Drop support for Windows on ARM (Windows Mobile)
#### cordova-sqlite-storage 5.1.0
- Add browser platform support using sql-asm-memory-growth.js from sql.js, with some limitations as documented
#### cordova-sqlite-storage 5.0.1
- enable RENAME table with view test - from December 2019 SQLite crash report, fixed in 2020 ref:
- http://sqlite.1065341.n5.nabble.com/Crash-Bug-Report-tc109903.html
- https://github.com/xpbrew/cordova-sqlite-storage/issues/904
- SQLite 3.32.3 update from cordova-sqlite-storage-dependencies@2.1.2
#### cordova-sqlite-storage 5.0.0
- avoid incorrect default directory on iOS/macOS - to be extra safe (see <https://github.com/xpbrew/cordova-sqlite-storage/issues/907>)
- ensure that default "nosync" directory *always* has resource value set for `NSURLIsExcludedFromBackupKey`
- add more checks for missing database directory
#### cordova-sqlite-storage 4.0.0
- rename PSPDFThreadSafeMutableDictionary to CustomPSPDFThreadSafeMutableDictionary and completely remove PSPDFThreadSafeMutableDictionary.h
#### cordova-sqlite-storage 3.4.1
- SQLite 3.30.1 update from cordova-sqlite-storage-dependencies@2.1.1
#### cordova-sqlite-storage 3.4.0
- quick workaround for `SYNTAX_ERR` redefinition
#### cordova-sqlite-storage 3.3.0
- new default page & cache sizes with cordova-sqlite-storage-dependencies@2.1.0
##### cordova-sqlite-storage-commoncore 1.0.0
- additional EU string manipulation test cases
#### cordova-sqlite-storage 3.2.1
- cordova-sqlite-storage-dependencies@2.0.1 with SQLite 3.28.0 update for all supported platforms Android/iOS/macOS/Windows
#### cordova-sqlite-storage 3.2.0
- sqlite3_threadsafe() error handling on iOS/macOS
#### cordova-sqlite-storage 3.1.0
- no SQLITE_DEFAULT_CACHE_SIZE compile-time setting on iOS/macOS/Windows
#### cordova-sqlite-storage 3.0.0
- Use cordova-sqlite-storage-dependencies 2.0.0 with SQLITE_DBCONFIG_DEFENSIVE setting used by sqlite-native-driver.jar on Android
###### cordova-sqlite-ext-common-core 0.2.0
- Move SQLite3.UWP.vcxproj out of extra SQLite3.UWP subdirectory
- Completely remove old Windows 8.1 & Windows Phone 8.1 vcxproj files
###### cordova-sqlite-extcore 0.1.0
- move the embedded `SQLite3-WinRT` component to `src/windows/SQLite3-WinRT-sync` and update `plugin.xml`
##### cordova-sqlite-ext-common-core 0.1.0
###### cordova-sqlite-ext-core-common 0.1.0
- beforePluginInstall.js updates
- use standard Promise
- get the plugin package name from package.json
- use const instead of var (this should be considered a POSSIBLY BREAKING CHANGE since const may not work on some really old Node.js versions)
- remove hasbang line that is not needed
###### cordova-sqlite-storage-ext-core-common 2.0.0
- SQLITE_DBCONFIG_DEFENSIVE flag - iOS/macOS/Windows (POTENTIALLY BREAKING CHANGE)
- remove internal qid usage from JavaScript (not needed)
- non-static Android database runner map (POTENTIALLY BREAKING CHANGE)
- Completely remove old Android SuppressLint (android.annotation.SuppressLint) - POSSIBLY BREAKING CHANGE
- drop workaround for pre-Honeycomb Android API (BREAKING CHANGE)
- no extra @synchronized block per batch (iOS/macOS) - should be considered a POSSIBLY BREAKING change
- remove backgroundExecuteSql method not needed (iOS/macOS)
- Completely remove iOS/macOS MRC (Manual Reference Counting) support - should be considered a POSSIBLY BREAKING change
### cordova-sqlite-storage 2.6.0
- Use cordova-sqlite-storage-dependencies 1.2.1 with SQLite 3.26.0, with a security update and support for window functions
### cordova-sqlite-storage 2.5.2
- Ignore Android end transaction error when closing for androidDatabaseProvider: 'system' setting, to avoid possible crash during app shutdown (<https://github.com/litehelpers/Cordova-sqlite-storage/issues/833>)
### cordova-sqlite-storage 2.5.1
- fix internal plugin cleanup error log on Android
### cordova-sqlite-storage 2.5.0
- androidDatabaseProvider: 'system' setting, to replace androidDatabaseImplementation setting which is now deprecated
### cordova-sqlite-storage 2.4.0
- Report internal plugin error in case of attempt to open database with no database name on iOS or macOS
- Cover use of standard (WebKit) Web SQL API in spec test suite
- Test and document insertId in UPDATE result set on plugin vs (WebKit) Web SQL
- other test updates
### cordova-sqlite-storage 2.3.3
- Quick fix for some iOS/macOS internal plugin error log messagess
- test updates
- quick doc updates
### cordova-sqlite-storage 2.3.2
- Mark some Android errors as internal plugin errors (quick fix)
- remove trailing whitespace from Android implementation
- test coverage updates
- quick doc updates
### cordova-sqlite-storage 2.3.1
- Mark some iOS/macOS plugin error messages as internal plugin errors (quick fix)
- Quick documentation updates
### cordova-sqlite-storage 2.3.0
- Use SQLite 3.22.0 with SQLITE_DEFAULT_SYNCHRONOUS=3 (EXTRA DURABLE) compile-time setting on all platforms (Android/iOS/macOS/Windows) ref: litehelpers/Cordova-sqlite-storage#736
### cordova-sqlite-storage 2.2.1
- SQLITE_THREADSAFE=1 compile-time setting for iOS/macOS
- Fix Android/iOS src copyright, perpetually
## cordova-sqlite-storage 2.2.0
- Android-sqlite-native-driver NDK objects in JAR to resolve issue on cordova-android@7
- Fix SQLiteAndroidDatabase implementation for Turkish and other foreign locales
## cordova-sqlite-storage 2.1.5
##### cordova-sqlite-legacy-core 1.0.7
- Add error info text in case of close error on Windows
- Signal INTERNAL ERROR in case of attempt to reuse db on Windows (should never happen due to workaround solution to BUG 666)
- SQLITE_DEFAULT_CACHE_SIZE build flag fix for macOS ("osx") and Windows
###### cordova-sqlite-legacy-express-core 1.0.5
- iOS/macOS @synchronized guard for sqlite3_open operation
- Signal INTERNAL ERROR in case of attempt to reuse db (Android/iOS) (should never happen due to workaround solution to BUG 666)
## cordova-sqlite-storage 2.1.4
##### cordova-sqlite-legacy-core 1.0.6
###### cordova-sqlite-legacy-express-core 1.0.4
- Cleaned up workaround solution to BUG 666: close db before opening (ignore close error)
- android.database end transaction if active before closing (needed for new BUG 666 workaround solution to pass selfTest in case of builtin android.database implementation)
## cordova-sqlite-storage 2.1.3
##### cordova-sqlite-legacy-core 1.0.5
###### cordova-sqlite-legacy-express-core 1.0.3
- Resolve Java 6/7/8 concurrent map compatibility issue reported in litehelpers/Cordova-sqlite-storage#726, THANKS to pointer by @NeoLSN (Jason Yang/楊朝傑) in litehelpers/Cordova-sqlite-storage#727.
- selfTest database cleanup do not ignore close or delete error on any platforms
## cordova-sqlite-storage 2.1.2
##### cordova-sqlite-legacy-core 1.0.4
- New workaround solution to BUG 666: close db before opening (ignore close error)
## cordova-sqlite-storage 2.1.1
##### cordova-sqlite-legacy-core 1.0.3
- Suppress warnings when building sqlite3.c & PSPDFThreadSafeMutableDictionary.m on iOS/macOS
##### cordova-sqlite-legacy-core 1.0.2
- Fix log in case of transaction waiting for open to finish; doc fixes
- SQLite 3.15.2 build with SQLITE_THREADSAFE=2 on iOS/macOS (SQLITE_THREADSAFE=1 on Android/Windows) and other flag fixes in this version branch to avoid possible malformed database due to multithreaded access ref: litehelpers/Cordova-sqlite-storage#703
- Windows 10 (UWP) build with /SAFESEH flag on Win32 (x86) target
###### cordova-sqlite-legacy-express-core 1.0.2
- Use PSPDFThreadSafeMutableDictionary for iOS/macOS to avoid threading issue ref: litehelpers/Cordova-sqlite-storage#716
###### cordova-sqlite-legacy-express-core 1.0.1
- Fix bug 666 workaround to trigger ROLLBACK in the next event tick (needed to support version with pre-populated database on Windows)
## cordova-sqlite-storage 2.1.0
- Visual Studio 2017 updates for Windows UWP build
## cordova-sqlite-storage 2.0.4
###### cordova-sqlite-legacy-express-core 1.0.0
- Workaround solution to BUG litehelpers/Cordova-sqlite-storage#666 (hanging transaction in case of location reload/change)
- selfTest simulate scenario & test solution to BUG litehelpers/Cordova-sqlite-storage#666 (also includes string test and test of effects of location reload/change in this version branch, along with another internal check)
## cordova-sqlite-storage 2.0.3
- Drop engines rule from package.json
- Doc fixes
### cordova-sqlite-storage 1.5.4
- Fix iOS/macOS version to report undefined insertId in case INSERT OR IGNORE is ignored
- Fix FIRST_WORD check for android.sqlite.database implementation
- SQLite 3.15.2 build fixes
- Doc updates
## cordova-sqlite-storage 2.0.2
- Fix Windows target platform version
### cordova-sqlite-storage 1.5.3
- Fix merges to prevent possible conflicts with other plugins (Windows)
- Fix handling of undefined SQL argument values (Windows)
- Signal error in case of a failure opening the database file (iOS/macOS)
- Doc fixes and updates
## cordova-sqlite-storage 2.0.1
### cordova-sqlite-storage 1.5.2
- Build with sqlite 3.15.2 with the following settings in this version branch:
- SQLITE_TEMP_STORE=2
- SQLITE_THREADSAFE=1
- SQLITE_ENABLE_FTS3
- SQLITE_ENABLE_FTS3_PARENTHESIS
- SQLITE_ENABLE_FTS4
- SQLITE_ENABLE_RTREE
- SQLITE_OMIT_BUILTIN_TEST
- SQLITE_OMIT_LOAD_EXTENSION
- SQLITE_DEFAULT_PAGE_SIZE=1024 and SQLITE_DEFAULT_CACHE_SIZE=2000 to avoid "potentially distruptive change(s)" from SQLite 3.12.0 ref: <http://sqlite.org/pgszchng2016.html>
- SQLITE_OS_WINRT for Windows only
- Check transaction callback functions to avoid crash on Windows
- Fix echoTest callback handling
- Fix openDatabase/deleteDatabase exception messages
- Move Lawnchair adapter to a separate project
- Doc updates
### cordova-sqlite-storage 2.0.0
- Reference Windows platform toolset v141 to support Visual Studio 2017 (RC)
### cordova-sqlite-storage 1.5.1
- Add engines rule to package.json to specify plugin version >= 2.0.0 in case of cordova-windows 4.4.2 or newer for Visual Studio 2017 (Preview)
### cordova-sqlite-storage 1.5.0
- Build with sqlite 3.15.1, with the following settings:
- SQLITE_TEMP_STORE=2
- SQLITE_THREADSAFE=2
- FTS3, FTS4, and R-Tree enabled
- SQLITE_DEFAULT_PAGE_SIZE=1024 and SQLITE_DEFAULT_CACHE_SIZE=2000 to avoid "potentially distruptive change(s)" from SQLite 3.12.0 ref: <http://sqlite.org/pgszchng2016.html>
- Drop support for Windows 8.1 & Windows Phone 8.1
### cordova-sqlite-storage 1.4.9
- Minor JavaScript fix (generated by CoffeeScript 1.11.1)
- Update test due to issue with u2028/u2029 on cordova-android 6.0.0
- doc fixes
- Cleanup plugin.xml: remove old engine constraint that was already commented out
- Fix LICENSE.md
### cordova-sqlite-storage 1.4.8
- selfTest function add string test and test of effects of location reload/change
- Support macOS ("osx" platform)
- Signal an error in case of SQL with too many parameter argument values on iOS (in addition to Android & Windows)
- Include proper SQL error code on Android (in certain cases)
- Fix reporting of SQL statement execution errors in Windows version
- Fix Windows version to report errors with a valid error code (0)
- Some doc fixes
### cordova-sqlite-storage 1.4.7
- Minor JavaScript fixes to pass @brodybits/Cordova-sql-test-app
### cordova-sqlite-storage 1.4.6
- Stop remaining transaction callback in case of an error with no error handler returning false
- Expand selfTest function to cover CRUD with unique record keys
- Fix readTransaction to reject ALTER, REINDEX, and REPLACE operations
- Fix Windows 10 ARM Release Build of SQLite3 by disabling SDL check (ARM Release only)
- Fix Windows 8.1/Windows Phone 8.1 Release Build of SQLite3 by disabling SDL check
- Some documentation fixes
### cordova-sqlite-storage 1.4.5
- Log/error message fixes; remove extra qid from internal JSON interface
### cordova-sqlite-storage 1.4.4
- Fix readTransaction to reject modification statements with extra semicolon(s) in the beginning
- Announce new Cordova-sqlite-evcore-extbuild-free version
- Additional tests
- Other doc fixes
### cordova-sqlite-storage 1.4.3
- Handle executeSql with object sql value (solves another possible crash on iOS)
### cordova-sqlite-storage 1.4.2
- Fix sqlitePlugin.openDatabase and sqlitePlugin.deleteDatabase to check location/iosDatabaseLocation values
- Fix sqlitePlugin.deleteDatabase to check that db name is really a string (prevents possible crash on iOS)
- Fix iOS version to use DLog macro to remove extra logging from release build
- Fix Lawnchair adapter to use new mandatory "location" parameter
- Remove special handling of Blob parameters, use toString for all non-value parameter objects
- Minor cleanup of Android version code
### cordova-sqlite-storage 1.4.1
- Minimum Cordova version no longer enforced in this version
### cordova-sqlite-storage 1.4.0
- Now using cordova-sqlite-storage-dependencies for SQLite 3.8.10.2 Android/iOS/Windows
- Android-sqlite-connector implementation supported by this version again
- Enforce minimum cordova-windows version (should be OK in Cordova 6.x)
- Support Windows 10 along with Windows 8.1/Windows Phone 8.1
### cordova-sqlite-storage 1.2.2
- Self-test function to verify ability to open/populate/read/delete a test database
- Read BLOB as Base-64 DISABLED in Android version (was already disabled for iOS)
### cordova-sqlite-storage 1.2.1
- Close Android SQLiteStatement after INSERT/UPDATE/DELETE
- Specify minimum Cordova version 6.0.0
- Lawnchair adapter fix: Changed remove method to work with key array
### cordova-sqlite-storage 1.2.0
- Rename Lawnchair adapter to prevent clash with standard webkit-sqlite adapter
- Support location: 'default' setting in openDatabase & deleteDatabase
### cordova-sqlite-storage 0.8.5
- More explicit iosDatabaseLocation option
- iOS database location is now mandatory
- Split-up of some more spec test scripts
### cordova-sqlite-storage 0.8.2
- Workaround fix for empty readTransaction issue (litehelpers/Cordova-sqlite-storage#409)
- Split spec/www/spec/legacy.js into db-open-close-delete-test.js & tx-extended.js
### cordova-sqlite-storage 0.8.0
- Simple sql batch transaction function
- Echo test function
- All iOS operations are now using background processing (reported to resolve intermittent problems with cordova-ios@4.0.1)
- Java source of Android version now using io.sqlc package
- Drop Android-sqlite-connector support
- Drop WP(8) and Windows support
### 0.7.14
- REGEXP support completely removed from this version branch
- Remove src/android/libs/.gitignore (inadvertently added in 0.7.13)
### 0.7.13
- REGEXP support partially removed from this version branch
- Rename Windows C++ Database close function to closedb to resolve conflict for Windows Store certification
- Android version with sqlite `3.8.10.2` embedded (with error messages fixed)
- Pre-populated database support removed from this version branch
- Amazon Fire-OS support removed
- Fix conversion warnings in iOS version
### 0.7.12
- Fix to Windows "Universal" version to support big integers
- Implement database close and delete operations for Windows "Universal"
- Fix readTransaction to skip BEGIN/COMMIT/ROLLBACK
### 0.7.11
- Fix plugin ID in plugin.xml to match npm package ID
- Unpacked sqlite-native-driver.so libraries from jar
- Fix conversion of INTEGER type (iOS version)
- Disable code to read BLOB as Base-64 (iOS version) due to https://issues.apache.org/jira/browse/CB-9638
### 0.7.10
- Use Android-sqlite-connector instead of sqlite4java
### 0.7.9
- Build iOS and Windows versions with sqlite 3.8.10.2 embedded
- Fix plugin id to match npm package id
### 0.7.8
- Support FTS3/FTS4 and R-Tree in iOS and Windows "Universal" (8.1) versions
- Build ARM target with Function Level Linking ref: http://www.monkey-x.com/Community/posts.php?topic=7739
- SQLite3.Windows.vcxproj and SQLite3.WindowsPhone.vcxproj in their own directories to avoid problems due to temporary files
### 0.7.7
- include build of sqlite4java for Android x86_64 and arm-64
- clean publish to plugins.cordova.io
### 0.7.6
- Small fix to plugin id
- Disable use of gethostuuid() in sqlite3.c (only used in iOS version)
- published to plugins.cordova.io - [BUG] published extra junk in workarea, causing problems with Windows (Universal) version
### 0.7.5
- Windows (Universal) version now supports both Windows 8.1 and Windows Phone 8.1
- iOS and Windows versions are now built with sqlite 3.8.9 embedded
- Improved locking style and other optimizations applied for iOS version
### 0.7.4
- iOS and Windows (8.1) versions built to keep non-essential temporary sqlite files in memory
- Option to use legacy Android database library, with Android locking/closing issue (BUG #193) workaround included again
### 0.7.3
- insertId & rowsAffected implemented for Windows (8.1)
- plugin id changed
### 0.7.2
- Android version with sqlite4java (sqlite 3.8.7 embedded), which solves BUG #193: Android closing/locking issue (ICU-UNICODE integration is now missing)
- iOS version fixed to override the correct pluginInitialize method and built with sqlite 3.8.8.3 embedded
### 0.7.1
- Project renamed
- Initial version for Windows (8.1) [with sqlite 3.8.8.3 embedded]
- Abort initially pending transactions for db handle (due to incorrect password key, for example) [from Cordova-sqlcipher-storage]
- WP7 build enabled (NOT TESTED)
### 1.0.6
- Proper handling of transactions that may be requested before the database open operation is completed
- Report an error upon attempt to close a database handle object multiple times.
### 1.0.5
- Workaround for Android db locking/closing issue
- Fix double-precision REAL values in result (iOS version)
- Fix query result truncation in case of NULL character (\0 or \u0000) (iOS version)
- Convert array SQL parameters to string, according to match Web SQL spec
- Fix closing of Android database
- Some fixes for SQL API error handling to be consistent with Web SQL
### 1.0.4
- Pre-populated database option (Android/iOS)
- Option to select database location to disable iCloud backup (iOS ONLY)
- Safeguard against closing of database while transaction is pending
- Fix to prevent double marshaling of data
### 1.0.3
- Fixed issue with multi-page apps on Android (due to problem when closing & re-opening app)
### 1.0.2
- Workaround for issue with multiple UPDATE statements WP(8) (#128)
### 1.0.1
- Support Cordova 3.3.0/3.4.0 to support Amazon-FireOS
- Fixes for WP(8):
- use one thread per db to solve open/close/delete issues
- fix integer data binding
- Fix open/close callbacks Android & WP(8)
- Resolve issue with INSERT OR IGNORE (Android)

View File

@ -1,33 +0,0 @@
# General
**IMPORTANT:** Please raise general questions in [litehelpers / Cordova-sqlite-help / issues](https://github.com/litehelpers/Cordova-sqlite-help/issues).
## Reproducible bugs
- Verify the results of calling the echoTest and selfTest functions as described in README.md
- Check the pitfalls and other troubleshooting steps in README.md and [brodybits / Avoiding-some-Cordova-pitfalls](https://github.com/brodybits/Avoiding-some-Cordova-pitfalls)
- Reproduce the issue in a fresh, clean project, preferably based on [brodybits / Cordova-sqlite-bootstrap-test](https://github.com/brodybits/Cordova-sqlite-bootstrap-test) or [brodybits / cordova-sqlite-test-app](https://github.com/brodybits/cordova-sqlite-test-app).
Please see README.md for more details.
## Feature requests
Feature requests are welcome for community discussion and future consideration. Preference will be given to paid customers. Please contact <sales@litehelpers.net> for more information.
## Other questions
**NOTE:** As stated above please other questions in [litehelpers / Cordova-sqlite-help / issues](https://github.com/litehelpers/Cordova-sqlite-help/issues).
## Contributing patches
- Patches with bug fixes are helpful, especially when submitted with test code.
- Other enhancements are welcome for consideration, when submitted with test code and are working for all supported platforms. Increase of complexity should be avoided.
- All contributions may be reused by [@brodybits](https://github.com/brodybits) under another license in the future. Efforts will be taken to give credit for major contributions but it will not be guaranteed.
- Project restructuring, i.e. moving files and/or directories around, should be avoided if possible.
Please see README.md for more details.
## Other
- Testimonials of apps that are using this plugin would be especially helpful.
- Reporting issues can help improve the quality of this plugin.

View File

@ -1,143 +0,0 @@
# History
## Overall
@brodybits (Christopher J. Brody aka Chris Brody) assembled the project in April 2012
from the following parts:
- DroidGap SQLite Storage Java and Javascript parts
- Phonegap-SQLitePlugin for iOS by @davibe (Davide Bertola <dade@dadeb.it>) and
@joenoon (Joe Noon <joenoon@gmail.com>)
@brodybits has been maintaining this project with a number of bug fixes and other improvements.
A number of contributions have been integrated. The most important contributors are explicitly
mentioned in AUTHORS.md.
## 2009-2010
DroidGap Storage Java and Javascript parts were initially added in December 2009.
## 2011
Phonegap-SQLitePlugin for iOS was started by @davibe in June 2011.
In September 2011 @joenoon rewrote the Javascript (using CoffeeScript) and added a
Lawnchair adapter.
## 2012
The original Phonegap-SQLitePlugin for iOS had a major deviation from the Web SQL API draft.
While the Web SQL API draft keeps the sql and the parameters array as separate parameters,
the original Phonegap-SQLitePlugin combined the sql and parameters in a single array.
This project as assembled by @brodybits keeps the sql and parameters array as separate
parameters to follow the Web SQL API draft more closely.
@marcucio (Mike Arcucio) contributed a major rework of the Android version to support
efficient batch processing.
For the first year the Javascript part was completely different for the iOS and
Android versions. @brodybits introduced a QUnit test suite, with some help from
the Lawnchair QUnit test suite as well as the usage sample by @joenoon and @davibe.
In October 2012 @ef4 (Edward Faulkner) reworked the Javascript for the iOS version
to implement the Web SQL failure-safe transaction semantics, along with some tests.
In December 2012 @brodybits split the project into separate Android and iOS parts
(merged back together in September 2013).
In December 2012 @marcucio (Mike Arcucio) made a WP8 version using CSharp-SQLite.
## 2013
In May 2013 @j3k0 (Jean-Christophe Hoelt <hoelt@fovea.cc>) contributed major changes
to the iOS version to work in Cordova 2.7 and support background processing.
In July 2013 @brodybits updated the Android version to use one background thread
per database and ported the failure-safe transaction semantics to work in the
Android version (with the help of CoffeeScript).
In August 2013 @brodybits fixed the iOS version to work with the Javascript from
the Android version.
In September 2013 @brodybits merged the Android version and iOS version to use the
same Javascript interface.
In September 2013 @brodybits published a fork of the WP8 version with a version
of the CSharp-SQLite source embedded.
Merge notes: The merged version from September 2013 has some of the early commits
repeated in history. This is because @brodybits removed the iOS sources from the
old Android version using the git filter-branch command.
## 2014
In July 2014 @Gillardo (Darren Gillard <darren.gillard81@gmail.com>) contributed an integration
of the WP8 version with background processing and improved transaction support.
Also in July 2014 @nolanlawson contributed a number of fixes and got this project
working with PouchDB. For example: introduction of nextTick to schedule actions to be taken
once the current HTML(5) event handler is finished.
In August 2014 Mark Oppenheim (<mark.oppenheim@mnetics.co.uk>) contributed the following:
- working open/close callbacks and repeated open/close/delete fixes for Android and WP8 versions
(@brodybits fixed these for the iOS version);
- fixed WP8 version to use one thread per database.
NOTE: The WP8 version is currently supported in the Cordova-sqlite-legacy version.
## 2015
In January 2015 @aarononeal (Aaron Oneal <aaron.oneal@spicypixel.com>) raised PR #170 with a
number of fixes, including:
- Fix to prevent double marshaling of data.
- Fix test runner to use correct plugin id (subsequently broken by @brodybits).
- Fix database close conditions and unit test (reject attempt to close database
the middle of a transaction).
- Propagate statement failures to transaction failures (in the case when a
statement error handler does not return false).
- Fix transaction and statement errors to conform to SQLError.
- Fix warning regarding test runner viewport format.
- Fix executeSql to throw on finalized transactions.
- Reproduce & fix truncation in iOS query result string encoding
(in case of UNICODE \u0000 character in the middle).
In addition, PR #170 includes a two-way SQL blob marshalling mechanism that is still under
consideration.
Other major changes by @brodybits in 2015:
- Porting of the existing test suite to work within the Jasmine framework.
- Introduction of workaround for Android locking bug.
- Introduction of Windows target version (Windows 8.0/Windows 8.1/Windows Phone 8.1),
which is now available in cordova-sqlite-ext and Cordova-sqlite-legacy version projects.
- Introduction of lightweight Android-sqlite-connector database library, which is
now available in cordova-sqlite-ext and Cordova-sqlite-legacy version projects.
- Use of Circle CI (Android version) and Travis CI (iOS version).
- Introduction of other version projects:
- Cordova-sqlcipher-adapter
- cordova-sqlite-ext with REGEXP and pre-populated database support
- Enterprise version with memory fix and other enhancements,
available under GPL or commercial licensing options
- react-native-sqlite-storage version for Android and iOS developed and maintained
by @andpor (Andrzej Porebski <fkuciapa@yahoo.com>), based on this project
## Major changes 2016
New features:
- Echo self-test function
- Simple sql batch query interface
Installation changes
- Use of `before_plugin_install` hook to install external dependencies
New versions introduced
- Cordova-sqlite-evcore-extbuild-free with major performance and memory fixes for Android,
available under GPL or commercial licensing options with support for PhoneGap Build
- Cordova-sqlite-evplus (legacy) versions with GPL or premium commercial licensing options
## Major changes 2017
Windows platform toolset dependency updated for Visual Studio 2017
## Recent changes
See CHANGES.md

View File

@ -1,49 +0,0 @@
# Licenses
## Common Javascript
MIT or Apache 2.0
## for browser platform
MIT or Apache 2.0
### sql.js
MIT
## for Android
MIT or Apache 2.0
### android-sqlite-native-ndk-connector
Unlicense (public domain)
### android-sqlite-ndk-native-driver
Unlicense (public domain)
## for iOS & macOS
MIT only
based on Phonegap-SQLitePlugin by @davibe (Davide Bertola <dade@dadeb.it>) and @joenoon (Joe Noon <joenoon@gmail.com>)
includes and uses PSPDFThreadSafeMutableDictionary (PSPDFThreadSafeMutableDictionary.m <https://gist.github.com/steipete/5928916>) MIT license by @steipete (<https://gist.github.com/steipete>)
## for Windows
MIT or Apache 2.0
### SQLite3-WinRT
by @doo (doo GmbH)
MIT License
## Common native code
### SQLite3
Public domain

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +0,0 @@
# Automated cordova tests. Installs the correct cordova platform,
# installs the plugin, installs the test app, and then runs it on
# a device or emulator.
#
# usage: .\bin\test.ps1 [android|ios|windows|wp8]
#
# N.B. if you functionally change this script you _must_ change .\bin\test.sh too.
#
# STATUS: UNSUPPORTED
#
# A known issue is that this script needs old coffeescript@1 or coffee-script@1
# to be installed globally while the package script is using locally installed
# version of coffeescript@1.
#
# It is recommended to use the package scripts with npm or yarn tool instead
# of this script.
#
param([string]$platform)
if (! $platform) {
echo "usage: .\bin\test.sh [android|ios|windows|wp8]"
exit 1
}
if (! (get-command coffee) ) {
echo "you need coffeescript. please install with:"
echo "npm install -g coffee-script"
exit 1
}
if (! (get-command cordova) ) {
echo "you need cordova. please install with:"
echo "npm install -g cordova"
exit 1
}
pushd spec
if (!$?) { # run from the bin/ directory
echo "re-pushing"
pushd ../spec
}
try {
# compile coffeescript
coffee --no-header -cl -o ../www ../SQLitePlugin.coffee.md
if (!$?) {
echo "coffeescript compilation failed"
exit 1
}
echo "compiled coffeescript to javascript"
# move everything to a temp folder to avoid infinite recursion errors
if (test-path ../.plugin) {
rm -force -recurse ../.plugin -ErrorAction ignore
}
mkdir -ErrorAction ignore ../.plugin | out-null
cp -recurse ../scripts, ../src, ../package.json, ../plugin.xml, ../www ../.plugin
# update the plugin, run the test app
cordova platform add $platform
cordova plugin rm com.phonegap.plugins.sqlite
cordova plugin add ../.plugin
cordova run $platform
} finally {
popd
}

View File

@ -1,66 +0,0 @@
#!/bin/bash
#
# Automated cordova tests. Installs the correct cordova platform,
# installs the plugin, installs the test app, and then runs it on
# a device or emulator.
#
# usage: ./bin/test.sh [android|ios]
#
# N.B. if you functionally change this script you _must_ change .\bin\test.sh too.
#
# STATUS: UNSUPPORTED
#
# A known issue is that this script needs old coffeescript@1 or coffee-script@1
# to be installed globally while the package script is using locally installed
# version of coffeescript@1.
#
# It is recommended to use the package scripts with npm or yarn tool instead
# of this script.
#
platform=$1
if [[ -z $platform ]]; then
echo "usage: ./bin/test.sh [android|ios]"
exit 1
fi
if [[ ! -x $(which coffee) ]]; then
echo "you need coffeescript. please install with:"
echo "npm install -g coffee-script"
exit 1
fi
if [[ ! -x $(which cordova) ]]; then
echo "you need cordova. please install with:"
echo "npm install -g cordova"
exit 1
fi
cd spec
if [[ $? != 0 ]]; then # run from the bin/ directory
cd ../spec
fi
# compile coffeescript
coffee --no-header -cl -o ../www ../SQLitePlugin.coffee.md
if [[ $? != 0 ]]; then
echo "coffeescript compilation failed"
exit 1
fi
echo "compiled coffeescript to javascript"
# move everything to a temp folder to avoid infinite recursion errors
rm -fr myplugin
mkdir -p myplugin
cp -r ../scripts ../src ../plugin.xml ../package.json ../www myplugin
# cleanup old test
rm -fr plugins platforms
# update the plugin, run the test app
cordova platform add $platform
#cordova plugin rm com.brodysoft.sqlitePlugin
cordova plugin add myplugin
cordova run $platform

View File

@ -1,28 +0,0 @@
machine:
environment:
ANDROID_NDK_HOME: $ANDROID_NDK
SPEC_ROOT: spec/www
TESTS_PATH: tests/tests.js
CORDOVA_PARAMEDIC_CMD: cordova-paramedic --platform android --plugin . --timeout 3600000
dependencies:
pre:
- npm install -g cordova-paramedic
- npm install -g cordova
test:
pre:
- emulator -avd circleci-android21 -no-audio -no-window:
background: true
parallel: true
- circle-android wait-for-boot
override:
- cordova-paramedic --platform android --plugin . || echo error-ignored
- cp $SPEC_ROOT/spec/self-test.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD
- cp $SPEC_ROOT/spec/db-tx-string-test.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD
- cp $SPEC_ROOT/spec/db-tx-sql-select-value-test.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD
- cp $SPEC_ROOT/spec/basic-db-tx-sql-storage-results.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD
- cp $SPEC_ROOT/spec/db-sql-operations-test.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD
- cp $SPEC_ROOT/spec/sql-batch-test.js $TESTS_PATH && $CORDOVA_PARAMEDIC_CMD

View File

@ -1,48 +0,0 @@
{
"name": "cordova-sqlite-storage",
"version": "7.0.0",
"description": "Native interface to SQLite for PhoneGap / Cordova - cordova-sqlite-storage plugin version",
"cordova": {
"id": "cordova-sqlite-storage",
"platforms": [
"android",
"browser",
"ios",
"osx",
"windows"
]
},
"repository": {
"type": "git",
"url": "https://github.com/xpbrew/cordova-sqlite-storage.git"
},
"keywords": [
"sqlite",
"ecosystem:cordova",
"cordova-android",
"cordova-browser",
"cordova-ios",
"cordova-osx",
"cordova-windows"
],
"author": "various",
"license": "MIT",
"bugs": {
"url": "https://github.com/xpbrew/cordova-sqlite-storage/issues"
},
"homepage": "https://github.com/xpbrew/cordova-sqlite-storage",
"dependencies": {
"cordova-sqlite-storage-dependencies": "5.0.0"
},
"scripts": {
"clean-spec": "rimraf spec/[mnp]* && git checkout -- spec/config.xml spec/package.json && git status --ignored",
"prepare-js": "coffee -p SQLitePlugin.coffee.md > www/SQLitePlugin.js",
"prepare-spec": "node scripts/prepareSpec.js"
},
"devDependencies": {
"coffeescript": "1",
"cross-spawn": "^6.0.5",
"fs-extra": "^8.1.0",
"rimraf": "^3.0.2"
}
}

View File

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-sqlite-storage"
version="7.0.0">
<name>Cordova SQLite storage plugin - cordova-sqlite-storage plugin version</name>
<license>MIT</license>
<keywords>sqlite</keywords>
<description>Native interface to SQLite for PhoneGap/Cordova. Allows you to use more storage and provides more flexibility than the standard Web SQL database (window.openDatabase).</description>
<author>Litehelpers/Various</author>
<!-- THANKS to AllJoyn-Cordova / cordova-plugin-alljoyn: -->
<hook type="before_plugin_install" src="scripts/beforePluginInstall.js" />
<js-module src="www/SQLitePlugin.js" name="SQLitePlugin">
<clobbers target="SQLitePlugin" />
</js-module>
<platform name="browser">
<!-- sql-asm js item must come before SQLiteProxy for SQLiteProxy.js to work on browser -->
<js-module src="node_modules/cordova-sqlite-storage-dependencies/sql-asm-memory-growth.js" name="sql">
<runs />
</js-module>
<js-module src="src/browser/SQLiteProxy.js" name="SQLiteProxy">
<runs />
</js-module>
</platform>
<!-- android -->
<platform name="android">
<!-- Cordova >= 3.0.0 -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="SQLitePlugin">
<param name="android-package" value="io.sqlc.SQLitePlugin"/>
</feature>
</config-file>
<source-file src="src/android/io/sqlc/SQLitePlugin.java" target-dir="src/io/sqlc"/>
<source-file src="src/android/io/sqlc/SQLiteAndroidDatabase.java" target-dir="src/io/sqlc"/>
<source-file src="src/android/io/sqlc/SQLiteConnectorDatabase.java" target-dir="src/io/sqlc"/>
<lib-file src="node_modules/cordova-sqlite-storage-dependencies/libs/sqlite-native-ndk-connector.jar" />
<lib-file src="node_modules/cordova-sqlite-storage-dependencies/libs/sqlite-ndk-native-driver.jar" />
</platform>
<!-- iOS -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="SQLitePlugin">
<param name="ios-package" value="SQLitePlugin" />
</feature>
</config-file>
<!-- Note: the iOS src is based off src/ios implicitly -->
<header-file src="src/ios/SQLitePlugin.h" />
<source-file src="src/ios/SQLitePlugin.m" />
<source-file src="src/ios/CustomPSPDFThreadSafeMutableDictionary.m"
compiler-flags="-w" />
<header-file src="node_modules/cordova-sqlite-storage-dependencies/sqlite3.h" />
<source-file src="node_modules/cordova-sqlite-storage-dependencies/sqlite3.c"
compiler-flags="-w -DSQLITE_THREADSAFE=1 -DSQLITE_DEFAULT_SYNCHRONOUS=3 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_TEMP_STORE=2 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_DEFAULT_PAGE_SIZE=4096" />
</platform>
<!-- macOS (osx) -->
<platform name="osx">
<config-file target="config.xml" parent="/*">
<feature name="SQLitePlugin">
<param name="osx-package" value="SQLitePlugin" />
</feature>
</config-file>
<!-- Note: the macOS (osx) src is based off src/ios implicitly -->
<header-file src="src/ios/SQLitePlugin.h" />
<source-file src="src/ios/SQLitePlugin.m" />
<source-file src="src/ios/CustomPSPDFThreadSafeMutableDictionary.m"
compiler-flags="-w" />
<header-file src="node_modules/cordova-sqlite-storage-dependencies/sqlite3.h" />
<source-file src="node_modules/cordova-sqlite-storage-dependencies/sqlite3.c"
compiler-flags="-w -DSQLITE_THREADSAFE=1 -DSQLITE_DEFAULT_SYNCHRONOUS=3 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_TEMP_STORE=2 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_DEFAULT_PAGE_SIZE=4096" />
</platform>
<!-- windows -->
<platform name="windows">
<js-module src="src/windows/sqlite-proxy.js" name="SQLiteProxy">
<runs />
</js-module>
<!-- SQLite3 JS module from SQLite3-WinRT/SQLite3JS: -->
<js-module src="src/windows/SQLite3-WinRT-sync/SQLite3JS/js/SQLite3.js" name="SQLite3">
<runs />
</js-module>
<!-- Thanks to AllJoyn-Cordova / cordova-plugin-alljoyn for guidance: -->
<framework src="src/windows/SQLite3-WinRT-sync/SQLite3/SQLite3.UWP.vcxproj" custom="true" type="projectReference" versions="10.*" />
</platform>
</plugin>
<!-- vim: set expandtab : -->

View File

@ -1,26 +0,0 @@
// Adapted from:
// https://github.com/AllJoyn-Cordova/cordova-plugin-alljoyn/blob/master/scripts/beforePluginInstall.js
const path = require('path');
const exec = require('child_process').exec;
const packageName = require('../package.json').name;
module.exports = function () {
return new Promise(function (resolve, reject) {
console.log('installing external dependencies via npm');
console.log('for package name: ' + packageName);
exec('npm install', { cwd: path.join('plugins', packageName) },
function (error, stdout, stderr) {
if (error !== null) {
console.log('npm install of external dependencies failed with error message: ' + error.message);
reject();
} else {
console.log('npm install of external dependencies ok');
resolve();
}
}
);
});
};

View File

@ -1,40 +0,0 @@
const path = require('path');
const fs = require('fs-extra');
const spawn = require('cross-spawn');
console.info('Removing any old artifacts from spec');
fs.removeSync('spec/myplugin');
fs.removeSync('spec/plugins');
fs.removeSync('spec/platforms');
const myplugin = path.join('spec', 'myplugin');
console.info('Copying plugin artifacts into ' + myplugin);
fs.ensureDirSync(myplugin);
['package.json', 'plugin.xml'].forEach((src) => {
const dest = path.join(myplugin, src);
fs.copySync(src, dest);
});
['scripts', 'src', 'www'].forEach((src) => {
const dest = path.join(myplugin, src);
fs.ensureDirSync(dest);
fs.copySync(src, dest);
});
const args = 'plugin add myplugin';
console.log('Spawning Cordova CLI in `spec` with the following arguments: ' + args);
spawn.sync('cordova', args.split(' '), {
cwd: 'spec',
stdio: 'inherit',
});
console.info('The spec is now ready to test a copy of this plugin.');
console.info('Please do `cd spec` and then use `cordova platform add` to add each desired platform.');

View File

@ -1,13 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.phonegap.plugins.sqlite.tests" version="0.0.1"
xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>cordova-sqlite-spec</name>
<description>
Runs the unit tests suite for the Cordova SQLite plugin.
</description>
<author email="info@litehelpers.net" href="http://litehelpers.net">
Various
</author>
<content src="index.html" />
<access origin="*" />
</widget>

View File

@ -1,4 +0,0 @@
{
"name": "cordova-sqlite-spec",
"cordova": {}
}

View File

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no" />
<title>SQLitePlugin Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.5.2/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-2.5.2/jasmine.css">
<script src="lib/jasmine-2.5.2/jasmine.js"></script>
<script src="lib/jasmine-2.5.2/jasmine-html.js"></script>
<script src="lib/jasmine-2.5.2/boot.js"></script>
<!-- [Cordova] source file(s): -->
<script src="cordova.js"></script>
<!-- browser startup test: -->
<script src="spec/browser-check-startup.js"></script>
<!-- other spec file(s): -->
<script src="spec/self-test.js"></script>
<script src="spec/sqlite-version-test.js"></script>
<script src="spec/db-tx-string-test.js"></script>
<script src="spec/db-tx-sql-select-value-test.js"></script>
<script src="spec/basic-db-tx-sql-storage-results.js"></script>
<script src="spec/db-sql-operations-test.js"></script>
<script src="spec/sql-batch-test.js"></script>
<script src="spec/db-tx-sql-features-test.js"></script>
<script src="spec/regexp-test.js"></script>
<script src="spec/db-simultaneous-tx-access-test.js"></script>
<script src="spec/db-tx-multiple-update-test.js"></script>
<script src="spec/tx-semantics-test.js"></script>
<script src="spec/db-tx-value-bindings-test.js"></script> <!-- stored [INSERT] value binding tests -->
<script src="spec/db-tx-error-handling-test.js"></script>
<script src="spec/db-tx-error-mapping-test.js"></script>
<script src="spec/ext-tx-blob-test.js"></script> <!-- Blob object value test(s) -->
<script src="spec/db-open-close-delete-test.js"></script> <!-- extended db open/close/delete testing -->
</head>
<body>
</body>
</html> <!-- vim: set expandtab : -->

View File

@ -1,130 +0,0 @@
/**
Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
[jasmine-gem]: http://github.com/pivotal/jasmine-gem
*/
(function() {
/**
* ## Require &amp; Instantiate
*
* Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
*/
window.jasmine = jasmineRequire.core(jasmineRequire);
/**
* Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
*/
jasmineRequire.html(jasmine);
/**
* Create the Jasmine environment. This is used to run all specs in a project.
*/
var env = jasmine.getEnv();
/**
* ## The Global Interface
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
*/
var jasmineInterface = jasmineRequire.interface(jasmine, env);
/**
* Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
*/
extend(window, jasmineInterface);
/**
* ## Runner Parameters
*
* More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
*/
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
});
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var throwingExpectationFailures = queryString.getParam("throwFailures");
env.throwOnExpectationFailure(throwingExpectationFailures);
var random = queryString.getParam("random");
env.randomizeTests(random);
var seed = queryString.getParam("seed");
if (seed) {
env.seed(seed);
}
/**
* ## Reporters
* The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
*/
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer()
});
/**
* The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
*/
env.addReporter(jasmineInterface.jsApiReporter);
env.addReporter(htmlReporter);
/**
* Filter which specs will be run by matching the start of the full name against the `spec` query param.
*/
var specFilter = new jasmine.HtmlSpecFilter({
filterString: function() { return queryString.getParam("spec"); }
});
env.specFilter = function(spec) {
return specFilter.matches(spec.getFullName());
};
/**
* Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
*/
window.setTimeout = window.setTimeout;
window.setInterval = window.setInterval;
window.clearTimeout = window.clearTimeout;
window.clearInterval = window.clearInterval;
/**
* ## Execution
*
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
*/
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
htmlReporter.initialize();
env.execute();
};
/**
* Helper function for readability above.
*/
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());

View File

@ -1,190 +0,0 @@
/*
Copyright (c) 2008-2016 Pivotal Labs
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.
*/
function getJasmineRequireObj() {
if (typeof module !== 'undefined' && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
return window.jasmineRequire;
}
}
getJasmineRequireObj().console = function(jRequire, j$) {
j$.ConsoleReporter = jRequire.ConsoleReporter();
};
getJasmineRequireObj().ConsoleReporter = function() {
var noopTimer = {
start: function(){},
elapsed: function(){ return 0; }
};
function ConsoleReporter(options) {
var print = options.print,
showColors = options.showColors || false,
onComplete = options.onComplete || function() {},
timer = options.timer || noopTimer,
specCount,
failureCount,
failedSpecs = [],
pendingCount,
ansi = {
green: '\x1B[32m',
red: '\x1B[31m',
yellow: '\x1B[33m',
none: '\x1B[0m'
},
failedSuites = [];
print('ConsoleReporter is deprecated and will be removed in a future version.');
this.jasmineStarted = function() {
specCount = 0;
failureCount = 0;
pendingCount = 0;
print('Started');
printNewline();
timer.start();
};
this.jasmineDone = function() {
printNewline();
for (var i = 0; i < failedSpecs.length; i++) {
specFailureDetails(failedSpecs[i]);
}
if(specCount > 0) {
printNewline();
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);
if (pendingCount) {
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
}
print(specCounts);
} else {
print('No specs found');
}
printNewline();
var seconds = timer.elapsed() / 1000;
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
for(i = 0; i < failedSuites.length; i++) {
suiteFailureDetails(failedSuites[i]);
}
onComplete(failureCount === 0);
};
this.specDone = function(result) {
specCount++;
if (result.status == 'pending') {
pendingCount++;
print(colored('yellow', '*'));
return;
}
if (result.status == 'passed') {
print(colored('green', '.'));
return;
}
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
print(colored('red', 'F'));
}
};
this.suiteDone = function(result) {
if (result.failedExpectations && result.failedExpectations.length > 0) {
failureCount++;
failedSuites.push(result);
}
};
return this;
function printNewline() {
print('\n');
}
function colored(color, str) {
return showColors ? (ansi[color] + str + ansi.none) : str;
}
function plural(str, count) {
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) {
arr.push(thing);
}
return arr;
}
function indent(str, spaces) {
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join('\n');
}
function specFailureDetails(result) {
printNewline();
print(result.fullName);
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent(failedExpectation.message, 2));
print(indent(failedExpectation.stack, 2));
}
printNewline();
}
function suiteFailureDetails(result) {
for (var i = 0; i < result.failedExpectations.length; i++) {
printNewline();
print(colored('red', 'An error was thrown in an afterAll'));
printNewline();
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
}
printNewline();
}
}
return ConsoleReporter;
};

View File

@ -1,481 +0,0 @@
/*
Copyright (c) 2008-2016 Pivotal Labs
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.
*/
jasmineRequire.html = function(j$) {
j$.ResultsNode = jasmineRequire.ResultsNode();
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
j$.QueryString = jasmineRequire.QueryString();
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
};
jasmineRequire.HtmlReporter = function(j$) {
var noopTimer = {
start: function() {},
elapsed: function() { return 0; }
};
function HtmlReporter(options) {
var env = options.env || {},
getContainer = options.getContainer,
createElement = options.createElement,
createTextNode = options.createTextNode,
onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {},
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
onRandomClick = options.onRandomClick || function() {},
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
timer = options.timer || noopTimer,
results = [],
specsExecuted = 0,
failureCount = 0,
pendingSpecCount = 0,
htmlReporterMain,
symbols,
failedSuites = [];
this.initialize = function() {
clearPrior();
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
createDom('div', {className: 'jasmine-banner'},
createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}),
createDom('span', {className: 'jasmine-version'}, j$.version)
),
createDom('ul', {className: 'jasmine-symbol-summary'}),
createDom('div', {className: 'jasmine-alert'}),
createDom('div', {className: 'jasmine-results'},
createDom('div', {className: 'jasmine-failures'})
)
);
getContainer().appendChild(htmlReporterMain);
};
var totalSpecsDefined;
this.jasmineStarted = function(options) {
totalSpecsDefined = options.totalSpecsDefined || 0;
timer.start();
};
var summary = createDom('div', {className: 'jasmine-summary'});
var topResults = new j$.ResultsNode({}, '', null),
currentParent = topResults;
this.suiteStarted = function(result) {
currentParent.addChild(result, 'suite');
currentParent = currentParent.last();
};
this.suiteDone = function(result) {
if (result.status == 'failed') {
failedSuites.push(result);
}
if (currentParent == topResults) {
return;
}
currentParent = currentParent.parent;
};
this.specStarted = function(result) {
currentParent.addChild(result, 'spec');
};
var failures = [];
this.specDone = function(result) {
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
console.error('Spec \'' + result.fullName + '\' has no expectations.');
}
if (result.status != 'disabled') {
specsExecuted++;
}
if (!symbols){
symbols = find('.jasmine-symbol-summary');
}
symbols.appendChild(createDom('li', {
className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status,
id: 'spec_' + result.id,
title: result.fullName
}
));
if (result.status == 'failed') {
failureCount++;
var failure =
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
createDom('div', {className: 'jasmine-description'},
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
),
createDom('div', {className: 'jasmine-messages'})
);
var messages = failure.childNodes[1];
for (var i = 0; i < result.failedExpectations.length; i++) {
var expectation = result.failedExpectations[i];
messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message));
messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack));
}
failures.push(failure);
}
if (result.status == 'pending') {
pendingSpecCount++;
}
};
this.jasmineDone = function(doneResult) {
var banner = find('.jasmine-banner');
var alert = find('.jasmine-alert');
var order = doneResult && doneResult.order;
alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
banner.appendChild(
createDom('div', { className: 'jasmine-run-options' },
createDom('span', { className: 'jasmine-trigger' }, 'Options'),
createDom('div', { className: 'jasmine-payload' },
createDom('div', { className: 'jasmine-exceptions' },
createDom('input', {
className: 'jasmine-raise',
id: 'jasmine-raise-exceptions',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')),
createDom('div', { className: 'jasmine-throw-failures' },
createDom('input', {
className: 'jasmine-throw',
id: 'jasmine-throw-failures',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')),
createDom('div', { className: 'jasmine-random-order' },
createDom('input', {
className: 'jasmine-random',
id: 'jasmine-random-order',
type: 'checkbox'
}),
createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order'))
)
));
var raiseCheckbox = find('#jasmine-raise-exceptions');
raiseCheckbox.checked = !env.catchingExceptions();
raiseCheckbox.onclick = onRaiseExceptionsClick;
var throwCheckbox = find('#jasmine-throw-failures');
throwCheckbox.checked = env.throwingExpectationFailures();
throwCheckbox.onclick = onThrowExpectationsClick;
var randomCheckbox = find('#jasmine-random-order');
randomCheckbox.checked = env.randomTests();
randomCheckbox.onclick = onRandomClick;
var optionsMenu = find('.jasmine-run-options'),
optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'),
optionsPayload = optionsMenu.querySelector('.jasmine-payload'),
isOpen = /\bjasmine-open\b/;
optionsTrigger.onclick = function() {
if (isOpen.test(optionsPayload.className)) {
optionsPayload.className = optionsPayload.className.replace(isOpen, '');
} else {
optionsPayload.className += ' jasmine-open';
}
};
if (specsExecuted < totalSpecsDefined) {
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
var skippedLink = order && order.random ? '?random=true' : '?';
alert.appendChild(
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
)
);
}
var statusBarMessage = '';
var statusBarClassName = 'jasmine-bar ';
if (totalSpecsDefined > 0) {
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
} else {
statusBarClassName += 'jasmine-skipped';
statusBarMessage += 'No specs found';
}
var seedBar;
if (order && order.random) {
seedBar = createDom('span', {className: 'jasmine-seed-bar'},
', randomized with seed ',
createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed)
);
}
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
var errorBarClassName = 'jasmine-bar jasmine-errored';
var errorBarMessagePrefix = 'AfterAll ';
for(var i = 0; i < failedSuites.length; i++) {
var failedSuite = failedSuites[i];
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
}
}
var globalFailures = (doneResult && doneResult.failedExpectations) || [];
for(i = 0; i < globalFailures.length; i++) {
var failure = globalFailures[i];
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
}
var results = find('.jasmine-results');
results.appendChild(summary);
summaryList(topResults, summary);
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
if (resultNode.type == 'suite') {
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
createDom('li', {className: 'jasmine-suite-detail'},
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
summaryList(resultNode, suiteListNode);
domParent.appendChild(suiteListNode);
}
if (resultNode.type == 'spec') {
if (domParent.getAttribute('class') != 'jasmine-specs') {
specListNode = createDom('ul', {className: 'jasmine-specs'});
domParent.appendChild(specListNode);
}
var specDescription = resultNode.result.description;
if(noExpectations(resultNode.result)) {
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
}
if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') {
specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason;
}
specListNode.appendChild(
createDom('li', {
className: 'jasmine-' + resultNode.result.status,
id: 'spec-' + resultNode.result.id
},
createDom('a', {href: specHref(resultNode.result)}, specDescription)
)
);
}
}
}
if (failures.length) {
alert.appendChild(
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'},
createDom('span', {}, 'Spec List | '),
createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures')));
alert.appendChild(
createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'},
createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'),
createDom('span', {}, ' | Failures ')));
find('.jasmine-failures-menu').onclick = function() {
setMenuModeTo('jasmine-failure-list');
};
find('.jasmine-spec-list-menu').onclick = function() {
setMenuModeTo('jasmine-spec-list');
};
setMenuModeTo('jasmine-failure-list');
var failureNode = find('.jasmine-failures');
for (i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
}
};
return this;
function find(selector) {
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
function clearPrior() {
// return the reporter
var oldReporter = find('');
if(oldReporter) {
getContainer().removeChild(oldReporter);
}
}
function createDom(type, attrs, childrenVarArgs) {
var el = createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(createTextNode(child));
} else {
if (child) {
el.appendChild(child);
}
}
}
for (var attr in attrs) {
if (attr == 'className') {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
}
function pluralize(singular, count) {
var word = (count == 1 ? singular : singular + 's');
return '' + count + ' ' + word;
}
function specHref(result) {
return addToExistingQueryString('spec', result.fullName);
}
function seedHref(seed) {
return addToExistingQueryString('seed', seed);
}
function defaultQueryString(key, value) {
return '?' + key + '=' + value;
}
function setMenuModeTo(mode) {
htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
}
function noExpectations(result) {
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
result.status === 'passed';
}
}
return HtmlReporter;
};
jasmineRequire.HtmlSpecFilter = function() {
function HtmlSpecFilter(options) {
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
var filterPattern = new RegExp(filterString);
this.matches = function(specName) {
return filterPattern.test(specName);
};
}
return HtmlSpecFilter;
};
jasmineRequire.ResultsNode = function() {
function ResultsNode(result, type, parent) {
this.result = result;
this.type = type;
this.parent = parent;
this.children = [];
this.addChild = function(result, type) {
this.children.push(new ResultsNode(result, type, this));
};
this.last = function() {
return this.children[this.children.length - 1];
};
}
return ResultsNode;
};
jasmineRequire.QueryString = function() {
function QueryString(options) {
this.navigateWithNewParam = function(key, value) {
options.getWindowLocation().search = this.fullStringWithNewParam(key, value);
};
this.fullStringWithNewParam = function(key, value) {
var paramMap = queryStringToParamMap();
paramMap[key] = value;
return toQueryString(paramMap);
};
this.getParam = function(key) {
return queryStringToParamMap()[key];
};
return this;
function toQueryString(paramMap) {
var qStrPairs = [];
for (var prop in paramMap) {
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
}
return '?' + qStrPairs.join('&');
}
function queryStringToParamMap() {
var paramStr = options.getWindowLocation().search.substring(1),
params = [],
paramMap = {};
if (paramStr.length > 0) {
params = paramStr.split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
var value = decodeURIComponent(p[1]);
if (value === 'true' || value === 'false') {
value = JSON.parse(value);
}
paramMap[decodeURIComponent(p[0])] = value;
}
}
return paramMap;
}
}
return QueryString;
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

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