@streetjs/storage 1.0.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 (363) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +719 -0
  3. package/dist/access.d.ts +95 -0
  4. package/dist/access.d.ts.map +1 -0
  5. package/dist/access.js +114 -0
  6. package/dist/access.js.map +1 -0
  7. package/dist/cli/commands.d.ts +88 -0
  8. package/dist/cli/commands.d.ts.map +1 -0
  9. package/dist/cli/commands.js +369 -0
  10. package/dist/cli/commands.js.map +1 -0
  11. package/dist/cli/generators.d.ts +41 -0
  12. package/dist/cli/generators.d.ts.map +1 -0
  13. package/dist/cli/generators.js +119 -0
  14. package/dist/cli/generators.js.map +1 -0
  15. package/dist/directory.d.ts +88 -0
  16. package/dist/directory.d.ts.map +1 -0
  17. package/dist/directory.js +148 -0
  18. package/dist/directory.js.map +1 -0
  19. package/dist/driver.d.ts +83 -0
  20. package/dist/driver.d.ts.map +1 -0
  21. package/dist/driver.js +16 -0
  22. package/dist/driver.js.map +1 -0
  23. package/dist/drivers/azure.d.ts +239 -0
  24. package/dist/drivers/azure.d.ts.map +1 -0
  25. package/dist/drivers/azure.js +476 -0
  26. package/dist/drivers/azure.js.map +1 -0
  27. package/dist/drivers/backblaze.d.ts +105 -0
  28. package/dist/drivers/backblaze.d.ts.map +1 -0
  29. package/dist/drivers/backblaze.js +279 -0
  30. package/dist/drivers/backblaze.js.map +1 -0
  31. package/dist/drivers/gcs.d.ts +239 -0
  32. package/dist/drivers/gcs.d.ts.map +1 -0
  33. package/dist/drivers/gcs.js +454 -0
  34. package/dist/drivers/gcs.js.map +1 -0
  35. package/dist/drivers/local.d.ts +126 -0
  36. package/dist/drivers/local.d.ts.map +1 -0
  37. package/dist/drivers/local.js +321 -0
  38. package/dist/drivers/local.js.map +1 -0
  39. package/dist/drivers/memory.d.ts +104 -0
  40. package/dist/drivers/memory.d.ts.map +1 -0
  41. package/dist/drivers/memory.js +197 -0
  42. package/dist/drivers/memory.js.map +1 -0
  43. package/dist/drivers/minio.d.ts +90 -0
  44. package/dist/drivers/minio.d.ts.map +1 -0
  45. package/dist/drivers/minio.js +276 -0
  46. package/dist/drivers/minio.js.map +1 -0
  47. package/dist/drivers/r2.d.ts +100 -0
  48. package/dist/drivers/r2.d.ts.map +1 -0
  49. package/dist/drivers/r2.js +240 -0
  50. package/dist/drivers/r2.js.map +1 -0
  51. package/dist/drivers/s3-base.d.ts +270 -0
  52. package/dist/drivers/s3-base.d.ts.map +1 -0
  53. package/dist/drivers/s3-base.js +436 -0
  54. package/dist/drivers/s3-base.js.map +1 -0
  55. package/dist/drivers/s3.d.ts +111 -0
  56. package/dist/drivers/s3.d.ts.map +1 -0
  57. package/dist/drivers/s3.js +311 -0
  58. package/dist/drivers/s3.js.map +1 -0
  59. package/dist/drivers/supabase.d.ts +246 -0
  60. package/dist/drivers/supabase.d.ts.map +1 -0
  61. package/dist/drivers/supabase.js +502 -0
  62. package/dist/drivers/supabase.js.map +1 -0
  63. package/dist/errors.d.ts +115 -0
  64. package/dist/errors.d.ts.map +1 -0
  65. package/dist/errors.js +131 -0
  66. package/dist/errors.js.map +1 -0
  67. package/dist/examples/storage-demo.d.ts +53 -0
  68. package/dist/examples/storage-demo.d.ts.map +1 -0
  69. package/dist/examples/storage-demo.js +242 -0
  70. package/dist/examples/storage-demo.js.map +1 -0
  71. package/dist/facade.d.ts +192 -0
  72. package/dist/facade.d.ts.map +1 -0
  73. package/dist/facade.js +898 -0
  74. package/dist/facade.js.map +1 -0
  75. package/dist/image.d.ts +94 -0
  76. package/dist/image.d.ts.map +1 -0
  77. package/dist/image.js +224 -0
  78. package/dist/image.js.map +1 -0
  79. package/dist/index.d.ts +47 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +53 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/integrations/events.d.ts +108 -0
  84. package/dist/integrations/events.d.ts.map +1 -0
  85. package/dist/integrations/events.js +111 -0
  86. package/dist/integrations/events.js.map +1 -0
  87. package/dist/integrations/queue.d.ts +89 -0
  88. package/dist/integrations/queue.d.ts.map +1 -0
  89. package/dist/integrations/queue.js +91 -0
  90. package/dist/integrations/queue.js.map +1 -0
  91. package/dist/integrations/realtime.d.ts +95 -0
  92. package/dist/integrations/realtime.d.ts.map +1 -0
  93. package/dist/integrations/realtime.js +90 -0
  94. package/dist/integrations/realtime.js.map +1 -0
  95. package/dist/lifecycle.d.ts +137 -0
  96. package/dist/lifecycle.d.ts.map +1 -0
  97. package/dist/lifecycle.js +240 -0
  98. package/dist/lifecycle.js.map +1 -0
  99. package/dist/metadata.d.ts +109 -0
  100. package/dist/metadata.d.ts.map +1 -0
  101. package/dist/metadata.js +139 -0
  102. package/dist/metadata.js.map +1 -0
  103. package/dist/multipart.d.ts +108 -0
  104. package/dist/multipart.d.ts.map +1 -0
  105. package/dist/multipart.js +200 -0
  106. package/dist/multipart.js.map +1 -0
  107. package/dist/observability.d.ts +82 -0
  108. package/dist/observability.d.ts.map +1 -0
  109. package/dist/observability.js +175 -0
  110. package/dist/observability.js.map +1 -0
  111. package/dist/plugin.d.ts +82 -0
  112. package/dist/plugin.d.ts.map +1 -0
  113. package/dist/plugin.js +100 -0
  114. package/dist/plugin.js.map +1 -0
  115. package/dist/resumable.d.ts +118 -0
  116. package/dist/resumable.d.ts.map +1 -0
  117. package/dist/resumable.js +223 -0
  118. package/dist/resumable.js.map +1 -0
  119. package/dist/search.d.ts +57 -0
  120. package/dist/search.d.ts.map +1 -0
  121. package/dist/search.js +172 -0
  122. package/dist/search.js.map +1 -0
  123. package/dist/signed-url.d.ts +110 -0
  124. package/dist/signed-url.d.ts.map +1 -0
  125. package/dist/signed-url.js +237 -0
  126. package/dist/signed-url.js.map +1 -0
  127. package/dist/testing/index.d.ts +219 -0
  128. package/dist/testing/index.d.ts.map +1 -0
  129. package/dist/testing/index.js +393 -0
  130. package/dist/testing/index.js.map +1 -0
  131. package/dist/tests/access.test.d.ts +2 -0
  132. package/dist/tests/access.test.d.ts.map +1 -0
  133. package/dist/tests/access.test.js +270 -0
  134. package/dist/tests/access.test.js.map +1 -0
  135. package/dist/tests/azure-driver.test.d.ts +2 -0
  136. package/dist/tests/azure-driver.test.d.ts.map +1 -0
  137. package/dist/tests/azure-driver.test.js +183 -0
  138. package/dist/tests/azure-driver.test.js.map +1 -0
  139. package/dist/tests/backblaze-driver.test.d.ts +2 -0
  140. package/dist/tests/backblaze-driver.test.d.ts.map +1 -0
  141. package/dist/tests/backblaze-driver.test.js +185 -0
  142. package/dist/tests/backblaze-driver.test.js.map +1 -0
  143. package/dist/tests/bridge-degradation.test.d.ts +2 -0
  144. package/dist/tests/bridge-degradation.test.d.ts.map +1 -0
  145. package/dist/tests/bridge-degradation.test.js +138 -0
  146. package/dist/tests/bridge-degradation.test.js.map +1 -0
  147. package/dist/tests/cli.test.d.ts +2 -0
  148. package/dist/tests/cli.test.d.ts.map +1 -0
  149. package/dist/tests/cli.test.js +127 -0
  150. package/dist/tests/cli.test.js.map +1 -0
  151. package/dist/tests/contract.d.ts +131 -0
  152. package/dist/tests/contract.d.ts.map +1 -0
  153. package/dist/tests/contract.js +222 -0
  154. package/dist/tests/contract.js.map +1 -0
  155. package/dist/tests/contract.test.d.ts +2 -0
  156. package/dist/tests/contract.test.d.ts.map +1 -0
  157. package/dist/tests/contract.test.js +110 -0
  158. package/dist/tests/contract.test.js.map +1 -0
  159. package/dist/tests/directory.test.d.ts +2 -0
  160. package/dist/tests/directory.test.d.ts.map +1 -0
  161. package/dist/tests/directory.test.js +125 -0
  162. package/dist/tests/directory.test.js.map +1 -0
  163. package/dist/tests/errors.test.d.ts +2 -0
  164. package/dist/tests/errors.test.d.ts.map +1 -0
  165. package/dist/tests/errors.test.js +93 -0
  166. package/dist/tests/errors.test.js.map +1 -0
  167. package/dist/tests/events-bridge.test.d.ts +2 -0
  168. package/dist/tests/events-bridge.test.d.ts.map +1 -0
  169. package/dist/tests/events-bridge.test.js +228 -0
  170. package/dist/tests/events-bridge.test.js.map +1 -0
  171. package/dist/tests/example-smoke.test.d.ts +2 -0
  172. package/dist/tests/example-smoke.test.d.ts.map +1 -0
  173. package/dist/tests/example-smoke.test.js +34 -0
  174. package/dist/tests/example-smoke.test.js.map +1 -0
  175. package/dist/tests/gcs-driver.test.d.ts +2 -0
  176. package/dist/tests/gcs-driver.test.d.ts.map +1 -0
  177. package/dist/tests/gcs-driver.test.js +197 -0
  178. package/dist/tests/gcs-driver.test.js.map +1 -0
  179. package/dist/tests/image.test.d.ts +2 -0
  180. package/dist/tests/image.test.d.ts.map +1 -0
  181. package/dist/tests/image.test.js +102 -0
  182. package/dist/tests/image.test.js.map +1 -0
  183. package/dist/tests/lifecycle.test.d.ts +2 -0
  184. package/dist/tests/lifecycle.test.d.ts.map +1 -0
  185. package/dist/tests/lifecycle.test.js +171 -0
  186. package/dist/tests/lifecycle.test.js.map +1 -0
  187. package/dist/tests/local-driver.test.d.ts +2 -0
  188. package/dist/tests/local-driver.test.d.ts.map +1 -0
  189. package/dist/tests/local-driver.test.js +153 -0
  190. package/dist/tests/local-driver.test.js.map +1 -0
  191. package/dist/tests/local-streaming.test.d.ts +2 -0
  192. package/dist/tests/local-streaming.test.d.ts.map +1 -0
  193. package/dist/tests/local-streaming.test.js +121 -0
  194. package/dist/tests/local-streaming.test.js.map +1 -0
  195. package/dist/tests/memory-driver.test.d.ts +2 -0
  196. package/dist/tests/memory-driver.test.d.ts.map +1 -0
  197. package/dist/tests/memory-driver.test.js +180 -0
  198. package/dist/tests/memory-driver.test.js.map +1 -0
  199. package/dist/tests/memory-streaming.test.d.ts +2 -0
  200. package/dist/tests/memory-streaming.test.d.ts.map +1 -0
  201. package/dist/tests/memory-streaming.test.js +92 -0
  202. package/dist/tests/memory-streaming.test.js.map +1 -0
  203. package/dist/tests/minio-driver.test.d.ts +2 -0
  204. package/dist/tests/minio-driver.test.d.ts.map +1 -0
  205. package/dist/tests/minio-driver.test.js +146 -0
  206. package/dist/tests/minio-driver.test.js.map +1 -0
  207. package/dist/tests/non-s3-integration.test.d.ts +2 -0
  208. package/dist/tests/non-s3-integration.test.d.ts.map +1 -0
  209. package/dist/tests/non-s3-integration.test.js +201 -0
  210. package/dist/tests/non-s3-integration.test.js.map +1 -0
  211. package/dist/tests/observability.registration.test.d.ts +2 -0
  212. package/dist/tests/observability.registration.test.d.ts.map +1 -0
  213. package/dist/tests/observability.registration.test.js +103 -0
  214. package/dist/tests/observability.registration.test.js.map +1 -0
  215. package/dist/tests/observability.test.d.ts +2 -0
  216. package/dist/tests/observability.test.d.ts.map +1 -0
  217. package/dist/tests/observability.test.js +240 -0
  218. package/dist/tests/observability.test.js.map +1 -0
  219. package/dist/tests/plugin.test.d.ts +2 -0
  220. package/dist/tests/plugin.test.d.ts.map +1 -0
  221. package/dist/tests/plugin.test.js +112 -0
  222. package/dist/tests/plugin.test.js.map +1 -0
  223. package/dist/tests/prop-concurrent.test.d.ts +2 -0
  224. package/dist/tests/prop-concurrent.test.d.ts.map +1 -0
  225. package/dist/tests/prop-concurrent.test.js +59 -0
  226. package/dist/tests/prop-concurrent.test.js.map +1 -0
  227. package/dist/tests/prop-copy.test.d.ts +2 -0
  228. package/dist/tests/prop-copy.test.d.ts.map +1 -0
  229. package/dist/tests/prop-copy.test.js +63 -0
  230. package/dist/tests/prop-copy.test.js.map +1 -0
  231. package/dist/tests/prop-delete.test.d.ts +2 -0
  232. package/dist/tests/prop-delete.test.d.ts.map +1 -0
  233. package/dist/tests/prop-delete.test.js +35 -0
  234. package/dist/tests/prop-delete.test.js.map +1 -0
  235. package/dist/tests/prop-directory.test.d.ts +2 -0
  236. package/dist/tests/prop-directory.test.d.ts.map +1 -0
  237. package/dist/tests/prop-directory.test.js +118 -0
  238. package/dist/tests/prop-directory.test.js.map +1 -0
  239. package/dist/tests/prop-driver-conformance.test.d.ts +2 -0
  240. package/dist/tests/prop-driver-conformance.test.d.ts.map +1 -0
  241. package/dist/tests/prop-driver-conformance.test.js +110 -0
  242. package/dist/tests/prop-driver-conformance.test.js.map +1 -0
  243. package/dist/tests/prop-driver-equivalence.test.d.ts +2 -0
  244. package/dist/tests/prop-driver-equivalence.test.d.ts.map +1 -0
  245. package/dist/tests/prop-driver-equivalence.test.js +163 -0
  246. package/dist/tests/prop-driver-equivalence.test.js.map +1 -0
  247. package/dist/tests/prop-lifecycle.test.d.ts +2 -0
  248. package/dist/tests/prop-lifecycle.test.d.ts.map +1 -0
  249. package/dist/tests/prop-lifecycle.test.js +83 -0
  250. package/dist/tests/prop-lifecycle.test.js.map +1 -0
  251. package/dist/tests/prop-list.test.d.ts +2 -0
  252. package/dist/tests/prop-list.test.d.ts.map +1 -0
  253. package/dist/tests/prop-list.test.js +53 -0
  254. package/dist/tests/prop-list.test.js.map +1 -0
  255. package/dist/tests/prop-metadata.test.d.ts +2 -0
  256. package/dist/tests/prop-metadata.test.d.ts.map +1 -0
  257. package/dist/tests/prop-metadata.test.js +87 -0
  258. package/dist/tests/prop-metadata.test.js.map +1 -0
  259. package/dist/tests/prop-move.test.d.ts +2 -0
  260. package/dist/tests/prop-move.test.d.ts.map +1 -0
  261. package/dist/tests/prop-move.test.js +67 -0
  262. package/dist/tests/prop-move.test.js.map +1 -0
  263. package/dist/tests/prop-multipart-abort.test.d.ts +2 -0
  264. package/dist/tests/prop-multipart-abort.test.d.ts.map +1 -0
  265. package/dist/tests/prop-multipart-abort.test.js +48 -0
  266. package/dist/tests/prop-multipart-abort.test.js.map +1 -0
  267. package/dist/tests/prop-multipart.test.d.ts +2 -0
  268. package/dist/tests/prop-multipart.test.d.ts.map +1 -0
  269. package/dist/tests/prop-multipart.test.js +65 -0
  270. package/dist/tests/prop-multipart.test.js.map +1 -0
  271. package/dist/tests/prop-resumable.test.d.ts +2 -0
  272. package/dist/tests/prop-resumable.test.d.ts.map +1 -0
  273. package/dist/tests/prop-resumable.test.js +78 -0
  274. package/dist/tests/prop-resumable.test.js.map +1 -0
  275. package/dist/tests/prop-search.test.d.ts +2 -0
  276. package/dist/tests/prop-search.test.d.ts.map +1 -0
  277. package/dist/tests/prop-search.test.js +120 -0
  278. package/dist/tests/prop-search.test.js.map +1 -0
  279. package/dist/tests/prop-signed-url.test.d.ts +2 -0
  280. package/dist/tests/prop-signed-url.test.d.ts.map +1 -0
  281. package/dist/tests/prop-signed-url.test.js +74 -0
  282. package/dist/tests/prop-signed-url.test.js.map +1 -0
  283. package/dist/tests/prop-streaming.test.d.ts +2 -0
  284. package/dist/tests/prop-streaming.test.d.ts.map +1 -0
  285. package/dist/tests/prop-streaming.test.js +34 -0
  286. package/dist/tests/prop-streaming.test.js.map +1 -0
  287. package/dist/tests/prop-upload-download.test.d.ts +2 -0
  288. package/dist/tests/prop-upload-download.test.d.ts.map +1 -0
  289. package/dist/tests/prop-upload-download.test.js +30 -0
  290. package/dist/tests/prop-upload-download.test.js.map +1 -0
  291. package/dist/tests/prop-validation.test.d.ts +2 -0
  292. package/dist/tests/prop-validation.test.d.ts.map +1 -0
  293. package/dist/tests/prop-validation.test.js +50 -0
  294. package/dist/tests/prop-validation.test.js.map +1 -0
  295. package/dist/tests/prop-versioning.test.d.ts +2 -0
  296. package/dist/tests/prop-versioning.test.d.ts.map +1 -0
  297. package/dist/tests/prop-versioning.test.js +74 -0
  298. package/dist/tests/prop-versioning.test.js.map +1 -0
  299. package/dist/tests/queue-bridge.test.d.ts +2 -0
  300. package/dist/tests/queue-bridge.test.d.ts.map +1 -0
  301. package/dist/tests/queue-bridge.test.js +111 -0
  302. package/dist/tests/queue-bridge.test.js.map +1 -0
  303. package/dist/tests/r2-driver.test.d.ts +2 -0
  304. package/dist/tests/r2-driver.test.d.ts.map +1 -0
  305. package/dist/tests/r2-driver.test.js +143 -0
  306. package/dist/tests/r2-driver.test.js.map +1 -0
  307. package/dist/tests/realtime-bridge.test.d.ts +2 -0
  308. package/dist/tests/realtime-bridge.test.d.ts.map +1 -0
  309. package/dist/tests/realtime-bridge.test.js +106 -0
  310. package/dist/tests/realtime-bridge.test.js.map +1 -0
  311. package/dist/tests/resumable.test.d.ts +2 -0
  312. package/dist/tests/resumable.test.d.ts.map +1 -0
  313. package/dist/tests/resumable.test.js +104 -0
  314. package/dist/tests/resumable.test.js.map +1 -0
  315. package/dist/tests/s3-base.test.d.ts +2 -0
  316. package/dist/tests/s3-base.test.d.ts.map +1 -0
  317. package/dist/tests/s3-base.test.js +289 -0
  318. package/dist/tests/s3-base.test.js.map +1 -0
  319. package/dist/tests/s3-integration.test.d.ts +2 -0
  320. package/dist/tests/s3-integration.test.d.ts.map +1 -0
  321. package/dist/tests/s3-integration.test.js +270 -0
  322. package/dist/tests/s3-integration.test.js.map +1 -0
  323. package/dist/tests/s3.test.d.ts +2 -0
  324. package/dist/tests/s3.test.d.ts.map +1 -0
  325. package/dist/tests/s3.test.js +203 -0
  326. package/dist/tests/s3.test.js.map +1 -0
  327. package/dist/tests/scaffold.test.d.ts +2 -0
  328. package/dist/tests/scaffold.test.d.ts.map +1 -0
  329. package/dist/tests/scaffold.test.js +13 -0
  330. package/dist/tests/scaffold.test.js.map +1 -0
  331. package/dist/tests/search.test.d.ts +2 -0
  332. package/dist/tests/search.test.d.ts.map +1 -0
  333. package/dist/tests/search.test.js +106 -0
  334. package/dist/tests/search.test.js.map +1 -0
  335. package/dist/tests/supabase-driver.test.d.ts +2 -0
  336. package/dist/tests/supabase-driver.test.d.ts.map +1 -0
  337. package/dist/tests/supabase-driver.test.js +196 -0
  338. package/dist/tests/supabase-driver.test.js.map +1 -0
  339. package/dist/tests/testing-utilities.test.d.ts +2 -0
  340. package/dist/tests/testing-utilities.test.d.ts.map +1 -0
  341. package/dist/tests/testing-utilities.test.js +138 -0
  342. package/dist/tests/testing-utilities.test.js.map +1 -0
  343. package/dist/tests/validation.test.d.ts +2 -0
  344. package/dist/tests/validation.test.d.ts.map +1 -0
  345. package/dist/tests/validation.test.js +135 -0
  346. package/dist/tests/validation.test.js.map +1 -0
  347. package/dist/tests/versioning.test.d.ts +2 -0
  348. package/dist/tests/versioning.test.d.ts.map +1 -0
  349. package/dist/tests/versioning.test.js +128 -0
  350. package/dist/tests/versioning.test.js.map +1 -0
  351. package/dist/types.d.ts +232 -0
  352. package/dist/types.d.ts.map +1 -0
  353. package/dist/types.js +23 -0
  354. package/dist/types.js.map +1 -0
  355. package/dist/validation.d.ts +105 -0
  356. package/dist/validation.d.ts.map +1 -0
  357. package/dist/validation.js +225 -0
  358. package/dist/validation.js.map +1 -0
  359. package/dist/versioning.d.ts +100 -0
  360. package/dist/versioning.d.ts.map +1 -0
  361. package/dist/versioning.js +179 -0
  362. package/dist/versioning.js.map +1 -0
  363. package/package.json +137 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,100 @@
