@opengis/fastify-table 2.3.5 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/dist/errors.d.ts +38 -0
  2. package/dist/errors.d.ts.map +1 -0
  3. package/dist/errors.js +10 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +30 -9
  6. package/dist/server/plugins/access/funcs/getAdminAccess.d.ts +1 -4
  7. package/dist/server/plugins/access/funcs/getAdminAccess.d.ts.map +1 -1
  8. package/dist/server/plugins/access/funcs/getAdminAccess.js +3 -2
  9. package/dist/server/plugins/auth/funcs/getQuery.d.ts.map +1 -1
  10. package/dist/server/plugins/auth/funcs/getQuery.js +2 -1
  11. package/dist/server/plugins/auth/funcs/loginFile.d.ts +1 -4
  12. package/dist/server/plugins/auth/funcs/loginFile.d.ts.map +1 -1
  13. package/dist/server/plugins/auth/funcs/loginFile.js +10 -5
  14. package/dist/server/plugins/auth/funcs/loginUser.d.ts.map +1 -1
  15. package/dist/server/plugins/auth/funcs/loginUser.js +25 -18
  16. package/dist/server/plugins/auth/index.d.ts.map +1 -1
  17. package/dist/server/plugins/auth/index.js +3 -4
  18. package/dist/server/plugins/crud/funcs/dataInsert.js +1 -1
  19. package/dist/server/plugins/extra/extraData.d.ts.map +1 -1
  20. package/dist/server/plugins/extra/extraData.js +3 -2
  21. package/dist/server/plugins/extra/extraDataGet.d.ts +1 -4
  22. package/dist/server/plugins/extra/extraDataGet.d.ts.map +1 -1
  23. package/dist/server/plugins/extra/extraDataGet.js +4 -6
  24. package/dist/server/plugins/file/uploadMultiPart.js +1 -1
  25. package/dist/server/plugins/grpc/utils/html2doc.d.ts +0 -6
  26. package/dist/server/plugins/grpc/utils/html2doc.d.ts.map +1 -1
  27. package/dist/server/plugins/grpc/utils/html2doc.js +3 -8
  28. package/dist/server/plugins/grpc/utils/html2img.d.ts +0 -6
  29. package/dist/server/plugins/grpc/utils/html2img.d.ts.map +1 -1
  30. package/dist/server/plugins/grpc/utils/html2img.js +3 -8
  31. package/dist/server/plugins/grpc/utils/html2pdf.d.ts +0 -6
  32. package/dist/server/plugins/grpc/utils/html2pdf.d.ts.map +1 -1
  33. package/dist/server/plugins/grpc/utils/html2pdf.js +7 -12
  34. package/dist/server/plugins/grpc/utils/mergePdf.d.ts +0 -7
  35. package/dist/server/plugins/grpc/utils/mergePdf.d.ts.map +1 -1
  36. package/dist/server/plugins/grpc/utils/mergePdf.js +4 -9
  37. package/dist/server/plugins/logger/checkUserAccess.d.ts +1 -4
  38. package/dist/server/plugins/logger/checkUserAccess.d.ts.map +1 -1
  39. package/dist/server/plugins/logger/checkUserAccess.js +4 -6
  40. package/dist/server/plugins/logger/errorMessage.d.ts +1 -1
  41. package/dist/server/plugins/logger/errorMessage.d.ts.map +1 -1
  42. package/dist/server/plugins/logger/errorMessage.js +7 -8
  43. package/dist/server/plugins/logger/errorStatus.d.ts.map +1 -1
  44. package/dist/server/plugins/logger/errorStatus.js +6 -0
  45. package/dist/server/plugins/logger/index.d.ts +2 -2
  46. package/dist/server/plugins/logger/index.d.ts.map +1 -1
  47. package/dist/server/plugins/logger/index.js +16 -18
  48. package/dist/server/plugins/pg/funcs/getMeta.d.ts.map +1 -1
  49. package/dist/server/plugins/pg/funcs/getMeta.js +5 -3
  50. package/dist/server/plugins/policy/funcs/checkJWT.d.ts +0 -9
  51. package/dist/server/plugins/policy/funcs/checkJWT.d.ts.map +1 -1
  52. package/dist/server/plugins/policy/funcs/checkJWT.js +6 -5
  53. package/dist/server/plugins/policy/funcs/checkPermissions.d.ts +1 -4
  54. package/dist/server/plugins/policy/funcs/checkPermissions.d.ts.map +1 -1
  55. package/dist/server/plugins/policy/funcs/checkPermissions.js +2 -1
  56. package/dist/server/plugins/policy/funcs/checkPolicy.d.ts +1 -4
  57. package/dist/server/plugins/policy/funcs/checkPolicy.d.ts.map +1 -1
  58. package/dist/server/plugins/policy/funcs/checkPolicy.js +8 -7
  59. package/dist/server/plugins/policy/index.d.ts.map +1 -1
  60. package/dist/server/plugins/policy/index.js +2 -11
  61. package/dist/server/plugins/table/funcs/getFilterSQL/index.d.ts +1 -15
  62. package/dist/server/plugins/table/funcs/getFilterSQL/index.d.ts.map +1 -1
  63. package/dist/server/plugins/table/funcs/getFilterSQL/index.js +6 -4
  64. package/dist/server/plugins/table/funcs/gisIRColumn.d.ts +0 -22
  65. package/dist/server/plugins/table/funcs/gisIRColumn.d.ts.map +1 -1
  66. package/dist/server/plugins/table/funcs/gisIRColumn.js +5 -3
  67. package/dist/server/plugins/upload/index.d.ts.map +1 -1
  68. package/dist/server/plugins/upload/index.js +7 -0
  69. package/dist/server/plugins/upload/s3.d.ts +7 -1
  70. package/dist/server/plugins/upload/s3.d.ts.map +1 -1
  71. package/dist/server/plugins/upload/s3.js +54 -10
  72. package/dist/server/plugins/upload/s3minio.d.ts +59 -0
  73. package/dist/server/plugins/upload/s3minio.d.ts.map +1 -0
  74. package/dist/server/plugins/upload/s3minio.js +199 -0
  75. package/dist/server/plugins/upload/startUpload.d.ts.map +1 -1
  76. package/dist/server/plugins/upload/startUpload.js +16 -8
  77. package/dist/server/plugins/upload/uploadChunk.d.ts.map +1 -1
  78. package/dist/server/plugins/upload/uploadChunk.js +14 -9
  79. package/dist/server/plugins/usercls/index.js +1 -1
  80. package/dist/server/routes/access/controllers/access.group.d.ts.map +1 -1
  81. package/dist/server/routes/access/controllers/access.group.js +3 -5
  82. package/dist/server/routes/access/controllers/access.group.post.d.ts.map +1 -1
  83. package/dist/server/routes/access/controllers/access.group.post.js +3 -5
  84. package/dist/server/routes/access/controllers/access.interface.d.ts.map +1 -1
  85. package/dist/server/routes/access/controllers/access.interface.js +1 -4
  86. package/dist/server/routes/access/controllers/access.user.d.ts +5 -1
  87. package/dist/server/routes/access/controllers/access.user.d.ts.map +1 -1
  88. package/dist/server/routes/access/controllers/access.user.js +4 -5
  89. package/dist/server/routes/access/controllers/access.user.post.d.ts.map +1 -1
  90. package/dist/server/routes/access/controllers/access.user.post.js +4 -5
  91. package/dist/server/routes/access/index.d.ts.map +1 -1
  92. package/dist/server/routes/access/index.js +10 -6
  93. package/dist/server/routes/auth/controllers/2factor/providers/totp.d.ts.map +1 -1
  94. package/dist/server/routes/auth/controllers/2factor/providers/totp.js +4 -3
  95. package/dist/server/routes/auth/controllers/2factor/qrcode.d.ts.map +1 -1
  96. package/dist/server/routes/auth/controllers/2factor/qrcode.js +6 -10
  97. package/dist/server/routes/auth/controllers/2factor/recovery.d.ts.map +1 -1
  98. package/dist/server/routes/auth/controllers/2factor/recovery.js +14 -23
  99. package/dist/server/routes/auth/controllers/2factor/reset.d.ts.map +1 -1
  100. package/dist/server/routes/auth/controllers/2factor/reset.js +3 -5
  101. package/dist/server/routes/auth/controllers/2factor/verify.d.ts.map +1 -1
  102. package/dist/server/routes/auth/controllers/2factor/verify.js +30 -43
  103. package/dist/server/routes/auth/controllers/core/login.d.ts +1 -4
  104. package/dist/server/routes/auth/controllers/core/login.d.ts.map +1 -1
  105. package/dist/server/routes/auth/controllers/core/passwordRecovery.d.ts.map +1 -1
  106. package/dist/server/routes/auth/controllers/core/passwordRecovery.js +7 -8
  107. package/dist/server/routes/auth/controllers/core/registration.d.ts +1 -4
  108. package/dist/server/routes/auth/controllers/core/registration.d.ts.map +1 -1
  109. package/dist/server/routes/auth/controllers/core/registration.js +10 -24
  110. package/dist/server/routes/auth/controllers/core/updateUserInfo.d.ts +1 -2
  111. package/dist/server/routes/auth/controllers/core/updateUserInfo.d.ts.map +1 -1
  112. package/dist/server/routes/auth/controllers/core/updateUserInfo.js +3 -2
  113. package/dist/server/routes/auth/controllers/euSign/authByData.d.ts.map +1 -1
  114. package/dist/server/routes/auth/controllers/euSign/authByData.js +4 -7
  115. package/dist/server/routes/auth/controllers/jwt/authorize.d.ts.map +1 -1
  116. package/dist/server/routes/auth/controllers/jwt/authorize.js +6 -9
  117. package/dist/server/routes/auth/controllers/jwt/token.d.ts.map +1 -1
  118. package/dist/server/routes/auth/controllers/jwt/token.js +9 -12
  119. package/dist/server/routes/auth/controllers/page/login2faTemplate.d.ts.map +1 -1
  120. package/dist/server/routes/auth/controllers/page/login2faTemplate.js +3 -2
  121. package/dist/server/routes/auth/index.d.ts +1 -2
  122. package/dist/server/routes/auth/index.d.ts.map +1 -1
  123. package/dist/server/routes/auth/index.js +4 -3
  124. package/dist/server/routes/cron/controllers/cronApi.d.ts.map +1 -1
  125. package/dist/server/routes/cron/controllers/cronApi.js +3 -4
  126. package/dist/server/routes/cron/index.js +1 -1
  127. package/dist/server/routes/crud/controllers/deleteCrud.d.ts.map +1 -1
  128. package/dist/server/routes/crud/controllers/deleteCrud.js +11 -33
  129. package/dist/server/routes/crud/controllers/insert.d.ts +1 -1
  130. package/dist/server/routes/crud/controllers/insert.d.ts.map +1 -1
  131. package/dist/server/routes/crud/controllers/insert.js +17 -31
  132. package/dist/server/routes/crud/controllers/table.d.ts.map +1 -1
  133. package/dist/server/routes/crud/controllers/table.js +14 -18
  134. package/dist/server/routes/crud/controllers/update.d.ts.map +1 -1
  135. package/dist/server/routes/crud/controllers/update.js +16 -28
  136. package/dist/server/routes/crud/index.d.ts.map +1 -1
  137. package/dist/server/routes/crud/index.js +14 -4
  138. package/dist/server/routes/dblist/controllers/setItem.d.ts +0 -6
  139. package/dist/server/routes/dblist/controllers/setItem.d.ts.map +1 -1
  140. package/dist/server/routes/dblist/controllers/setItem.js +3 -2
  141. package/dist/server/routes/dblist/index.d.ts.map +1 -1
  142. package/dist/server/routes/dblist/index.js +5 -3
  143. package/dist/server/routes/file/controllers/delete.d.ts +4 -1
  144. package/dist/server/routes/file/controllers/delete.d.ts.map +1 -1
  145. package/dist/server/routes/file/controllers/delete.js +8 -8
  146. package/dist/server/routes/file/controllers/download.d.ts.map +1 -1
  147. package/dist/server/routes/file/controllers/download.js +5 -8
  148. package/dist/server/routes/file/controllers/export.d.ts.map +1 -1
  149. package/dist/server/routes/file/controllers/export.js +8 -8
  150. package/dist/server/routes/file/controllers/files.d.ts.map +1 -1
  151. package/dist/server/routes/file/controllers/files.js +6 -8
  152. package/dist/server/routes/file/controllers/resize.d.ts.map +1 -1
  153. package/dist/server/routes/file/controllers/resize.js +4 -12
  154. package/dist/server/routes/file/index.d.ts.map +1 -1
  155. package/dist/server/routes/file/index.js +10 -7
  156. package/dist/server/routes/grpc/controllers/file2geojson.d.ts.map +1 -1
  157. package/dist/server/routes/grpc/controllers/file2geojson.js +7 -7
  158. package/dist/server/routes/grpc/controllers/filePreview.d.ts.map +1 -1
  159. package/dist/server/routes/grpc/controllers/filePreview.js +5 -4
  160. package/dist/server/routes/grpc/index.d.ts.map +1 -1
  161. package/dist/server/routes/grpc/index.js +3 -2
  162. package/dist/server/routes/logger/controllers/logger.file.d.ts +1 -1
  163. package/dist/server/routes/logger/controllers/logger.file.d.ts.map +1 -1
  164. package/dist/server/routes/logger/controllers/logger.file.js +4 -5
  165. package/dist/server/routes/logger/controllers/logger.metrics.d.ts.map +1 -1
  166. package/dist/server/routes/logger/controllers/logger.metrics.js +1 -4
  167. package/dist/server/routes/logger/index.d.ts.map +1 -1
  168. package/dist/server/routes/logger/index.js +4 -2
  169. package/dist/server/routes/menu/controllers/getMenu.d.ts.map +1 -1
  170. package/dist/server/routes/menu/controllers/getMenu.js +2 -1
  171. package/dist/server/routes/menu/index.d.ts.map +1 -1
  172. package/dist/server/routes/menu/index.js +9 -2
  173. package/dist/server/routes/notifications/controllers/addUserNotification.d.ts +1 -2
  174. package/dist/server/routes/notifications/controllers/addUserNotification.d.ts.map +1 -1
  175. package/dist/server/routes/notifications/controllers/addUserNotification.js +5 -6
  176. package/dist/server/routes/notifications/controllers/deleteUserNotification.d.ts +1 -2
  177. package/dist/server/routes/notifications/controllers/deleteUserNotification.d.ts.map +1 -1
  178. package/dist/server/routes/notifications/controllers/deleteUserNotification.js +5 -6
  179. package/dist/server/routes/notifications/controllers/editUserNotification.d.ts +1 -2
  180. package/dist/server/routes/notifications/controllers/editUserNotification.d.ts.map +1 -1
  181. package/dist/server/routes/notifications/controllers/editUserNotification.js +6 -9
  182. package/dist/server/routes/notifications/controllers/readNotifications.d.ts +4 -2
  183. package/dist/server/routes/notifications/controllers/readNotifications.d.ts.map +1 -1
  184. package/dist/server/routes/notifications/controllers/readNotifications.js +4 -3
  185. package/dist/server/routes/notifications/controllers/userNotifications.d.ts +5 -2
  186. package/dist/server/routes/notifications/controllers/userNotifications.d.ts.map +1 -1
  187. package/dist/server/routes/notifications/controllers/userNotifications.js +4 -5
  188. package/dist/server/routes/notifications/index.d.ts +1 -2
  189. package/dist/server/routes/notifications/index.d.ts.map +1 -1
  190. package/dist/server/routes/notifications/index.js +3 -1
  191. package/dist/server/routes/properties/controllers/properties.get.d.ts +5 -2
  192. package/dist/server/routes/properties/controllers/properties.get.d.ts.map +1 -1
  193. package/dist/server/routes/properties/controllers/properties.get.js +6 -5
  194. package/dist/server/routes/properties/controllers/properties.post.d.ts +1 -1
  195. package/dist/server/routes/properties/controllers/properties.post.d.ts.map +1 -1
  196. package/dist/server/routes/properties/controllers/properties.post.js +7 -6
  197. package/dist/server/routes/properties/index.d.ts.map +1 -1
  198. package/dist/server/routes/properties/index.js +4 -7
  199. package/dist/server/routes/table/controllers/card.d.ts +1 -1
  200. package/dist/server/routes/table/controllers/card.d.ts.map +1 -1
  201. package/dist/server/routes/table/controllers/card.js +9 -7
  202. package/dist/server/routes/table/controllers/cardData.d.ts.map +1 -1
  203. package/dist/server/routes/table/controllers/cardData.js +4 -6
  204. package/dist/server/routes/table/controllers/cardTabData.d.ts.map +1 -1
  205. package/dist/server/routes/table/controllers/cardTabData.js +3 -2
  206. package/dist/server/routes/table/controllers/dataInfo.d.ts.map +1 -1
  207. package/dist/server/routes/table/controllers/dataInfo.js +4 -3
  208. package/dist/server/routes/table/controllers/filter.d.ts.map +1 -1
  209. package/dist/server/routes/table/controllers/filter.js +3 -2
  210. package/dist/server/routes/table/controllers/form.d.ts +1 -1
  211. package/dist/server/routes/table/controllers/form.d.ts.map +1 -1
  212. package/dist/server/routes/table/controllers/form.js +7 -5
  213. package/dist/server/routes/table/controllers/getFormByTable.d.ts.map +1 -1
  214. package/dist/server/routes/table/controllers/getFormByTable.js +12 -12
  215. package/dist/server/routes/table/controllers/suggest.d.ts +1 -1
  216. package/dist/server/routes/table/controllers/suggest.d.ts.map +1 -1
  217. package/dist/server/routes/table/controllers/suggest.js +14 -29
  218. package/dist/server/routes/table/controllers/tableInfo.d.ts +1 -2
  219. package/dist/server/routes/table/controllers/tableInfo.d.ts.map +1 -1
  220. package/dist/server/routes/table/controllers/tableInfo.js +9 -8
  221. package/dist/server/routes/table/controllers/tokenInfo.d.ts.map +1 -1
  222. package/dist/server/routes/table/controllers/tokenInfo.js +2 -1
  223. package/dist/server/routes/table/functions/getData.d.ts.map +1 -1
  224. package/dist/server/routes/table/functions/getData.js +19 -25
  225. package/dist/server/routes/table/index.d.ts.map +1 -1
  226. package/dist/server/routes/table/index.js +15 -13
  227. package/dist/server/routes/templates/controllers/getTemplate.d.ts.map +1 -1
  228. package/dist/server/routes/templates/controllers/getTemplate.js +9 -5
  229. package/dist/server/routes/templates/index.d.ts.map +1 -1
  230. package/dist/server/routes/templates/index.js +2 -1
  231. package/dist/server/routes/upload/index.d.ts.map +1 -1
  232. package/dist/server/routes/upload/index.js +31 -20
  233. package/dist/server/routes/usercls/controllers/addUserCls.d.ts.map +1 -1
  234. package/dist/server/routes/usercls/controllers/addUserCls.js +2 -1
  235. package/dist/server/routes/usercls/controllers/deleteUserCls.d.ts.map +1 -1
  236. package/dist/server/routes/usercls/controllers/deleteUserCls.js +2 -1
  237. package/dist/server/routes/usercls/controllers/editUserCls.d.ts.map +1 -1
  238. package/dist/server/routes/usercls/controllers/editUserCls.js +2 -1
  239. package/dist/server/routes/usercls/controllers/getUserCls.d.ts +1 -1
  240. package/dist/server/routes/usercls/controllers/getUserCls.d.ts.map +1 -1
  241. package/dist/server/routes/usercls/controllers/getUserCls.js +4 -3
  242. package/dist/server/routes/usercls/index.d.ts.map +1 -1
  243. package/dist/server/routes/usercls/index.js +12 -5
  244. package/dist/server/routes/util/controllers/api.list.d.ts +19 -0
  245. package/dist/server/routes/util/controllers/api.list.d.ts.map +1 -0
  246. package/dist/server/routes/util/controllers/api.list.js +58 -0
  247. package/dist/server/routes/util/controllers/code.generator.d.ts.map +1 -1
  248. package/dist/server/routes/util/controllers/code.generator.js +7 -6
  249. package/dist/server/routes/util/controllers/user.tokens.d.ts +1 -2
  250. package/dist/server/routes/util/controllers/user.tokens.d.ts.map +1 -1
  251. package/dist/server/routes/util/controllers/user.tokens.js +6 -5
  252. package/dist/server/routes/util/index.d.ts.map +1 -1
  253. package/dist/server/routes/util/index.js +8 -7
  254. package/dist/server/routes/widget/controllers/file.edit.d.ts.map +1 -1
  255. package/dist/server/routes/widget/controllers/file.edit.js +5 -4
  256. package/dist/server/routes/widget/controllers/widget.del.d.ts.map +1 -1
  257. package/dist/server/routes/widget/controllers/widget.del.js +6 -7
  258. package/dist/server/routes/widget/controllers/widget.get.d.ts.map +1 -1
  259. package/dist/server/routes/widget/controllers/widget.get.js +4 -3
  260. package/dist/server/routes/widget/controllers/widget.set.d.ts.map +1 -1
  261. package/dist/server/routes/widget/controllers/widget.set.js +5 -4
  262. package/dist/server/routes/widget/index.d.ts.map +1 -1
  263. package/dist/server/routes/widget/index.js +3 -2
  264. package/package.json +3 -1
  265. package/dist/module/core/cls/constraint_type.json +0 -14
  266. package/dist/module/core/cls/constraint_type_table.json +0 -18
  267. package/dist/server/migrations/oauth.sql.sql +0 -77
  268. package/dist/server/plugins/auth/funcs/getUserPermissions.d.ts +0 -2
  269. package/dist/server/plugins/auth/funcs/getUserPermissions.d.ts.map +0 -1
  270. package/dist/server/plugins/auth/funcs/getUserPermissions.js +0 -24
  271. package/dist/server/plugins/auth/onRequest.d.ts +0 -4
  272. package/dist/server/plugins/auth/onRequest.d.ts.map +0 -1
  273. package/dist/server/plugins/auth/onRequest.js +0 -104
  274. package/dist/server/plugins/migration/index.d.ts +0 -3
  275. package/dist/server/plugins/migration/index.d.ts.map +0 -1
  276. package/dist/server/plugins/migration/index.js +0 -5
  277. package/dist/server/plugins/policy/funcs/checkAuth.d.ts +0 -4
  278. package/dist/server/plugins/policy/funcs/checkAuth.d.ts.map +0 -1
  279. package/dist/server/plugins/policy/funcs/checkAuth.js +0 -104
  280. package/dist/server/routes/access/controllers/access.resources.d.ts +0 -6
  281. package/dist/server/routes/access/controllers/access.resources.d.ts.map +0 -1
  282. package/dist/server/routes/access/controllers/access.resources.js +0 -14
  283. package/dist/server/routes/access/controllers/resources.d.ts +0 -11
  284. package/dist/server/routes/access/controllers/resources.d.ts.map +0 -1
  285. package/dist/server/routes/access/controllers/resources.js +0 -14
  286. package/dist/server/routes/access/functions/resources.d.ts +0 -6
  287. package/dist/server/routes/access/functions/resources.d.ts.map +0 -1
  288. package/dist/server/routes/access/functions/resources.js +0 -11
  289. package/dist/server/types/errors.d.ts +0 -14
  290. package/dist/server/types/errors.d.ts.map +0 -1
  291. package/dist/server/types/errors.js +0 -4
