@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
@@ -0,0 +1,203 @@
1
+ // Unit tests for the Amazon S3 provider submodule (task 28.2), exercised through
2
+ // the built `dist/drivers/s3.js` entry that backs `@streetjs/storage/s3`.
3
+ //
4
+ // The submodule contributes only client wiring on top of the shared S3-style
5
+ // base; its own responsibilities are:
6
+ // - createS3StorageDriver wraps an injected S3ClientLike as a name:"s3" driver
7
+ // and delegates the whole StorageDriver contract to the base
8
+ // - createS3StorageDriver rejects a missing/invalid client with a descriptive
9
+ // StorageConfigError (no SDK is ever loaded on the injected path)
10
+ // - createS3StorageDriverFromConfig wraps a supplied client without loading any
11
+ // SDK, and throws a descriptive StorageConfigError when it must build a
12
+ // client but the optional @aws-sdk/client-s3 peer dependency is absent
13
+ // - the shared driver contract-conformance suite passes against the wrapper
14
+ //
15
+ // A fake in-memory S3ClientLike stands in for the AWS SDK so the driver is
16
+ // exercised with no external service and no SDK dependency.
17
+ //
18
+ // Requirements: 2.1, 2.3, 3.3
19
+ import test from "node:test";
20
+ import assert from "node:assert/strict";
21
+ import { createS3StorageDriver, createS3StorageDriverFromConfig, } from "../drivers/s3.js";
22
+ import { StorageConfigError } from "../errors.js";
23
+ import { registerStorageDriverContractTests } from "./contract.js";
24
+ const FIXED_NOW = 1_700_000_000_000;
25
+ const fixedClock = () => FIXED_NOW;
26
+ function bytes(str) {
27
+ return new TextEncoder().encode(str);
28
+ }
29
+ /** A minimal in-memory S3ClientLike (with native multipart) standing in for the SDK. */
30
+ function makeFakeClient() {
31
+ const objects = new Map(); // key -> { body, contentType, metadata }
32
+ const uploads = new Map(); // uploadId -> { key, contentType, metadata, parts: Map }
33
+ let seed = 0;
34
+ return {
35
+ async putObject({ key, body, contentType, metadata }) {
36
+ objects.set(key, {
37
+ body: body.slice(),
38
+ contentType,
39
+ metadata: metadata ? { ...metadata } : undefined,
40
+ });
41
+ return { etag: `"${key}-etag"` };
42
+ },
43
+ async getObject({ key }) {
44
+ const obj = objects.get(key);
45
+ if (obj === undefined)
46
+ return null;
47
+ return {
48
+ body: obj.body.slice(),
49
+ contentType: obj.contentType,
50
+ etag: `"${key}-etag"`,
51
+ size: obj.body.byteLength,
52
+ lastModified: FIXED_NOW,
53
+ metadata: obj.metadata,
54
+ };
55
+ },
56
+ async headObject({ key }) {
57
+ const obj = objects.get(key);
58
+ if (obj === undefined)
59
+ return null;
60
+ return {
61
+ contentType: obj.contentType,
62
+ etag: `"${key}-etag"`,
63
+ size: obj.body.byteLength,
64
+ lastModified: FIXED_NOW,
65
+ metadata: obj.metadata,
66
+ };
67
+ },
68
+ async deleteObject({ key }) {
69
+ objects.delete(key);
70
+ },
71
+ async listObjects({ prefix }) {
72
+ return [...objects.entries()]
73
+ .filter(([key]) => key.startsWith(prefix))
74
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
75
+ .map(([key, obj]) => ({ key, size: obj.body.byteLength, updatedAt: FIXED_NOW }));
76
+ },
77
+ async createMultipartUpload({ key, contentType, metadata }) {
78
+ const uploadId = `upload-${(seed += 1)}`;
79
+ uploads.set(uploadId, { key, contentType, metadata, parts: new Map() });
80
+ return { uploadId };
81
+ },
82
+ async uploadPart({ uploadId, partNumber, body }) {
83
+ uploads.get(uploadId).parts.set(partNumber, body.slice());
84
+ return { etag: `"${uploadId}-${partNumber}"` };
85
+ },
86
+ async completeMultipartUpload({ uploadId, parts }) {
87
+ const session = uploads.get(uploadId);
88
+ const ordered = [...parts].sort((a, b) => a.partNumber - b.partNumber);
89
+ const buffers = ordered.map((p) => Buffer.from(session.parts.get(p.partNumber)));
90
+ objects.set(session.key, {
91
+ body: new Uint8Array(Buffer.concat(buffers)),
92
+ contentType: session.contentType,
93
+ metadata: session.metadata,
94
+ });
95
+ uploads.delete(uploadId);
96
+ return { etag: `"${session.key}-etag"` };
97
+ },
98
+ async abortMultipartUpload({ uploadId }) {
99
+ uploads.delete(uploadId);
100
+ },
101
+ };
102
+ }
103
+ // ── createS3StorageDriver: injected client (no SDK) ─────────────────────────────
104
+ test("createS3StorageDriver wraps an injected client as a name:s3 driver", () => {
105
+ const driver = createS3StorageDriver(makeFakeClient(), { clock: fixedClock });
106
+ assert.equal(driver.name, "s3");
107
+ });
108
+ test("createS3StorageDriver round-trips bytes and typed metadata via the base", async () => {
109
+ const driver = createS3StorageDriver(makeFakeClient(), { clock: fixedClock });
110
+ const content = bytes("amazon s3 content");
111
+ const meta = await driver.put("docs/report.txt", content, {
112
+ contentType: "text/plain",
113
+ owner: "user-9",
114
+ tenant: "tenant-z",
115
+ accessLevel: "public",
116
+ custom: { label: "q3" },
117
+ });
118
+ assert.equal(meta.key, "docs/report.txt");
119
+ assert.equal(meta.size, content.byteLength);
120
+ assert.match(meta.checksum, /^[0-9a-f]{64}$/);
121
+ const result = await driver.get("docs/report.txt");
122
+ assert.equal(result.found, true);
123
+ assert.deepEqual(result.bytes, content);
124
+ assert.equal(result.metadata.contentType, "text/plain");
125
+ assert.equal(result.metadata.owner, "user-9");
126
+ assert.equal(result.metadata.tenant, "tenant-z");
127
+ assert.equal(result.metadata.accessLevel, "public");
128
+ assert.deepEqual(result.metadata.custom, { label: "q3" });
129
+ });
130
+ test("createS3StorageDriver reports a missing key as found:false (not an error)", async () => {
131
+ const driver = createS3StorageDriver(makeFakeClient(), { clock: fixedClock });
132
+ const result = await driver.get("missing");
133
+ assert.equal(result.found, false);
134
+ });
135
+ test("createS3StorageDriver wires native multipart from the injected client", async () => {
136
+ const driver = createS3StorageDriver(makeFakeClient(), { clock: fixedClock });
137
+ assert.notEqual(driver.multipart, undefined);
138
+ assert.ok(driver.multipart);
139
+ const uploadId = await driver.multipart.create("big/file.bin", { contentType: "text/plain" });
140
+ const p1 = await driver.multipart.uploadPart(uploadId, 1, bytes("part-one-"));
141
+ const p2 = await driver.multipart.uploadPart(uploadId, 2, bytes("part-two"));
142
+ const meta = await driver.multipart.complete(uploadId, [p1, p2]);
143
+ assert.equal(meta.key, "big/file.bin");
144
+ const result = await driver.get("big/file.bin");
145
+ assert.ok(result.found);
146
+ assert.deepEqual(result.bytes, bytes("part-one-part-two"));
147
+ });
148
+ test("createS3StorageDriver delegates injected native capabilities", () => {
149
+ const versioning = {
150
+ snapshot: async () => null,
151
+ list: async () => [],
152
+ restore: async () => ({
153
+ key: "",
154
+ size: 0,
155
+ contentType: "application/octet-stream",
156
+ etag: "",
157
+ checksum: "",
158
+ accessLevel: "private",
159
+ createdAt: 0,
160
+ updatedAt: 0,
161
+ custom: {},
162
+ }),
163
+ deleteVersion: async () => { },
164
+ };
165
+ const driver = createS3StorageDriver(makeFakeClient(), { capabilities: { versioning } });
166
+ assert.equal(driver.versioning, versioning);
167
+ });
168
+ // ── createS3StorageDriver: invalid client ───────────────────────────────────────
169
+ test("createS3StorageDriver throws StorageConfigError when no client is injected", () => {
170
+ assert.throws(() => createS3StorageDriver(undefined), (error) => {
171
+ assert.ok(error instanceof StorageConfigError);
172
+ assert.equal(error.provider, "s3");
173
+ return true;
174
+ });
175
+ });
176
+ test("createS3StorageDriver throws StorageConfigError for a non-conforming client", () => {
177
+ assert.throws(() => createS3StorageDriver({ putObject() { } }), (error) => error instanceof StorageConfigError && error.provider === "s3");
178
+ });
179
+ // ── createS3StorageDriverFromConfig ─────────────────────────────────────────────
180
+ test("createS3StorageDriverFromConfig wraps a supplied client without loading any SDK", async () => {
181
+ const driver = await createS3StorageDriverFromConfig({
182
+ bucket: "my-bucket",
183
+ client: makeFakeClient(),
184
+ clock: fixedClock,
185
+ });
186
+ assert.equal(driver.name, "s3");
187
+ const meta = await driver.put("k", bytes("v"), {});
188
+ assert.equal(meta.key, "k");
189
+ const got = await driver.get("k");
190
+ assert.ok(got.found);
191
+ assert.deepEqual(got.bytes, bytes("v"));
192
+ });
193
+ test("createS3StorageDriverFromConfig throws a descriptive StorageConfigError when the AWS SDK is absent", async () => {
194
+ await assert.rejects(() => createS3StorageDriverFromConfig({ bucket: "my-bucket", region: "us-east-1" }), (error) => {
195
+ assert.ok(error instanceof StorageConfigError, "must be a StorageConfigError");
196
+ assert.equal(error.provider, "s3");
197
+ assert.match(error.message, /@aws-sdk\/client-s3/);
198
+ return true;
199
+ });
200
+ });
201
+ // ── shared contract-conformance suite ───────────────────────────────────────────
202
+ registerStorageDriverContractTests("s3", () => createS3StorageDriver(makeFakeClient(), { clock: fixedClock }), test);
203
+ //# sourceMappingURL=s3.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.test.js","sourceRoot":"","sources":["../../src/tests/s3.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=scaffold.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.test.d.ts","sourceRoot":"","sources":["../../src/tests/scaffold.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ // Placeholder scaffold test for @streetjs/storage.
2
+ //
3
+ // Verifies that the package builds and its compiled entry point can be imported
4
+ // and exposes the expected placeholder surface. Uses the Node.js built-in test
5
+ // runner (node:test) and is executed via `node --test dist/tests/*.test.js`.
6
+ import test from "node:test";
7
+ import assert from "node:assert/strict";
8
+ import { STORAGE_FRAMEWORK_VERSION, STORAGE_PACKAGE_NAME } from "../index.js";
9
+ test("built entry point exposes placeholder exports", () => {
10
+ assert.equal(STORAGE_PACKAGE_NAME, "@streetjs/storage");
11
+ assert.equal(STORAGE_FRAMEWORK_VERSION, "1.0.0");
12
+ });
13
+ //# sourceMappingURL=scaffold.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.test.js","sourceRoot":"","sources":["../../src/tests/scaffold.test.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,6EAA6E;AAE7E,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE9E,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACzD,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../src/tests/search.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ // Unit tests for search filtering wired into the storage facade (task 18.1).
2
+ //
3
+ // Verifies the Requirement 16 semantics over the zero-dependency `memory`
4
+ // provider, exercised through `storage.search`:
5
+ //
6
+ // - Filtering supports prefix, contentType, owner, tenant, size range,
7
+ // updated-time range, and custom metadata (16.1).
8
+ // - Multiple filters combine with AND semantics: only objects satisfying
9
+ // EVERY supplied filter are returned (16.2).
10
+ // - When no object satisfies the filters, an empty result set is returned
11
+ // (16.3).
12
+ // - Reserved internal keys (.versions/ etc.) are excluded from broad searches.
13
+ //
14
+ // Uses the Node.js built-in test runner (node:test); executed via
15
+ // `node --test dist/tests/*.test.js`.
16
+ //
17
+ // Requirements: 16.1, 16.2, 16.3
18
+ import test from "node:test";
19
+ import assert from "node:assert/strict";
20
+ import { createStorage } from "../facade.js";
21
+ import { searchObjects } from "../search.js";
22
+ import { MemoryStorageDriver } from "../drivers/memory.js";
23
+ /** A fixed clock so updatedAt values are deterministic for time-range filters. */
24
+ function fixedClock(now) {
25
+ return () => now;
26
+ }
27
+ /** Build a facade backed by a fresh in-memory driver with a fixed clock. */
28
+ function makeStorage(now = 1000) {
29
+ const driver = new MemoryStorageDriver({ clock: fixedClock(now) });
30
+ return { storage: createStorage({ provider: "memory", driver }), driver };
31
+ }
32
+ /** Collect the sorted keys from a list of StorageListItem results. */
33
+ function keysOf(items) {
34
+ return items.map((item) => item.key).sort();
35
+ }
36
+ test("search returns exactly the objects satisfying EVERY supplied filter (16.2)", async () => {
37
+ const { storage } = makeStorage();
38
+ // Two objects share owner "alice"; one also matches the content type and size.
39
+ await storage.put("photos/a.jpg", "aa", { contentType: "image/jpeg", owner: "alice" }); // size 2
40
+ await storage.put("photos/b.png", "bbbbb", { contentType: "image/png", owner: "alice" }); // size 5
41
+ await storage.put("photos/c.jpg", "cccc", { contentType: "image/jpeg", owner: "bob" }); // size 4
42
+ await storage.put("docs/readme.txt", "hello", { contentType: "text/plain", owner: "alice" });
43
+ // Conjunctive filter: prefix AND contentType AND owner AND size range.
44
+ const result = await storage.search({
45
+ prefix: "photos/",
46
+ contentType: "image/jpeg",
47
+ owner: "alice",
48
+ minSize: 1,
49
+ maxSize: 3,
50
+ });
51
+ // Only photos/a.jpg satisfies all four constraints at once.
52
+ assert.deepEqual(keysOf(result), ["photos/a.jpg"]);
53
+ });
54
+ test("each filter dimension narrows results independently (16.1)", async () => {
55
+ const { storage } = makeStorage(5000);
56
+ await storage.put("t1/x", "a", { owner: "alice", tenant: "acme", contentType: "text/plain" });
57
+ await storage.put("t1/y", "bb", { owner: "bob", tenant: "acme", contentType: "text/plain" });
58
+ await storage.put("t2/z", "ccc", { owner: "alice", tenant: "globex", contentType: "image/png" });
59
+ assert.deepEqual(keysOf(await storage.search({ owner: "alice" })), ["t1/x", "t2/z"]);
60
+ assert.deepEqual(keysOf(await storage.search({ tenant: "acme" })), ["t1/x", "t1/y"]);
61
+ assert.deepEqual(keysOf(await storage.search({ contentType: "image/png" })), ["t2/z"]);
62
+ assert.deepEqual(keysOf(await storage.search({ prefix: "t1/" })), ["t1/x", "t1/y"]);
63
+ // Size range: only the 2-byte and 3-byte objects.
64
+ assert.deepEqual(keysOf(await storage.search({ minSize: 2 })), ["t1/y", "t2/z"]);
65
+ });
66
+ test("search matches on updated-time range and custom metadata (16.1)", async () => {
67
+ const { storage } = makeStorage(2000);
68
+ await storage.put("k1", "one", { custom: { category: "invoice", region: "eu" } });
69
+ await storage.put("k2", "two", { custom: { category: "receipt", region: "eu" } });
70
+ // Custom metadata filter (AND across supplied custom fields).
71
+ const invoices = await storage.search({ metadata: { category: "invoice" } });
72
+ assert.deepEqual(keysOf(invoices), ["k1"]);
73
+ const euReceipts = await storage.search({ metadata: { category: "receipt", region: "eu" } });
74
+ assert.deepEqual(keysOf(euReceipts), ["k2"]);
75
+ // Time range covering the fixed clock value returns all; a window before it none.
76
+ assert.deepEqual(keysOf(await storage.search({ updatedAfter: 1000, updatedBefore: 3000 })), [
77
+ "k1",
78
+ "k2",
79
+ ]);
80
+ assert.deepEqual(await storage.search({ updatedBefore: 1000 }), []);
81
+ });
82
+ test("search returns an empty set when no object matches (16.3)", async () => {
83
+ const { storage } = makeStorage();
84
+ await storage.put("photos/a.jpg", "aa", { contentType: "image/jpeg", owner: "alice" });
85
+ // A filter combination no object satisfies.
86
+ assert.deepEqual(await storage.search({ owner: "nobody" }), []);
87
+ assert.deepEqual(await storage.search({ contentType: "image/jpeg", owner: "bob" }), []);
88
+ assert.deepEqual(await storage.search({ minSize: 100 }), []);
89
+ // Searching an empty store also yields an empty set.
90
+ const { storage: empty } = makeStorage();
91
+ assert.deepEqual(await empty.search({}), []);
92
+ });
93
+ test("search excludes reserved internal keys from broad searches", async () => {
94
+ const { storage, driver } = makeStorage();
95
+ await storage.put("photos/a.jpg", "aa", { owner: "alice" });
96
+ // Simulate framework bookkeeping written directly to the driver.
97
+ await driver.put(".versions/photos/a.jpg/v1", new Uint8Array([1]), {});
98
+ await driver.put(".multipart/upload-1/1", new Uint8Array([2]), {});
99
+ // A broad, unfiltered search surfaces only the user-visible object.
100
+ const all = await storage.search({});
101
+ assert.deepEqual(keysOf(all), ["photos/a.jpg"]);
102
+ // But an explicit search into the reserved space still finds those keys.
103
+ const versions = await searchObjects(driver, { prefix: ".versions/" });
104
+ assert.deepEqual(keysOf(versions), [".versions/photos/a.jpg/v1"]);
105
+ });
106
+ //# sourceMappingURL=search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../src/tests/search.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=supabase-driver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-driver.test.d.ts","sourceRoot":"","sources":["../../src/tests/supabase-driver.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,196 @@
1
+ // Unit tests for the Supabase Storage driver submodule (task 29.1). Unlike the
2
+ // S3-compatible providers, Supabase Storage uses a bucket-scoped file API, so
3
+ // the driver maps the StorageDriver contract directly onto a purpose-built
4
+ // structural SupabaseStorageClientLike (not the shared S3 base). These tests
5
+ // exercise the injected-client path with an in-memory SupabaseStorageClientLike
6
+ // double (no `@supabase/supabase-js` SDK, no external service), the
7
+ // StorageConfigError guard when no client is injected, the connect() guard when
8
+ // the SDK is absent, and the shared driver contract-conformance suite.
9
+ //
10
+ // Requirements: 2.1, 2.3, 3.3
11
+ import test from "node:test";
12
+ import assert from "node:assert/strict";
13
+ import { createSupabaseStorageDriver, connectSupabaseStorageDriver, } from "../drivers/supabase.js";
14
+ import { StorageConfigError } from "../errors.js";
15
+ import { registerStorageDriverContractTests } from "./contract.js";
16
+ const FIXED_NOW = 1_700_000_000_000;
17
+ const fixedClock = () => FIXED_NOW;
18
+ function bytes(str) {
19
+ return new TextEncoder().encode(str);
20
+ }
21
+ /**
22
+ * A minimal in-memory SupabaseStorageClientLike double. It stores the raw bytes
23
+ * plus the content type and custom-metadata map exactly as the real Supabase
24
+ * object model would, and returns `null` (never throws) for a missing object so
25
+ * the driver's not-found mapping is exercised.
26
+ */
27
+ function makeFakeClient() {
28
+ const objects = new Map(); // path -> { bytes, contentType, metadata }
29
+ return {
30
+ async upload({ path, body, contentType, metadata }) {
31
+ objects.set(path, {
32
+ bytes: body.slice(),
33
+ contentType,
34
+ metadata: metadata ? { ...metadata } : undefined,
35
+ });
36
+ return {};
37
+ },
38
+ async download(path) {
39
+ const obj = objects.get(path);
40
+ return obj === undefined ? null : obj.bytes.slice();
41
+ },
42
+ async remove(path) {
43
+ objects.delete(path);
44
+ },
45
+ async exists(path) {
46
+ return objects.has(path);
47
+ },
48
+ async info(path) {
49
+ const obj = objects.get(path);
50
+ if (obj === undefined)
51
+ return null;
52
+ return {
53
+ size: obj.bytes.byteLength,
54
+ contentType: obj.contentType,
55
+ etag: `${path}-etag`,
56
+ createdAt: new Date(FIXED_NOW).toISOString(),
57
+ updatedAt: new Date(FIXED_NOW).toISOString(),
58
+ userMetadata: obj.metadata,
59
+ };
60
+ },
61
+ async list({ prefix }) {
62
+ return [...objects.entries()]
63
+ .filter(([name]) => name.startsWith(prefix))
64
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
65
+ .map(([name, obj]) => ({
66
+ name,
67
+ size: obj.bytes.byteLength,
68
+ updatedAt: new Date(FIXED_NOW).toISOString(),
69
+ }));
70
+ },
71
+ };
72
+ }
73
+ function makeDriver() {
74
+ return createSupabaseStorageDriver(makeFakeClient(), { clock: fixedClock });
75
+ }
76
+ // ── name ──────────────────────────────────────────────────────────────────────
77
+ test("driver name is fixed to supabase", () => {
78
+ assert.equal(makeDriver().name, "supabase");
79
+ });
80
+ // ── injected-client primitives round-trip ─────────────────────────────────────
81
+ test("put/get round-trips bytes and typed metadata over the injected client", async () => {
82
+ const driver = makeDriver();
83
+ const content = bytes("supabase object payload");
84
+ await driver.put("bucketed/key.txt", content, {
85
+ contentType: "text/plain",
86
+ owner: "user-7",
87
+ tenant: "tenant-q",
88
+ accessLevel: "public",
89
+ custom: { label: "report" },
90
+ });
91
+ const result = await driver.get("bucketed/key.txt");
92
+ assert.equal(result.found, true);
93
+ assert.deepEqual(result.bytes, content);
94
+ assert.equal(result.metadata.contentType, "text/plain");
95
+ assert.equal(result.metadata.owner, "user-7");
96
+ assert.equal(result.metadata.tenant, "tenant-q");
97
+ assert.equal(result.metadata.accessLevel, "public");
98
+ assert.deepEqual(result.metadata.custom, { label: "report" });
99
+ assert.equal(result.metadata.size, content.byteLength);
100
+ });
101
+ test("createdAt is preserved across overwrite while updatedAt advances", async () => {
102
+ let now = 1000;
103
+ const driver = createSupabaseStorageDriver(makeFakeClient(), { clock: () => now });
104
+ const first = await driver.put("k.txt", bytes("v1"), {});
105
+ now = 5000;
106
+ const second = await driver.put("k.txt", bytes("v2-longer"), {});
107
+ assert.equal(second.createdAt, first.createdAt);
108
+ assert.equal(second.updatedAt, 5000);
109
+ assert.equal(second.size, bytes("v2-longer").byteLength);
110
+ });
111
+ test("exists/delete/stat/list behave consistently", async () => {
112
+ const driver = makeDriver();
113
+ await driver.put("d/a.txt", bytes("a"), {});
114
+ await driver.put("d/b.txt", bytes("bb"), {});
115
+ assert.equal(await driver.exists("d/a.txt"), true);
116
+ assert.equal(await driver.exists("d/missing.txt"), false);
117
+ const stat = await driver.stat("d/b.txt");
118
+ assert.ok(stat);
119
+ assert.equal(stat.size, 2);
120
+ assert.equal(await driver.stat("d/missing.txt"), null);
121
+ const items = await driver.list("d/");
122
+ assert.deepEqual(items.map((i) => i.key), ["d/a.txt", "d/b.txt"]);
123
+ await driver.delete("d/a.txt");
124
+ assert.equal(await driver.exists("d/a.txt"), false);
125
+ });
126
+ test("list honors cursor and limit", async () => {
127
+ const driver = makeDriver();
128
+ await driver.put("p/1", bytes("1"), {});
129
+ await driver.put("p/2", bytes("2"), {});
130
+ await driver.put("p/3", bytes("3"), {});
131
+ const limited = await driver.list("p/", { limit: 2 });
132
+ assert.deepEqual(limited.map((i) => i.key), ["p/1", "p/2"]);
133
+ const afterCursor = await driver.list("p/", { cursor: "p/1" });
134
+ assert.deepEqual(afterCursor.map((i) => i.key), ["p/2", "p/3"]);
135
+ });
136
+ test("get on a missing key reports found:false", async () => {
137
+ const driver = makeDriver();
138
+ const result = await driver.get("nope");
139
+ assert.equal(result.found, false);
140
+ });
141
+ // ── streaming ──────────────────────────────────────────────────────────────────
142
+ test("putStream/getStream round-trip through the injected client", async () => {
143
+ const { Readable } = await import("node:stream");
144
+ const driver = makeDriver();
145
+ const payload = bytes("streamed supabase payload");
146
+ await driver.putStream("s/obj.bin", Readable.from([Buffer.from(payload)]), {
147
+ contentType: "application/octet-stream",
148
+ });
149
+ const stream = await driver.getStream("s/obj.bin");
150
+ const chunks = [];
151
+ for await (const chunk of stream)
152
+ chunks.push(Buffer.from(chunk));
153
+ assert.deepEqual(new Uint8Array(Buffer.concat(chunks)), payload);
154
+ });
155
+ test("getStream throws NotFoundError for a missing key", async () => {
156
+ const driver = makeDriver();
157
+ await assert.rejects(() => driver.getStream("absent"), (err) => {
158
+ assert.ok(err instanceof Error);
159
+ assert.equal(err.name, "NotFoundError");
160
+ return true;
161
+ });
162
+ });
163
+ // ── advanced capabilities are left undefined for facade simulation ─────────────
164
+ test("advanced capabilities are undefined (simulated by the facade)", () => {
165
+ const driver = makeDriver();
166
+ assert.equal(driver.multipart, undefined);
167
+ assert.equal(driver.resumable, undefined);
168
+ assert.equal(driver.versioning, undefined);
169
+ assert.equal(driver.signedUrl, undefined);
170
+ assert.equal(driver.lifecycle, undefined);
171
+ });
172
+ // ── configuration guards ──────────────────────────────────────────────────────
173
+ test("createSupabaseStorageDriver throws StorageConfigError when no client is injected", () => {
174
+ assert.throws(() => createSupabaseStorageDriver(undefined), (err) => {
175
+ assert.ok(err instanceof StorageConfigError);
176
+ assert.equal(err.provider, "supabase");
177
+ return true;
178
+ });
179
+ });
180
+ test("connectSupabaseStorageDriver throws StorageConfigError when the Supabase SDK is absent", async () => {
181
+ await assert.rejects(() => connectSupabaseStorageDriver({ url: "https://x.supabase.co", key: "k", bucket: "b" }), (err) => {
182
+ assert.ok(err instanceof StorageConfigError);
183
+ assert.equal(err.provider, "supabase");
184
+ return true;
185
+ });
186
+ });
187
+ test("connectSupabaseStorageDriver throws StorageConfigError when config is incomplete", async () => {
188
+ await assert.rejects(() => connectSupabaseStorageDriver({ url: "", key: "", bucket: "" }), (err) => {
189
+ assert.ok(err instanceof StorageConfigError);
190
+ assert.equal(err.provider, "supabase");
191
+ return true;
192
+ });
193
+ });
194
+ // ── shared contract-conformance suite ─────────────────────────────────────────
195
+ registerStorageDriverContractTests("supabase", () => createSupabaseStorageDriver(makeFakeClient(), { clock: fixedClock }), test);
196
+ //# sourceMappingURL=supabase-driver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase-driver.test.js","sourceRoot":"","sources":["../../src/tests/supabase-driver.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=testing-utilities.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing-utilities.test.d.ts","sourceRoot":"","sources":["../../src/tests/testing-utilities.test.ts"],"names":[],"mappings":""}