1
+ // src/plugin.ts
2
+ // @streetjs/storage — plugin registration entry point (reuses the core
3
+ // PluginModule / SandboxedApp).
4
+ //
5
+ // `StoragePlugin.onLoad` constructs the facade via `createStorage`, which wires
6
+ // observability (health check + metrics) against the `metrics` / `health`
7
+ // registries supplied on the plugin options, applies the declarative bridge
8
+ // wiring, and exposes the live facade through the `storage` accessor.
9
+ // `onUnload` detaches the bridges and closes the facade gracefully
10
+ // (`storage.close()` stops the observability refresh timer).
11
+ //
12
+ // The `SandboxedApp` handed to a plugin exposes only `use` / `on` — it has no
13
+ // registry to attach to — so the health / metrics registries are resolved from
14
+ // the plugin options (mirroring how the events / queue / realtime plugins
15
+ // resolve theirs). The plugin never touches any existing public API: it only
16
+ // consumes the already-public `createStorage` surface (Requirements 20.1,
17
+ // 20.2, 20.3).
18
+ import { PluginModule } from "streetjs";
19
+ import { createStorage } from "./facade.js";
20
+ /**
21
+ * Plugin entry point that constructs and wires the application storage layer.
22
+ *
23
+ * Compatible with the core {@link PluginModule} and safe to register with a
24
+ * `SandboxedApp` (Requirements 20.1, 20.2). Once loaded, the application
25
+ * retrieves the live {@link Storage} facade through the {@link storage}
26
+ * accessor without any existing public API being modified (Requirement 20.3).
27
+ *
28
+ * @typeParam T - Optional per-application custom metadata map.
29
+ */
30
+ export class StoragePlugin extends PluginModule {
31
+ name = "@streetjs/storage";
32
+ version = "1.0.0";
33
+ options;
34
+ storageInstance;
35
+ bridgeDetachers = [];
36
+ constructor(options) {
37
+ super();
38
+ this.options = options;
39
+ }
40
+ /**
41
+ * The constructed facade, or `undefined` before load / after unload. Because
42
+ * the `SandboxedApp` has no registry to attach to, the application retrieves
43
+ * the live {@link Storage} facade through this accessor after the plugin
44
+ * loads (Requirement 20.3).
45
+ */
46
+ get storage() {
47
+ return this.storageInstance;
48
+ }
49
+ /**
50
+ * Construct the facade (which wires observability from the configured
51
+ * `metrics` / `health` registries and the structural bridges), apply the
52
+ * declarative bridge wiring collecting any detach functions, and expose the
53
+ * facade. Idempotent per load: a second `onLoad` without an intervening
54
+ * `onUnload` reuses the already-constructed facade.
55
+ */
56
+ async onLoad(_app) {
57
+ if (this.storageInstance) {
58
+ return;
59
+ }
60
+ // `createStorage` resolves the driver and, when `metrics` / `health` are
61
+ // present on the config, registers storage observability against those
62
+ // registries and primes the gauges — so passing the plugin options through
63
+ // as the StorageConfig wires observability from the plugin-option
64
+ // registries (Requirement 23.1, 23.3). The structural events / queue /
65
+ // realtime bridges on `options.bridges` are likewise wired by the facade.
66
+ const storage = createStorage(this.options);
67
+ this.storageInstance = storage;
68
+ // Apply declarative bridge wiring, collecting any detach functions so
69
+ // onUnload can tear them down.
70
+ for (const attach of this.options.wireBridges ?? []) {
71
+ const detach = attach(storage);
72
+ if (typeof detach === "function") {
73
+ this.bridgeDetachers.push(detach);
74
+ }
75
+ }
76
+ }
77
+ /**
78
+ * Detach the declarative bridges and close the facade gracefully (which stops
79
+ * the observability refresh timer). Safe if never loaded.
80
+ */
81
+ async onUnload(_app) {
82
+ const storage = this.storageInstance;
83
+ const detachers = this.bridgeDetachers;
84
+ this.storageInstance = undefined;
85
+ this.bridgeDetachers = [];
86
+ // Detach bridges first so no bridge fires during/after teardown.
87
+ for (const detach of detachers) {
88
+ try {
89
+ detach();
90
+ }
91
+ catch {
92
+ /* best-effort detach */
93
+ }
94
+ }
95
+ if (storage) {
96
+ await storage.close();
97
+ }
98
+ }
99
+ }
100
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,uEAAuE;AACvE,gCAAgC;AAChC,EAAE;AACF,gFAAgF;AAChF,0EAA0E;AAC1E,4EAA4E;AAC5E,sEAAsE;AACtE,mEAAmE;AACnE,6DAA6D;AAC7D,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,0EAA0E;AAC1E,6EAA6E;AAC7E,0EAA0E;AAC1E,eAAe;AAEf,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AA4C1D;;;;;;;;;GASG;AACH,MAAM,OAAO,aAEX,SAAQ,YAAY;IACX,IAAI,GAAG,mBAAmB,CAAC;IAC3B,OAAO,GAAG,OAAO,CAAC;IAER,OAAO,CAA0B;IAE5C,eAAe,CAAc;IAC7B,eAAe,GAAsB,EAAE,CAAC;IAEhD,YAAY,OAAgC;QAC1C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACM,KAAK,CAAC,MAAM,CAAC,IAAkB;QACtC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,kEAAkE;QAClE,uEAAuE;QACvE,0EAA0E;QAC1E,MAAM,OAAO,GAAG,aAAa,CAAI,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAE/B,sEAAsE;QACtE,+BAA+B;QAC/B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAC/B,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACM,KAAK,CAAC,QAAQ,CAAC,IAAkB;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,iEAAiE;QACjE,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC;YACX,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;QACH,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @streetjs/storage — the resumable upload manager.
3
+ *
4
+ * A {@link Resumable_Upload} is an upload session that can be interrupted and
5
+ * continued from the last persisted byte offset without restarting from the
6
+ * beginning (Requirement 7). {@link ResumableManager} provides this capability
7
+ * in a **provider-agnostic** way, mirroring {@link MultipartManager}:
8
+ *
9
+ * - When the backing {@link StorageDriver} implements the optional native
10
+ * `resumable` capability, the manager delegates to the driver so a provider
11
+ * with first-class resumable support (e.g. GCS resumable uploads) is used
12
+ * directly.
13
+ * - Otherwise the manager **simulates** resumable sessions over the mandatory
14
+ * driver primitives (`put`/`get`/`delete`). The accumulated bytes for a
15
+ * session are persisted under a reserved key derived from the session id
16
+ * (mirroring the design's `.resumable/<sessionId>` layout), and the persisted
17
+ * byte offset is simply the length of that accumulated content.
18
+ *
19
+ * Semantics (Requirement 7):
20
+ * - {@link ResumableManager.start} creates a session and returns a session id
21
+ * (Requirement 7.1); the persisted offset begins at zero.
22
+ * - {@link ResumableManager.resume} continues the upload from the last persisted
23
+ * offset (Requirement 7.2). The supplied stream carries the object's **full**
24
+ * intended content from offset zero; the manager appends only the portion of
25
+ * the stream that lies beyond the already-persisted offset and skips the bytes
26
+ * it already holds. Because the final object is exactly the full stream
27
+ * content regardless of how many times the upload was interrupted and resumed,
28
+ * completion yields an object byte-identical to an equivalent uninterrupted
29
+ * upload (Requirement 7.3).
30
+ * - {@link ResumableManager.cancel} discards the session and its persisted data,
31
+ * creating no object (Requirement 7.4) — **unless** the session is already
32
+ * completing (its stream has been fully consumed and the final object is being
33
+ * written), in which case the cancel is ignored and the upload is allowed to
34
+ * finish and create the object (Requirement 7.5).
35
+ *
36
+ * The module depends only on the driver contract, the shared type surface, the
37
+ * error hierarchy, and the metadata layer, keeping the dependency direction
38
+ * acyclic.
39
+ *
40
+ * _Requirements: 7.1, 7.2, 7.3, 7.4, 7.5_
41
+ */
42
+ import type { NodeReadable, StorageDriver } from "./driver.js";
43
+ import type { StorageObjectMetadata, WriteMetadata } from "./types.js";
44
+ /**
45
+ * Provider-agnostic resumable upload manager built on the driver contract.
46
+ *
47
+ * A single instance is held by the facade and bound to one {@link StorageDriver}
48
+ * for its lifetime, so the native-vs-simulated decision (based on whether the
49
+ * driver exposes a `resumable` capability) is stable across every call for a
50
+ * given session id.
51
+ */
52
+ export declare class ResumableManager {
53
+ /** The driver every operation is delegated to or simulated over. */
54
+ private readonly driver;
55
+ /**
56
+ * In-progress simulated sessions keyed by session id. Empty when the driver
57
+ * provides a native `resumable` capability (that path keeps no local state).
58
+ */
59
+ private readonly sessions;
60
+ constructor(driver: StorageDriver);
61
+ /** The driver's native resumable capability, when present. */
62
+ private get native();
63
+ /**
64
+ * Create a resumable upload session for `key` and return its session id
65
+ * (Requirement 7.1). When the driver has a native capability the driver mints
66
+ * the id and initializes the offset; otherwise a fresh id is generated and a
67
+ * local session records the target key and its write-time metadata. No
68
+ * reserved key is written yet — the persisted offset is zero until the first
69
+ * `resume` appends content.
70
+ */
71
+ start(key: string, metadata: WriteMetadata): Promise<string>;
72
+ /**
73
+ * Continue the upload for `sessionId` from the last persisted offset and, on
74
+ * completion, create the final object and return its metadata (Requirements
75
+ * 7.2, 7.3).
76
+ *
77
+ * `stream` carries the object's full intended content from offset zero. The
78
+ * manager appends only the bytes lying beyond the already-persisted offset —
79
+ * bytes it already holds are skipped — so the final object equals the full
80
+ * stream content and is byte-identical to an equivalent uninterrupted upload
81
+ * regardless of how many prior interruptions occurred.
82
+ *
83
+ * Once the stream is fully consumed the session enters its completing phase;
84
+ * from that point a concurrent {@link cancel} is ignored so the object is
85
+ * still created (Requirement 7.5). If a cancel arrives *before* completion,
86
+ * the in-progress resume aborts and creates no object (Requirement 7.4).
87
+ */
88
+ resume(sessionId: string, stream: NodeReadable): Promise<StorageObjectMetadata>;
89
+ /**
90
+ * Discard the session `sessionId` and its persisted data, creating no object
91
+ * (Requirement 7.4). If the session is already completing — its stream has
92
+ * been fully consumed and the final object is being written — the cancel is
93
+ * ignored so the upload finishes and creates the object (Requirement 7.5). An
94
+ * unknown/already-finalized session id is treated as an idempotent no-op.
95
+ */
96
+ cancel(sessionId: string): Promise<void>;
97
+ /**
98
+ * Native-capability resume: drive the driver's `offset`/`append`/`finish`
99
+ * primitives. As in the simulated path, `stream` carries the full content and
100
+ * only the portion beyond the driver's reported offset is appended, so the
101
+ * finished object is byte-identical to an uninterrupted upload.
102
+ */
103
+ private resumeNative;
104
+ /**
105
+ * Read the accumulated bytes persisted for a simulated session, returning an
106
+ * empty buffer when nothing has been persisted yet (offset zero).
107
+ */
108
+ private readPersisted;
109
+ /** The reserved driver key a simulated session's accumulated bytes live under. */
110
+ private sessionKey;
111
+ /**
112
+ * Resolve the simulated session for `sessionId`, throwing a descriptive
113
+ * {@link StorageError} when the id is unknown or the session has already been
114
+ * finalized or cancelled.
115
+ */
116
+ private requireSession;
117
+ }
118
+ //# sourceMappingURL=resumable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resumable.d.ts","sourceRoot":"","sources":["../src/resumable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAuB,aAAa,EAAE,MAAM,aAAa,CAAC;AAGpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqCvE;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAC3B,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;gBAEpD,MAAM,EAAE,aAAa;IAIjC,8DAA8D;IAC9D,OAAO,KAAK,MAAM,GAEjB;IAED;;;;;;;OAOG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IASlE;;;;;;;;;;;;;;;OAeG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAqDrF;;;;;;OAMG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB9C;;;;;OAKG;YACW,YAAY;IAsB1B;;;OAGG;YACW,aAAa;IAK3B,kFAAkF;IAClF,OAAO,CAAC,UAAU;IAIlB;;;;OAIG;IACH,OAAO,CAAC,cAAc;CASvB"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * @streetjs/storage — the resumable upload manager.
3
+ *
4
+ * A {@link Resumable_Upload} is an upload session that can be interrupted and
5
+ * continued from the last persisted byte offset without restarting from the
6
+ * beginning (Requirement 7). {@link ResumableManager} provides this capability
7
+ * in a **provider-agnostic** way, mirroring {@link MultipartManager}:
8
+ *
9
+ * - When the backing {@link StorageDriver} implements the optional native
10
+ * `resumable` capability, the manager delegates to the driver so a provider
11
+ * with first-class resumable support (e.g. GCS resumable uploads) is used
12
+ * directly.
13
+ * - Otherwise the manager **simulates** resumable sessions over the mandatory
14
+ * driver primitives (`put`/`get`/`delete`). The accumulated bytes for a
15
+ * session are persisted under a reserved key derived from the session id
16
+ * (mirroring the design's `.resumable/<sessionId>` layout), and the persisted
17
+ * byte offset is simply the length of that accumulated content.
18
+ *
19
+ * Semantics (Requirement 7):
20
+ * - {@link ResumableManager.start} creates a session and returns a session id
21
+ * (Requirement 7.1); the persisted offset begins at zero.
22
+ * - {@link ResumableManager.resume} continues the upload from the last persisted
23
+ * offset (Requirement 7.2). The supplied stream carries the object's **full**
24
+ * intended content from offset zero; the manager appends only the portion of
25
+ * the stream that lies beyond the already-persisted offset and skips the bytes
26
+ * it already holds. Because the final object is exactly the full stream
27
+ * content regardless of how many times the upload was interrupted and resumed,
28
+ * completion yields an object byte-identical to an equivalent uninterrupted
29
+ * upload (Requirement 7.3).
30
+ * - {@link ResumableManager.cancel} discards the session and its persisted data,
31
+ * creating no object (Requirement 7.4) — **unless** the session is already
32
+ * completing (its stream has been fully consumed and the final object is being
33
+ * written), in which case the cancel is ignored and the upload is allowed to
34
+ * finish and create the object (Requirement 7.5).
35
+ *
36
+ * The module depends only on the driver contract, the shared type surface, the
37
+ * error hierarchy, and the metadata layer, keeping the dependency direction
38
+ * acyclic.
39
+ *
40
+ * _Requirements: 7.1, 7.2, 7.3, 7.4, 7.5_
41
+ */
42
+ import { Buffer } from "node:buffer";
43
+ import { randomUUID } from "node:crypto";
44
+ import { StorageError } from "./errors.js";
45
+ import { normalizeMetadata } from "./metadata.js";
46
+ /**
47
+ * Reserved key prefix under which a simulated session's accumulated bytes are
48
+ * persisted via the driver primitives. Session content lives at
49
+ * `${SESSION_KEY_PREFIX}<sessionId>` and is removed on completion/cancel, so it
50
+ * never remains visible after a resumable upload finalizes.
51
+ */
52
+ const SESSION_KEY_PREFIX = ".resumable/";
53
+ /** Write metadata used when persisting a session's (transient) accumulated bytes. */
54
+ const SESSION_WRITE_METADATA = { contentType: "application/octet-stream" };
55
+ /**
56
+ * Provider-agnostic resumable upload manager built on the driver contract.
57
+ *
58
+ * A single instance is held by the facade and bound to one {@link StorageDriver}
59
+ * for its lifetime, so the native-vs-simulated decision (based on whether the
60
+ * driver exposes a `resumable` capability) is stable across every call for a
61
+ * given session id.
62
+ */
63
+ export class ResumableManager {
64
+ /** The driver every operation is delegated to or simulated over. */
65
+ driver;
66
+ /**
67
+ * In-progress simulated sessions keyed by session id. Empty when the driver
68
+ * provides a native `resumable` capability (that path keeps no local state).
69
+ */
70
+ sessions = new Map();
71
+ constructor(driver) {
72
+ this.driver = driver;
73
+ }
74
+ /** The driver's native resumable capability, when present. */
75
+ get native() {
76
+ return this.driver.resumable;
77
+ }
78
+ /**
79
+ * Create a resumable upload session for `key` and return its session id
80
+ * (Requirement 7.1). When the driver has a native capability the driver mints
81
+ * the id and initializes the offset; otherwise a fresh id is generated and a
82
+ * local session records the target key and its write-time metadata. No
83
+ * reserved key is written yet — the persisted offset is zero until the first
84
+ * `resume` appends content.
85
+ */
86
+ async start(key, metadata) {
87
+ if (this.native !== undefined) {
88
+ return this.native.start(key, metadata);
89
+ }
90
+ const sessionId = randomUUID();
91
+ this.sessions.set(sessionId, { key, metadata, completing: false, cancelled: false });
92
+ return sessionId;
93
+ }
94
+ /**
95
+ * Continue the upload for `sessionId` from the last persisted offset and, on
96
+ * completion, create the final object and return its metadata (Requirements
97
+ * 7.2, 7.3).
98
+ *
99
+ * `stream` carries the object's full intended content from offset zero. The
100
+ * manager appends only the bytes lying beyond the already-persisted offset —
101
+ * bytes it already holds are skipped — so the final object equals the full
102
+ * stream content and is byte-identical to an equivalent uninterrupted upload
103
+ * regardless of how many prior interruptions occurred.
104
+ *
105
+ * Once the stream is fully consumed the session enters its completing phase;
106
+ * from that point a concurrent {@link cancel} is ignored so the object is
107
+ * still created (Requirement 7.5). If a cancel arrives *before* completion,
108
+ * the in-progress resume aborts and creates no object (Requirement 7.4).
109
+ */
110
+ async resume(sessionId, stream) {
111
+ if (this.native !== undefined) {
112
+ return this.resumeNative(this.native, sessionId, stream);
113
+ }
114
+ const session = this.requireSession(sessionId);
115
+ const reservedKey = this.sessionKey(sessionId);
116
+ // The persisted content (and therefore the offset) is the single source of
117
+ // truth for how many bytes have already been stored for this session.
118
+ let persisted = await this.readPersisted(reservedKey);
119
+ let seen = 0;
120
+ for await (const chunk of stream) {
121
+ // A cancel that arrived before completion aborts the resume and leaves no
122
+ // final object (Requirement 7.4); the reserved data has already been
123
+ // discarded by cancel, but delete again defensively in case this resume
124
+ // wrote after the cancel began.
125
+ if (session.cancelled) {
126
+ await this.driver.delete(reservedKey);
127
+ throw new StorageError(`Resumable upload session "${sessionId}" was cancelled during resume.`);
128
+ }
129
+ const buf = toBuffer(chunk);
130
+ const chunkEnd = seen + buf.byteLength;
131
+ // Append only the portion of this chunk that lies beyond the persisted
132
+ // offset; bytes at positions already persisted are skipped.
133
+ if (chunkEnd > persisted.byteLength) {
134
+ const skip = Math.max(0, persisted.byteLength - seen);
135
+ const toAppend = buf.subarray(skip);
136
+ persisted = Buffer.concat([persisted, toAppend]);
137
+ await this.driver.put(reservedKey, new Uint8Array(persisted), SESSION_WRITE_METADATA);
138
+ }
139
+ seen = chunkEnd;
140
+ }
141
+ // Completion phase: from here the upload is committing, so a concurrent
142
+ // cancel is ignored and the object is still created (Requirement 7.5).
143
+ session.completing = true;
144
+ const metadata = await this.driver.put(session.key, new Uint8Array(persisted), session.metadata);
145
+ await this.driver.delete(reservedKey);
146
+ this.sessions.delete(sessionId);
147
+ return normalizeMetadata(metadata);
148
+ }
149
+ /**
150
+ * Discard the session `sessionId` and its persisted data, creating no object
151
+ * (Requirement 7.4). If the session is already completing — its stream has
152
+ * been fully consumed and the final object is being written — the cancel is
153
+ * ignored so the upload finishes and creates the object (Requirement 7.5). An
154
+ * unknown/already-finalized session id is treated as an idempotent no-op.
155
+ */
156
+ async cancel(sessionId) {
157
+ if (this.native !== undefined) {
158
+ await this.native.cancel(sessionId);
159
+ return;
160
+ }
161
+ const session = this.sessions.get(sessionId);
162
+ if (session === undefined) {
163
+ return;
164
+ }
165
+ // Already committing — let the in-flight resume finish and create the object.
166
+ if (session.completing) {
167
+ return;
168
+ }
169
+ session.cancelled = true;
170
+ await this.driver.delete(this.sessionKey(sessionId));
171
+ this.sessions.delete(sessionId);
172
+ }
173
+ /**
174
+ * Native-capability resume: drive the driver's `offset`/`append`/`finish`
175
+ * primitives. As in the simulated path, `stream` carries the full content and
176
+ * only the portion beyond the driver's reported offset is appended, so the
177
+ * finished object is byte-identical to an uninterrupted upload.
178
+ */
179
+ async resumeNative(native, sessionId, stream) {
180
+ let offset = await native.offset(sessionId);
181
+ let seen = 0;
182
+ for await (const chunk of stream) {
183
+ const buf = toBuffer(chunk);
184
+ const chunkEnd = seen + buf.byteLength;
185
+ if (chunkEnd > offset) {
186
+ const skip = Math.max(0, offset - seen);
187
+ const toAppend = buf.subarray(skip);
188
+ offset = await native.append(sessionId, new Uint8Array(toAppend), offset);
189
+ }
190
+ seen = chunkEnd;
191
+ }
192
+ return normalizeMetadata(await native.finish(sessionId));
193
+ }
194
+ /**
195
+ * Read the accumulated bytes persisted for a simulated session, returning an
196
+ * empty buffer when nothing has been persisted yet (offset zero).
197
+ */
198
+ async readPersisted(reservedKey) {
199
+ const result = await this.driver.get(reservedKey);
200
+ return result.found ? Buffer.from(result.bytes) : Buffer.alloc(0);
201
+ }
202
+ /** The reserved driver key a simulated session's accumulated bytes live under. */
203
+ sessionKey(sessionId) {
204
+ return `${SESSION_KEY_PREFIX}${sessionId}`;
205
+ }
206
+ /**
207
+ * Resolve the simulated session for `sessionId`, throwing a descriptive
208
+ * {@link StorageError} when the id is unknown or the session has already been
209
+ * finalized or cancelled.
210
+ */
211
+ requireSession(sessionId) {
212
+ const session = this.sessions.get(sessionId);
213
+ if (session === undefined) {
214
+ throw new StorageError(`Unknown or already-finalized resumable upload session "${sessionId}".`);
215
+ }
216
+ return session;
217
+ }
218
+ }
219
+ /** Normalize a stream chunk to a `Buffer` without copying when already one. */
220
+ function toBuffer(chunk) {
221
+ return Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
222
+ }
223
+ //# sourceMappingURL=resumable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resumable.js","sourceRoot":"","sources":["../src/resumable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @streetjs/storage — attribute search / filtering over the flat key space
3
+ * (task 18.1).
4
+ *
5
+ * Object stores expose only a flat key space plus per-object metadata, so
6
+ * search is implemented as a provider-agnostic filter over the two mandatory
7
+ * driver primitives {@link StorageDriver.list} and {@link StorageDriver.stat}:
8
+ *
9
+ * 1. Enumerate candidate keys with `driver.list(prefix)` (the prefix filter is
10
+ * pushed down to the driver; an absent prefix lists the whole key space).
11
+ * 2. For each candidate, read its typed metadata with `driver.stat(key)`.
12
+ * 3. Keep the object only when it satisfies **every** supplied filter
13
+ * (conjunctive / AND semantics — Requirement 16.2); when no object satisfies
14
+ * the filters the result is the empty set (Requirement 16.3).
15
+ *
16
+ * The supported filters mirror {@link SearchFilters} (Requirement 16.1):
17
+ *
18
+ * - `prefix` — key begins with the prefix (pushed to `driver.list`).
19
+ * - `contentType` — exact content-type match.
20
+ * - `owner` — exact owner match.
21
+ * - `tenant` — exact tenant match.
22
+ * - `minSize` — size ≥ minSize (inclusive lower bound).
23
+ * - `maxSize` — size ≤ maxSize (inclusive upper bound).
24
+ * - `updatedAfter` — updatedAt ≥ updatedAfter (inclusive lower time bound).
25
+ * - `updatedBefore` — updatedAt ≤ updatedBefore (inclusive upper time bound).
26
+ * - `metadata` — every supplied custom field deep-equals the object's
27
+ * corresponding `custom` field.
28
+ *
29
+ * Reserved internal key spaces used by the cross-cutting layers
30
+ * (`.versions/`, `.multipart/`, `.resumable/`, `.archive/`) are excluded from
31
+ * results unless the supplied `prefix` explicitly targets one of them, so a
32
+ * broad search returns only user-visible objects and never leaks framework
33
+ * bookkeeping keys.
34
+ *
35
+ * The result preserves the {@link StorageListItem} shape returned by
36
+ * `driver.list`, so `search` composes with the rest of the facade surface.
37
+ *
38
+ * _Requirements: 16.1, 16.2, 16.3_
39
+ */
40
+ import type { StorageDriver } from "./driver.js";
41
+ import type { SearchFilters, StorageListItem } from "./types.js";
42
+ /**
43
+ * Return the stored objects that satisfy **every** supplied filter, evaluated
44
+ * over `driver.list` + `driver.stat`.
45
+ *
46
+ * The prefix filter is delegated to `driver.list`; the remaining filters are
47
+ * applied against each candidate's metadata. Objects whose metadata cannot be
48
+ * read (e.g. removed concurrently between `list` and `stat`) are skipped. When
49
+ * no object satisfies the filters, an empty array is returned (Requirement
50
+ * 16.3).
51
+ *
52
+ * @param driver The storage driver to search over.
53
+ * @param filters The conjunctive set of {@link SearchFilters} to apply.
54
+ * @returns The matching objects as {@link StorageListItem}s.
55
+ */
56
+ export declare function searchObjects(driver: StorageDriver, filters?: SearchFilters): Promise<StorageListItem[]>;
57
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAyB,MAAM,YAAY,CAAC;AAcxF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC,CA2B5B"}