@@ -138,6 +138,7 @@ export async function refreshUploadTTL(id, ttl = UPLOAD_TTL_SECONDS, s3 = s3Clie
138
138
  }
139
139
  export async function deleteUploadMeta(id, key) {
140
140
  clearUploadTimeout(id);
141
+ await deleteUploadParts(id);
141
142
  if (!config.redis) {
142
143
  const meta = uploads.get(id);
143
144
  uploads.delete(id);
@@ -295,6 +296,39 @@ export async function startUpload({ Bucket, Key, ContentType, fileSize, }, s3 =
295
296
  UploadId: res.UploadId,
296
297
  };
297
298
  }
299
+ const uploadPartsKey = (id) => `upload:${id}:parts`;
300
+ // non-redis in-memory parts cache
301
+ const uploadParts = new Map();
302
+ export async function savePart(id, part) {
303
+ if (!config.redis) {
304
+ const existing = uploadParts.get(id) || [];
305
+ // overwrite existing part number (S3 semantics)
306
+ const filtered = existing.filter((p) => p.PartNumber !== part.PartNumber);
307
+ filtered.push(part);
308
+ uploadParts.set(id, filtered);
309
+ return;
310
+ }
311
+ // use redis hash keyed by part number
312
+ await rclient.hset(uploadPartsKey(id), String(part.PartNumber), JSON.stringify(part));
313
+ // keep ttl aligned with upload meta
314
+ await rclient.expire(uploadPartsKey(id), REDIS_TTL);
315
+ }
316
+ export async function getStoredParts(id) {
317
+ if (!config.redis) {
318
+ return (uploadParts.get(id) || []).sort((a, b) => a.PartNumber - b.PartNumber);
319
+ }
320
+ const parts = await rclient.hgetall(uploadPartsKey(id));
321
+ return Object.values(parts)
322
+ .map((v) => JSON.parse(v))
323
+ .sort((a, b) => a.PartNumber - b.PartNumber);
324
+ }
325
+ export async function deleteUploadParts(id) {
326
+ if (!config.redis) {
327
+ uploadParts.delete(id);
328
+ return;
329
+ }
330
+ await rclient.del(uploadPartsKey(id));
331
+ }
298
332
  export async function uploadChunk({ id, chunk, partNumber, }, s3 = s3Client) {
299
333
  if (!s3)
300
334
  throw new Error("No S3 client");
@@ -305,13 +339,17 @@ export async function uploadChunk({ id, chunk, partNumber, }, s3 = s3Client) {
305
339
  if (upload.parts.some((p) => p.PartNumber === partNumber)) {
306
340
  throw new Error(`Part ${partNumber} already uploaded`);
307
341
  }
308
- await s3.send(new UploadPartCommand({
342
+ const res = await s3.send(new UploadPartCommand({
309
343
  Bucket: upload.Bucket,
310
344
  Key: upload.Key,
311
345
  UploadId: upload.UploadId,
312
346
  PartNumber: partNumber,
313
347
  Body: chunk,
314
348
  }));
349
+ await savePart(id, {
350
+ ETag: res.ETag,
351
+ PartNumber: partNumber,
352
+ });
315
353
  await refreshUploadTTL(id, UPLOAD_TTL_SECONDS, s3);
316
354
  return upload;
317
355
  }
@@ -321,25 +359,30 @@ export async function finishUpload({ id, }, s3 = s3Client) {
321
359
  const redisCache = await getUploadMeta(id);
322
360
  const { fileSize: cachedSize, Key, Bucket } = redisCache || {};
323
361
  const size = cachedSize ? Number(cachedSize) : undefined;
324
- const upload = await findUpload({ id }, s3);
325
- if (!upload?.uploaded) {
326
- throw new Error("File not uploaded");
327
- }
328
- if (size && size !== upload.uploaded) {
329
- throw new Error("File size mismatch");
330
- }
362
+ // const upload = await findUpload({ id }, s3);
363
+ // if (!upload?.uploaded) {
364
+ // throw new Error("File not uploaded");
365
+ // }
366
+ // if (size && size !== upload.uploaded) {
367
+ // throw new Error("File size mismatch");
368
+ // }
369
+ const parts = await getStoredParts(id);
331
370
  await s3.send(new CompleteMultipartUploadCommand({
332
371
  Bucket,
333
372
  Key,
334
373
  UploadId: id,
335
374
  MultipartUpload: {
336
- Parts: upload.parts.sort((a, b) => a.PartNumber - b.PartNumber),
375
+ Parts: parts.sort((a, b) => a.PartNumber - b.PartNumber),
376
+ // Parts: upload.parts.sort(
377
+ // (a: any, b: any) => a.PartNumber - b.PartNumber
378
+ // ),
337
379
  },
338
380
  }));
339
381
  await deleteUploadMeta(id, Key);
340
382
  return {
341
383
  finished: true,
342
- uploaded: upload.uploaded,
384
+ // uploaded: upload.uploaded,
385
+ uploaded: size,
343
386
  filepath: Key.replace(config.folder, ""),
344
387
  };
345
388
  }
@@ -379,6 +422,7 @@ export async function getUploadStatus({ id, Key, Bucket, }, s3 = s3Client) {
379
422
  uploaded: res?.ContentLength,
380
423
  };
381
424
  }
425
+ // const parts = id ? await getStoredParts(id) : { Parts: [] };
382
426
  const parts = await s3
383
427
  .send(new ListPartsCommand({
384
428
  Bucket: redisBucket,
@@ -0,0 +1,59 @@
1
+ export declare function close(): void;
2
+ export declare function startUpload({ Bucket, Key, fileSize: size, ContentType, }: {
3
+ Bucket?: string;
4
+ Key: string;
5
+ fileSize: number;
6
+ ContentType: string;
7
+ }): Promise<{
8
+ UploadId: any;
9
+ }>;
10
+ export declare function findUpload({ Bucket, Key, id: UploadId, }: {
11
+ Bucket?: string;
12
+ Key?: string;
13
+ id?: string;
14
+ }): Promise<{
15
+ UploadId: string;
16
+ fileSize: any;
17
+ } | {
18
+ UploadId: any;
19
+ fileSize?: undefined;
20
+ }>;
21
+ export declare function uploadChunk({ id: UploadId, chunk: Body, partNumber: PartNumber, }: {
22
+ id: string;
23
+ chunk: any;
24
+ partNumber: number;
25
+ }): Promise<{
26
+ uploaded: any;
27
+ ETag: any;
28
+ PartNumber: number;
29
+ }>;
30
+ export declare function finishUpload({ id: UploadId }: {
31
+ id: string;
32
+ }): Promise<{
33
+ finished: boolean;
34
+ uploaded: any;
35
+ filepath: any;
36
+ }>;
37
+ export declare function getUploadStatus({ id, Bucket, Key, }: {
38
+ id?: string;
39
+ Key?: string;
40
+ Bucket?: string;
41
+ }): Promise<{
42
+ exists: boolean;
43
+ finished: boolean;
44
+ uploaded: any;
45
+ id: any;
46
+ size: number | undefined;
47
+ parts: {
48
+ ETag: any;
49
+ PartNumber: any;
50
+ }[];
51
+ }>;
52
+ export declare function cleanupMultipartUploads({ Bucket, }?: {
53
+ Bucket: string;
54
+ }): Promise<PromiseSettledResult<{
55
+ Key: any;
56
+ UploadId: any;
57
+ }>[]>;
58
+ export declare function deleteUploadMeta(id: string): Promise<void>;
59
+ //# sourceMappingURL=s3minio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3minio.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/s3minio.ts"],"names":[],"mappings":"AAuBA,wBAAgB,KAAK,SAIpB;AAwBD,wBAAsB,WAAW,CAAC,EAChC,MAA2C,EAC3C,GAAG,EACH,QAAQ,EAAE,IAAI,EACd,WAAW,GACZ,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;;GAqBA;AAED,wBAAsB,UAAU,CAAC,EAC/B,MAA2C,EAC3C,GAAG,EACH,EAAE,EAAE,QAAQ,GACb,EAAE;IACD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;;;;;;GAuBA;AAED,wBAAsB,WAAW,CAAC,EAChC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,IAAI,EACX,UAAU,EAAE,UAAU,GACvB,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;;;;GA8BA;AAED,wBAAsB,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;;;;GAwClE;AAED,wBAAsB,eAAe,CAAC,EACpC,EAAE,EACF,MAAM,EACN,GAAG,GACJ,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;;;;;;;;;;GA4CA;AAED,wBAAsB,uBAAuB,CAC3C,EACE,MAAM,GACP,GAAE;IACD,MAAM,EAAE,MAAM,CAAC;CACiC;;;MAqCnD;AAED,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,iBAEhD"}
@@ -0,0 +1,199 @@
1
+ import http from "node:http";
2
+ import https from "node:https";
3
+ import { Client } from "minio";
4
+ import config from "../../../config.js";
5
+ import rclient from "../../plugins/redis/client.js";
6
+ import { BadRequestError, NotFoundError } from "../../../errors.js";
7
+ const [protocol, endPoint, port] = config.s3?.endpoint?.split?.(":") || [];
8
+ const useSSL = config.s3?.useSSL || protocol === "https";
9
+ const agent = useSSL
10
+ ? new https.Agent({
11
+ keepAlive: true,
12
+ maxSockets: 100,
13
+ })
14
+ : new http.Agent({
15
+ keepAlive: true,
16
+ maxSockets: 100,
17
+ });
18
+ export function close() {
19
+ console.log("closing minio connections");
20
+ agent.destroy();
21
+ console.log("closed minio agent");
22
+ }
23
+ const minio = endPoint
24
+ ? new Client({
25
+ endPoint: endPoint.substring(2), // trim "//" after split of http://ip:port
26
+ port: port,
27
+ useSSL,
28
+ accessKey: config.s3.user,
29
+ secretKey: config.s3.password,
30
+ // transport: agent,
31
+ })
32
+ : null;
33
+ if (minio) {
34
+ minio.setRequestOptions({
35
+ agent,
36
+ });
37
+ }
38
+ const UPLOAD_TTL_SECONDS = 60 * 60 * 24;
39
+ const CLEANUP_OLDER_THAN_MS = 1000 * 60 * 60 * 24;
40
+ const uploadCacheKey = (id) => `multipart:upload:${id}`;
41
+ export async function startUpload({ Bucket = config.s3?.containerName || "work", Key, fileSize: size, ContentType, }) {
42
+ if (!minio)
43
+ throw new Error("s3 not configured");
44
+ if (!size)
45
+ throw new BadRequestError("invalid params: size");
46
+ if (!Key)
47
+ throw new BadRequestError("not enough params: Key");
48
+ if (!ContentType)
49
+ throw new BadRequestError("not enough params: ContentType");
50
+ const res = await minio.initiateNewMultipartUpload(Bucket, Key, {
51
+ "Content-Type": ContentType,
52
+ });
53
+ const redisKey = uploadCacheKey(res);
54
+ await rclient.set(redisKey, JSON.stringify({ Bucket, Key, ContentType, size }), "EX", UPLOAD_TTL_SECONDS);
55
+ return {
56
+ UploadId: res,
57
+ };
58
+ }
59
+ export async function findUpload({ Bucket = config.s3?.containerName || "work", Key, id: UploadId, }) {
60
+ if (!minio)
61
+ throw new Error("s3 not configured");
62
+ if (UploadId) {
63
+ const redisKey = uploadCacheKey(UploadId);
64
+ const cache = await rclient
65
+ .get(redisKey)
66
+ .then((r) => JSON.parse(r || "{}"));
67
+ return {
68
+ UploadId,
69
+ fileSize: cache.size,
70
+ };
71
+ }
72
+ if (!Key)
73
+ throw new BadRequestError("not enough params: Key");
74
+ const uploads = await minio.listIncompleteUploads(Bucket, Key, true);
75
+ const found = uploads.find((u) => u.key === Key);
76
+ return {
77
+ UploadId: found?.uploadId,
78
+ };
79
+ }
80
+ export async function uploadChunk({ id: UploadId, chunk: Body, partNumber: PartNumber, }) {
81
+ if (!minio)
82
+ throw new Error("s3 not configured");
83
+ const redisKey = uploadCacheKey(UploadId);
84
+ const cache = await rclient
85
+ .get(redisKey)
86
+ .then((r) => JSON.parse(r || "{}"));
87
+ if (!cache.Key) {
88
+ throw NotFoundError("multipart upload not found");
89
+ }
90
+ const etag = await minio.uploadPart({
91
+ bucketName: cache.Bucket,
92
+ objectName: cache.Key,
93
+ uploadID: UploadId,
94
+ partNumber: PartNumber,
95
+ headers: {
96
+ "Content-Type": cache.contentType,
97
+ },
98
+ }, Body);
99
+ return {
100
+ uploaded: Body.length,
101
+ ETag: etag,
102
+ PartNumber,
103
+ };
104
+ }
105
+ export async function finishUpload({ id: UploadId }) {
106
+ if (!minio)
107
+ throw new Error("s3 not configured");
108
+ const redisKey = uploadCacheKey(UploadId);
109
+ const cache = await rclient
110
+ .get(redisKey)
111
+ .then((r) => JSON.parse(r || "{}"));
112
+ if (!cache.Bucket || !cache.Key) {
113
+ throw NotFoundError("s3 upload not found");
114
+ }
115
+ const parts = cache.Bucket && cache.Key
116
+ ? await minio.listParts(cache.Bucket, cache.Key, UploadId)
117
+ : [];
118
+ const uploaded = parts.reduce((acc, curr) => acc + (curr.size || 0), 0) || 0;
119
+ const sortedParts = parts
120
+ .map((p) => ({
121
+ part: p.part,
122
+ etag: p.etag,
123
+ }))
124
+ .sort((a, b) => a.part - b.part);
125
+ await minio.completeMultipartUpload(cache.Bucket, cache.Key, UploadId, sortedParts);
126
+ await rclient.del(redisKey);
127
+ return {
128
+ finished: true,
129
+ uploaded,
130
+ filepath: cache.Key.replace(config.folder, ""),
131
+ };
132
+ }
133
+ export async function getUploadStatus({ id, Bucket, Key, }) {
134
+ if (!minio)
135
+ throw new Error("s3 not configured");
136
+ if (!id && !(Bucket && Key)) {
137
+ throw new BadRequestError("not enough params: id / Bucket && Key");
138
+ }
139
+ const UploadId = id || (await findUpload({ Bucket, Key }).then((r) => r.UploadId));
140
+ const cache = UploadId
141
+ ? await rclient
142
+ .get(uploadCacheKey(UploadId))
143
+ .then((r) => JSON.parse(r || "{}"))
144
+ : {};
145
+ let stat;
146
+ let parts = [];
147
+ const Key1 = id ? cache.Key : Key;
148
+ const Bucket1 = id ? cache.Bucket : Bucket;
149
+ if (Bucket1 && Key1 && UploadId) {
150
+ try {
151
+ stat = await minio.statObject(Bucket1, Key1);
152
+ }
153
+ catch { }
154
+ try {
155
+ parts = await minio.listParts(Bucket1, Key1, UploadId);
156
+ }
157
+ catch { }
158
+ }
159
+ return {
160
+ exists: !!stat || !!parts.length,
161
+ finished: !!stat,
162
+ uploaded: stat
163
+ ? stat.size
164
+ : parts.reduce((acc, curr) => acc + (curr.size || 0), 0),
165
+ id: UploadId,
166
+ size: cache.size ? Number(cache.size) : undefined,
167
+ parts: parts.map((p) => ({
168
+ ETag: p.etag,
169
+ PartNumber: p.part,
170
+ })),
171
+ };
172
+ }
173
+ export async function cleanupMultipartUploads({ Bucket, } = { Bucket: config.s3?.containerName || "work" }) {
174
+ if (!minio)
175
+ throw new Error("s3 not configured");
176
+ console.log("minio cleanupMultipartUploads start");
177
+ const stream = minio.listIncompleteUploads(Bucket, "", true);
178
+ const uploads = [];
179
+ for await (const upload of stream) {
180
+ uploads.push(upload);
181
+ }
182
+ const now = Date.now();
183
+ const staleUploads = uploads.filter((u) => u.initiated &&
184
+ now - new Date(u.initiated).getTime() > CLEANUP_OLDER_THAN_MS);
185
+ const results = await Promise.allSettled(staleUploads.map(async (upload) => {
186
+ await minio.removeIncompleteUpload(Bucket, upload.key);
187
+ const redisKey = uploadCacheKey(upload.uploadId);
188
+ await rclient.del(redisKey);
189
+ return {
190
+ Key: upload.key,
191
+ UploadId: upload.uploadId,
192
+ };
193
+ }));
194
+ return results;
195
+ }
196
+ export async function deleteUploadMeta(id) {
197
+ if (rclient && id)
198
+ await rclient.del(id);
199
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"startUpload.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/startUpload.ts"],"names":[],"mappings":"AAiBA,wBAA8B,WAAW,CAAC,EACxC,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,gBA+EA"}
1
+ {"version":3,"file":"startUpload.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/startUpload.ts"],"names":[],"mappings":"AAoBA,wBAA8B,WAAW,CAAC,EACxC,IAAI,EACJ,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,gBAyFA"}
@@ -6,12 +6,11 @@ import getUploadStatus from "./getUploadStatus.js";
6
6
  import { prefix, fileDir, metaDir, uploadChunkDirectory, fetchTimeoutMs, } from "./index.js";
7
7
  import mimes from "../file/providers/mime/mimes.js";
8
8
  import { startUpload as startUploadS3 } from "./s3.js";
9
+ import { BadRequestError } from "../../../errors.js";
10
+ const { chunkSize = 5242880 } = config;
9
11
  export default async function startUpload({ host, id, fileName, size, subdir, }) {
10
12
  if (subdir && (typeof subdir !== "string" || subdir.includes(".."))) {
11
- return {
12
- error: "invalid params: subdir",
13
- code: 400,
14
- };
13
+ throw BadRequestError("invalid params: subdir");
15
14
  }
16
15
  if (!host) {
17
16
  const id1 = id || randomUUID();
@@ -20,14 +19,19 @@ export default async function startUpload({ host, id, fileName, size, subdir, })
20
19
  .join(uploadChunkDirectory, subdir || "")
21
20
  .replace(/\\/g, "/");
22
21
  if (config.s3) {
23
- const filepath = path.posix.join(config.folder || '', relativeDirpath, `${id1}.${extension}`);
22
+ const filepath = path.posix.join(config.folder || "", relativeDirpath, `${id1}.${extension}`);
24
23
  const { UploadId } = await startUploadS3({
25
24
  Bucket: config.s3?.containerName || "work",
26
25
  Key: filepath[0] === "/" ? filepath?.slice(1) : filepath,
27
26
  ContentType: mimes[extension],
28
27
  fileSize: size,
29
28
  });
30
- return { id: UploadId, UploadId, provider: "s3" };
29
+ return {
30
+ id: UploadId,
31
+ UploadId,
32
+ provider: "s3",
33
+ chunkSize,
34
+ };
31
35
  }
32
36
  const key = id1.split("-").pop();
33
37
  const meta = {
@@ -57,10 +61,14 @@ export default async function startUpload({ host, id, fileName, size, subdir, })
57
61
  subdir,
58
62
  metaPath: undefined,
59
63
  relativeDirpath,
60
- provider: "fs"
64
+ provider: "fs",
61
65
  };
62
66
  await writeFile(path.join(metaDir, `${id1}.json`), JSON.stringify(metaData, null, 2));
63
- return { ...meta, metaPath: undefined };
67
+ return {
68
+ ...meta,
69
+ metaPath: undefined,
70
+ chunkSize,
71
+ };
64
72
  }
65
73
  const res = await fetch(`${host}/${prefix}/start`, {
66
74
  method: "POST",
@@ -1 +1 @@
1
- {"version":3,"file":"uploadChunk.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/uploadChunk.ts"],"names":[],"mappings":"AAqBA,wBAA8B,WAAW,CAAC,EACxC,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,MAAM,EACN,GAAG,EACH,IAAI,GACL,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,gBAwIA"}
1
+ {"version":3,"file":"uploadChunk.d.ts","sourceRoot":"","sources":["../../../../server/plugins/upload/uploadChunk.ts"],"names":[],"mappings":"AAwBA,wBAA8B,WAAW,CAAC,EACxC,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,MAAM,EACN,GAAG,EACH,IAAI,GACL,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,gBA4IA"}
@@ -7,11 +7,16 @@ import uploadFile from "../file/uploadFile.js";
7
7
  import applyHook from "../hook/applyHook.js";
8
8
  import getFileSize from "../file/getFileSize.js";
9
9
  import { finishUpload as finishUploadS3, uploadChunk as uploadChunkS3, getUploadStatus as getUploadStatusS3, findUpload as findUploadS3, } from "./s3.js";
10
+ import { BadRequestError, ConflictError, NotFoundError } from "../../../errors.js";
11
+ const { chunkSize = 5242880 } = config;
10
12
  export default async function uploadChunk({ host, id, body, offset, end, size, }) {
11
13
  if (!host) {
12
14
  if (config.s3) {
13
- const partNumber = Math.floor(offset / config.chunkSize) + 1;
14
- const { fileSize } = await findUploadS3({ id });
15
+ const partNumber = Math.floor(offset / chunkSize) + 1;
16
+ const { UploadId, fileSize } = await findUploadS3({ id });
17
+ if (!UploadId) {
18
+ throw NotFoundError("upload not found");
19
+ }
15
20
  await uploadChunkS3({
16
21
  id,
17
22
  chunk: body,
@@ -26,17 +31,17 @@ export default async function uploadChunk({ host, id, body, offset, end, size, }
26
31
  }
27
32
  const metaExists = existsSync(path.join(metaDir, `${id}.json`));
28
33
  if (!metaExists) {
29
- return { error: "File not found", code: 404 };
34
+ throw NotFoundError("File not found");
30
35
  }
31
36
  const meta = JSON.parse(await readFile(path.join(metaDir, `${id}.json`), "utf8"));
32
37
  if (size !== meta.size) {
33
- return { error: "Total size mismatch", code: 400 };
38
+ throw BadRequestError("Total size mismatch");
34
39
  }
35
40
  if (offset !== meta.uploaded) {
36
- return { error: "Wrong offset", expected: meta.uploaded, code: 409 };
41
+ throw ConflictError("Wrong offset");
37
42
  }
38
43
  if (body?.length !== end - offset + 1) {
39
- return { error: "Chunk size mismatch", code: 400 };
44
+ throw BadRequestError("Chunk size mismatch with Content-Range");
40
45
  }
41
46
  const relpath = path.posix.join(uploadChunkDirectory, `${id}.${meta.extension}`);
42
47
  const res = await getFileSize(relpath, { fallback: false }).catch((err) => ({
@@ -46,10 +51,10 @@ export default async function uploadChunk({ host, id, body, offset, end, size, }
46
51
  if (res.error &&
47
52
  res.error !== "Error: file not found" &&
48
53
  res.code !== "ENOENT") {
49
- throw new Error(res.error);
54
+ throw Error(res.error);
50
55
  }
51
56
  if (!res.error && res > meta.size) {
52
- throw new Error("uploaded size exceeds file size");
57
+ throw BadRequestError("uploaded size exceeds file size");
53
58
  }
54
59
  // append chunk to existing file
55
60
  await uploadFile(path
@@ -84,7 +89,7 @@ export default async function uploadChunk({ host, id, body, offset, end, size, }
84
89
  return { uploaded: meta.uploaded, finished };
85
90
  }
86
91
  if (!end || !size) {
87
- return { error: "not enough params: offset/end/size", code: 400 };
92
+ throw BadRequestError("not enough params: offset/end/size");
88
93
  }
89
94
  const url = `${host}/${prefix}/${id}`;
90
95
  const range = `bytes ${offset || 0}-${end}/${size}`;
@@ -1,4 +1,4 @@
1
- import { NotFoundError } from "../../types/errors.js";
1
+ import { NotFoundError } from "../../../errors.js";
2
2
  import pgClients from "../pg/pgClients.js";
3
3
  import dataInsert from "../crud/funcs/dataInsert.js";
4
4
  import dataUpdate from "../crud/funcs/dataUpdate.js";
@@ -1 +1 @@
1
- {"version":3,"file":"access.group.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,wBAA8B,WAAW,CACvC,EACE,EAAqB,EACrB,MAAM,EACN,IAAS,GACV,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,EAED,KAAK,EAAE,YAAY;;;;GA4CpB"}
1
+ {"version":3,"file":"access.group.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD,wBAA8B,WAAW,CACvC,EACE,EAAqB,EACrB,MAAM,EACN,IAAS,GACV,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,EAED,KAAK,EAAE,YAAY;;;;GAwCpB"}
@@ -1,16 +1,14 @@
1
1
  import { pgClients, getAdminAccess } from "../../../../utils.js";
2
+ import { BadRequestError } from "../../../../errors.js";
2
3
  export default async function accessGroup({ pg = pgClients.client, params, user = {}, }, reply) {
3
4
  if (!params?.id) {
4
- return reply.status(400).send("not enough params: id");
5
+ throw BadRequestError("not enough params: id");
5
6
  }
6
7
  // restrict access - admin only
7
- const check = await getAdminAccess({
8
+ await getAdminAccess({
8
9
  id: params.id,
9
10
  user,
10
11
  });
11
- if (check?.message && check?.status && process.env.NODE_ENV !== "test") {
12
- return reply.status(check?.status).send(check?.message);
13
- }
14
12
  const routes = await pg
15
13
  .query(`select a.route_id as path, b.actions from admin.routes a
16
14
  left join admin.role_access b on a.route_id=b.route_id
@@ -1 +1 @@
1
- {"version":3,"file":"access.group.post.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.group.post.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD,wBAA8B,eAAe,CAC3C,EACE,EAAqB,EACrB,MAAM,EACN,IAAS,EACT,IAAS,GACV,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,EACD,KAAK,EAAE,YAAY;;;;GA+GpB"}
1
+ {"version":3,"file":"access.group.post.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.group.post.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAMzD,wBAA8B,eAAe,CAC3C,EACE,EAAqB,EACrB,MAAM,EACN,IAAS,EACT,IAAS,GACV,EAAE;IACD,EAAE,EAAE,UAAU,CAAC;IACf,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B,EACD,KAAK,EAAE,YAAY;;;;GA4GpB"}
@@ -1,15 +1,13 @@
1
1
  import { pgClients, getAdminAccess } from "../../../../utils.js";
2
2
  import accessGroup from "./access.group.js";
3
+ import { UnauthorizedError } from "../../../../errors.js";
3
4
  export default async function accessGroupPost({ pg = pgClients.client, params, user = {}, body = {}, }, reply) {
4
5
  const { id } = params;
5
6
  if (!user?.uid) {
6
- return reply.status(401).send("unauthorized");
7
+ throw UnauthorizedError("unauthorized");
7
8
  }
8
9
  // restrict access - admin only
9
- const check = await getAdminAccess({ id, user });
10
- if (check?.message && check?.status && process.env.NODE_ENV !== "test") {
11
- return reply.status(check?.status).send(check?.message);
12
- }
10
+ await getAdminAccess({ id, user });
13
11
  const { users = [], routes = [] } = body;
14
12
  if (!routes?.length) {
15
13
  await pg.query("delete from admin.role_access where role_id=$1", [id]);
@@ -1 +1 @@
1
- {"version":3,"file":"access.interface.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAqB5C,wBAA8B,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY;;GAqB1E"}
1
+ {"version":3,"file":"access.interface.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAqB5C,wBAA8B,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY;;GAkB1E"}
@@ -18,13 +18,10 @@ where $1 in (a.route_id, a.alias, a.table_name) and coalesce(b.user_uid, d.user_
18
18
  export default async function accessInterface(req, reply) {
19
19
  const { pg = pgClients.client, params = {}, user = {}, unittest } = req;
20
20
  // restrict access - admin only
21
- const check = await getAdminAccess({
21
+ await getAdminAccess({
22
22
  id: params.name,
23
23
  user,
24
24
  });
25
- if (check?.message && check?.status && !unittest) {
26
- return reply.status(check?.status).send(check?.message);
27
- }
28
25
  const { rows = [] } = await pg.query(q, [params.name]);
29
26
  const cls = {
30
27
  user_uid: "core.user_uid",
@@ -1,2 +1,6 @@
1
- export default function accessUser(req: any, reply: any): Promise<any>;
1
+ export default function accessUser(req: any): Promise<{
2
+ routes: any;
3
+ resources: any;
4
+ user: any;
5
+ }>;
2
6
  //# sourceMappingURL=access.user.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"access.user.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.user.ts"],"names":[],"mappings":"AAEA,wBAA8B,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAqC5D"}
1
+ {"version":3,"file":"access.user.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.user.ts"],"names":[],"mappings":"AAGA,wBAA8B,UAAU,CAAC,GAAG,EAAE,GAAG;;;;GAmChD"}
@@ -1,9 +1,8 @@
1
+ import { BadRequestError } from "../../../../errors.js";
1
2
  import { pgClients } from "../../../../utils.js";
2
- export default async function accessUser(req, reply) {
3
+ export default async function accessUser(req) {
3
4
  if (!req.params?.id) {
4
- return reply
5
- .status(400)
6
- .send({ error: "not enough params: id", code: 400 });
5
+ throw BadRequestError("not enough params: id");
7
6
  }
8
7
  const { pg = pgClients.client } = req;
9
8
  const routes = await pg
@@ -21,5 +20,5 @@ where resource_id is not null and user_uid=$1`, [req.params.id])
21
20
  left join admin.users b on a.user_uid=b.uid
22
21
  where a.user_uid=$1`, [req.params.id])
23
22
  .then((el) => el.rows?.[0]);
24
- return reply.status(200).send({ routes, resources, user });
23
+ return { routes, resources, user };
25
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"access.user.post.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.user.post.ts"],"names":[],"mappings":"AAIA,wBAA8B,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAyDhE"}
1
+ {"version":3,"file":"access.user.post.d.ts","sourceRoot":"","sources":["../../../../../server/routes/access/controllers/access.user.post.ts"],"names":[],"mappings":"AAKA,wBAA8B,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,gBAuDhE"}
@@ -1,14 +1,13 @@
1
+ import { BadRequestError, UnauthorizedError } from "../../../../errors.js";
1
2
  import { pgClients } from "../../../../utils.js";
2
3
  import accessUser from "./access.user.js";
3
4
  export default async function accessUserPost(req, reply) {
4
5
  const { pg = pgClients.client, params, body, user } = req;
5
6
  if (!params?.id) {
6
- return reply
7
- .status(400)
8
- .send({ error: "not enough params: id", code: 400 });
7
+ throw BadRequestError("not enough params: id");
9
8
  }
10
9
  if (!user?.uid) {
11
- return reply.status(401).send({ error: "unauthorized", code: 401 });
10
+ throw UnauthorizedError("unauthorized");
12
11
  }
13
12
  await pg.query("delete from admin.role_access where user_uid=$1", [
14
13
  params.id,
@@ -28,6 +27,6 @@ export default async function accessUserPost(req, reply) {
28
27
  await Promise.all(body.routes
29
28
  .filter((el) => el.resource && el.actions)
30
29
  .map((el) => pg.query("insert into admin.role_access(user_uid,resource_id,actions) values ($1,$2,$3)", [params.id, el.resource, el.actions])));
31
- const result = await accessUser({ pg, params }, reply);
30
+ const result = await accessUser({ pg, params });
32
31
  return result;
33
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/routes/access/index.ts"],"names":[],"mappings":"AAgBA,wBAA8B,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAE,GAAQ,iBA8B9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/routes/access/index.ts"],"names":[],"mappings":"AAkBA,wBAA8B,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAE,GAAQ,iBAqC9D"}