@streetjs/storage 1.0.0 → 1.0.1

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 (225) hide show
  1. package/dist/drivers/local.d.ts +8 -0
  2. package/dist/drivers/local.d.ts.map +1 -1
  3. package/dist/drivers/local.js +18 -3
  4. package/dist/drivers/local.js.map +1 -1
  5. package/package.json +12 -6
  6. package/dist/tests/access.test.d.ts +0 -2
  7. package/dist/tests/access.test.d.ts.map +0 -1
  8. package/dist/tests/access.test.js +0 -270
  9. package/dist/tests/access.test.js.map +0 -1
  10. package/dist/tests/azure-driver.test.d.ts +0 -2
  11. package/dist/tests/azure-driver.test.d.ts.map +0 -1
  12. package/dist/tests/azure-driver.test.js +0 -183
  13. package/dist/tests/azure-driver.test.js.map +0 -1
  14. package/dist/tests/backblaze-driver.test.d.ts +0 -2
  15. package/dist/tests/backblaze-driver.test.d.ts.map +0 -1
  16. package/dist/tests/backblaze-driver.test.js +0 -185
  17. package/dist/tests/backblaze-driver.test.js.map +0 -1
  18. package/dist/tests/bridge-degradation.test.d.ts +0 -2
  19. package/dist/tests/bridge-degradation.test.d.ts.map +0 -1
  20. package/dist/tests/bridge-degradation.test.js +0 -138
  21. package/dist/tests/bridge-degradation.test.js.map +0 -1
  22. package/dist/tests/cli.test.d.ts +0 -2
  23. package/dist/tests/cli.test.d.ts.map +0 -1
  24. package/dist/tests/cli.test.js +0 -127
  25. package/dist/tests/cli.test.js.map +0 -1
  26. package/dist/tests/contract.d.ts +0 -131
  27. package/dist/tests/contract.d.ts.map +0 -1
  28. package/dist/tests/contract.js +0 -222
  29. package/dist/tests/contract.js.map +0 -1
  30. package/dist/tests/contract.test.d.ts +0 -2
  31. package/dist/tests/contract.test.d.ts.map +0 -1
  32. package/dist/tests/contract.test.js +0 -110
  33. package/dist/tests/contract.test.js.map +0 -1
  34. package/dist/tests/directory.test.d.ts +0 -2
  35. package/dist/tests/directory.test.d.ts.map +0 -1
  36. package/dist/tests/directory.test.js +0 -125
  37. package/dist/tests/directory.test.js.map +0 -1
  38. package/dist/tests/errors.test.d.ts +0 -2
  39. package/dist/tests/errors.test.d.ts.map +0 -1
  40. package/dist/tests/errors.test.js +0 -93
  41. package/dist/tests/errors.test.js.map +0 -1
  42. package/dist/tests/events-bridge.test.d.ts +0 -2
  43. package/dist/tests/events-bridge.test.d.ts.map +0 -1
  44. package/dist/tests/events-bridge.test.js +0 -228
  45. package/dist/tests/events-bridge.test.js.map +0 -1
  46. package/dist/tests/example-smoke.test.d.ts +0 -2
  47. package/dist/tests/example-smoke.test.d.ts.map +0 -1
  48. package/dist/tests/example-smoke.test.js +0 -34
  49. package/dist/tests/example-smoke.test.js.map +0 -1
  50. package/dist/tests/gcs-driver.test.d.ts +0 -2
  51. package/dist/tests/gcs-driver.test.d.ts.map +0 -1
  52. package/dist/tests/gcs-driver.test.js +0 -197
  53. package/dist/tests/gcs-driver.test.js.map +0 -1
  54. package/dist/tests/image.test.d.ts +0 -2
  55. package/dist/tests/image.test.d.ts.map +0 -1
  56. package/dist/tests/image.test.js +0 -102
  57. package/dist/tests/image.test.js.map +0 -1
  58. package/dist/tests/lifecycle.test.d.ts +0 -2
  59. package/dist/tests/lifecycle.test.d.ts.map +0 -1
  60. package/dist/tests/lifecycle.test.js +0 -171
  61. package/dist/tests/lifecycle.test.js.map +0 -1
  62. package/dist/tests/local-driver.test.d.ts +0 -2
  63. package/dist/tests/local-driver.test.d.ts.map +0 -1
  64. package/dist/tests/local-driver.test.js +0 -153
  65. package/dist/tests/local-driver.test.js.map +0 -1
  66. package/dist/tests/local-streaming.test.d.ts +0 -2
  67. package/dist/tests/local-streaming.test.d.ts.map +0 -1
  68. package/dist/tests/local-streaming.test.js +0 -121
  69. package/dist/tests/local-streaming.test.js.map +0 -1
  70. package/dist/tests/memory-driver.test.d.ts +0 -2
  71. package/dist/tests/memory-driver.test.d.ts.map +0 -1
  72. package/dist/tests/memory-driver.test.js +0 -180
  73. package/dist/tests/memory-driver.test.js.map +0 -1
  74. package/dist/tests/memory-streaming.test.d.ts +0 -2
  75. package/dist/tests/memory-streaming.test.d.ts.map +0 -1
  76. package/dist/tests/memory-streaming.test.js +0 -92
  77. package/dist/tests/memory-streaming.test.js.map +0 -1
  78. package/dist/tests/minio-driver.test.d.ts +0 -2
  79. package/dist/tests/minio-driver.test.d.ts.map +0 -1
  80. package/dist/tests/minio-driver.test.js +0 -146
  81. package/dist/tests/minio-driver.test.js.map +0 -1
  82. package/dist/tests/non-s3-integration.test.d.ts +0 -2
  83. package/dist/tests/non-s3-integration.test.d.ts.map +0 -1
  84. package/dist/tests/non-s3-integration.test.js +0 -201
  85. package/dist/tests/non-s3-integration.test.js.map +0 -1
  86. package/dist/tests/observability.registration.test.d.ts +0 -2
  87. package/dist/tests/observability.registration.test.d.ts.map +0 -1
  88. package/dist/tests/observability.registration.test.js +0 -103
  89. package/dist/tests/observability.registration.test.js.map +0 -1
  90. package/dist/tests/observability.test.d.ts +0 -2
  91. package/dist/tests/observability.test.d.ts.map +0 -1
  92. package/dist/tests/observability.test.js +0 -240
  93. package/dist/tests/observability.test.js.map +0 -1
  94. package/dist/tests/plugin.test.d.ts +0 -2
  95. package/dist/tests/plugin.test.d.ts.map +0 -1
  96. package/dist/tests/plugin.test.js +0 -112
  97. package/dist/tests/plugin.test.js.map +0 -1
  98. package/dist/tests/prop-concurrent.test.d.ts +0 -2
  99. package/dist/tests/prop-concurrent.test.d.ts.map +0 -1
  100. package/dist/tests/prop-concurrent.test.js +0 -59
  101. package/dist/tests/prop-concurrent.test.js.map +0 -1
  102. package/dist/tests/prop-copy.test.d.ts +0 -2
  103. package/dist/tests/prop-copy.test.d.ts.map +0 -1
  104. package/dist/tests/prop-copy.test.js +0 -63
  105. package/dist/tests/prop-copy.test.js.map +0 -1
  106. package/dist/tests/prop-delete.test.d.ts +0 -2
  107. package/dist/tests/prop-delete.test.d.ts.map +0 -1
  108. package/dist/tests/prop-delete.test.js +0 -35
  109. package/dist/tests/prop-delete.test.js.map +0 -1
  110. package/dist/tests/prop-directory.test.d.ts +0 -2
  111. package/dist/tests/prop-directory.test.d.ts.map +0 -1
  112. package/dist/tests/prop-directory.test.js +0 -118
  113. package/dist/tests/prop-directory.test.js.map +0 -1
  114. package/dist/tests/prop-driver-conformance.test.d.ts +0 -2
  115. package/dist/tests/prop-driver-conformance.test.d.ts.map +0 -1
  116. package/dist/tests/prop-driver-conformance.test.js +0 -110
  117. package/dist/tests/prop-driver-conformance.test.js.map +0 -1
  118. package/dist/tests/prop-driver-equivalence.test.d.ts +0 -2
  119. package/dist/tests/prop-driver-equivalence.test.d.ts.map +0 -1
  120. package/dist/tests/prop-driver-equivalence.test.js +0 -163
  121. package/dist/tests/prop-driver-equivalence.test.js.map +0 -1
  122. package/dist/tests/prop-lifecycle.test.d.ts +0 -2
  123. package/dist/tests/prop-lifecycle.test.d.ts.map +0 -1
  124. package/dist/tests/prop-lifecycle.test.js +0 -83
  125. package/dist/tests/prop-lifecycle.test.js.map +0 -1
  126. package/dist/tests/prop-list.test.d.ts +0 -2
  127. package/dist/tests/prop-list.test.d.ts.map +0 -1
  128. package/dist/tests/prop-list.test.js +0 -53
  129. package/dist/tests/prop-list.test.js.map +0 -1
  130. package/dist/tests/prop-metadata.test.d.ts +0 -2
  131. package/dist/tests/prop-metadata.test.d.ts.map +0 -1
  132. package/dist/tests/prop-metadata.test.js +0 -87
  133. package/dist/tests/prop-metadata.test.js.map +0 -1
  134. package/dist/tests/prop-move.test.d.ts +0 -2
  135. package/dist/tests/prop-move.test.d.ts.map +0 -1
  136. package/dist/tests/prop-move.test.js +0 -67
  137. package/dist/tests/prop-move.test.js.map +0 -1
  138. package/dist/tests/prop-multipart-abort.test.d.ts +0 -2
  139. package/dist/tests/prop-multipart-abort.test.d.ts.map +0 -1
  140. package/dist/tests/prop-multipart-abort.test.js +0 -48
  141. package/dist/tests/prop-multipart-abort.test.js.map +0 -1
  142. package/dist/tests/prop-multipart.test.d.ts +0 -2
  143. package/dist/tests/prop-multipart.test.d.ts.map +0 -1
  144. package/dist/tests/prop-multipart.test.js +0 -65
  145. package/dist/tests/prop-multipart.test.js.map +0 -1
  146. package/dist/tests/prop-resumable.test.d.ts +0 -2
  147. package/dist/tests/prop-resumable.test.d.ts.map +0 -1
  148. package/dist/tests/prop-resumable.test.js +0 -78
  149. package/dist/tests/prop-resumable.test.js.map +0 -1
  150. package/dist/tests/prop-search.test.d.ts +0 -2
  151. package/dist/tests/prop-search.test.d.ts.map +0 -1
  152. package/dist/tests/prop-search.test.js +0 -120
  153. package/dist/tests/prop-search.test.js.map +0 -1
  154. package/dist/tests/prop-signed-url.test.d.ts +0 -2
  155. package/dist/tests/prop-signed-url.test.d.ts.map +0 -1
  156. package/dist/tests/prop-signed-url.test.js +0 -74
  157. package/dist/tests/prop-signed-url.test.js.map +0 -1
  158. package/dist/tests/prop-streaming.test.d.ts +0 -2
  159. package/dist/tests/prop-streaming.test.d.ts.map +0 -1
  160. package/dist/tests/prop-streaming.test.js +0 -34
  161. package/dist/tests/prop-streaming.test.js.map +0 -1
  162. package/dist/tests/prop-upload-download.test.d.ts +0 -2
  163. package/dist/tests/prop-upload-download.test.d.ts.map +0 -1
  164. package/dist/tests/prop-upload-download.test.js +0 -30
  165. package/dist/tests/prop-upload-download.test.js.map +0 -1
  166. package/dist/tests/prop-validation.test.d.ts +0 -2
  167. package/dist/tests/prop-validation.test.d.ts.map +0 -1
  168. package/dist/tests/prop-validation.test.js +0 -50
  169. package/dist/tests/prop-validation.test.js.map +0 -1
  170. package/dist/tests/prop-versioning.test.d.ts +0 -2
  171. package/dist/tests/prop-versioning.test.d.ts.map +0 -1
  172. package/dist/tests/prop-versioning.test.js +0 -74
  173. package/dist/tests/prop-versioning.test.js.map +0 -1
  174. package/dist/tests/queue-bridge.test.d.ts +0 -2
  175. package/dist/tests/queue-bridge.test.d.ts.map +0 -1
  176. package/dist/tests/queue-bridge.test.js +0 -111
  177. package/dist/tests/queue-bridge.test.js.map +0 -1
  178. package/dist/tests/r2-driver.test.d.ts +0 -2
  179. package/dist/tests/r2-driver.test.d.ts.map +0 -1
  180. package/dist/tests/r2-driver.test.js +0 -143
  181. package/dist/tests/r2-driver.test.js.map +0 -1
  182. package/dist/tests/realtime-bridge.test.d.ts +0 -2
  183. package/dist/tests/realtime-bridge.test.d.ts.map +0 -1
  184. package/dist/tests/realtime-bridge.test.js +0 -106
  185. package/dist/tests/realtime-bridge.test.js.map +0 -1
  186. package/dist/tests/resumable.test.d.ts +0 -2
  187. package/dist/tests/resumable.test.d.ts.map +0 -1
  188. package/dist/tests/resumable.test.js +0 -104
  189. package/dist/tests/resumable.test.js.map +0 -1
  190. package/dist/tests/s3-base.test.d.ts +0 -2
  191. package/dist/tests/s3-base.test.d.ts.map +0 -1
  192. package/dist/tests/s3-base.test.js +0 -289
  193. package/dist/tests/s3-base.test.js.map +0 -1
  194. package/dist/tests/s3-integration.test.d.ts +0 -2
  195. package/dist/tests/s3-integration.test.d.ts.map +0 -1
  196. package/dist/tests/s3-integration.test.js +0 -270
  197. package/dist/tests/s3-integration.test.js.map +0 -1
  198. package/dist/tests/s3.test.d.ts +0 -2
  199. package/dist/tests/s3.test.d.ts.map +0 -1
  200. package/dist/tests/s3.test.js +0 -203
  201. package/dist/tests/s3.test.js.map +0 -1
  202. package/dist/tests/scaffold.test.d.ts +0 -2
  203. package/dist/tests/scaffold.test.d.ts.map +0 -1
  204. package/dist/tests/scaffold.test.js +0 -13
  205. package/dist/tests/scaffold.test.js.map +0 -1
  206. package/dist/tests/search.test.d.ts +0 -2
  207. package/dist/tests/search.test.d.ts.map +0 -1
  208. package/dist/tests/search.test.js +0 -106
  209. package/dist/tests/search.test.js.map +0 -1
  210. package/dist/tests/supabase-driver.test.d.ts +0 -2
  211. package/dist/tests/supabase-driver.test.d.ts.map +0 -1
  212. package/dist/tests/supabase-driver.test.js +0 -196
  213. package/dist/tests/supabase-driver.test.js.map +0 -1
  214. package/dist/tests/testing-utilities.test.d.ts +0 -2
  215. package/dist/tests/testing-utilities.test.d.ts.map +0 -1
  216. package/dist/tests/testing-utilities.test.js +0 -138
  217. package/dist/tests/testing-utilities.test.js.map +0 -1
  218. package/dist/tests/validation.test.d.ts +0 -2
  219. package/dist/tests/validation.test.d.ts.map +0 -1
  220. package/dist/tests/validation.test.js +0 -135
  221. package/dist/tests/validation.test.js.map +0 -1
  222. package/dist/tests/versioning.test.d.ts +0 -2
  223. package/dist/tests/versioning.test.d.ts.map +0 -1
  224. package/dist/tests/versioning.test.js +0 -128
  225. package/dist/tests/versioning.test.js.map +0 -1
@@ -1,240 +0,0 @@
1
- // Unit + integration tests for the storage observability wiring (task 22.1).
2
- //
3
- // Verifies the Requirement 23 semantics over the zero-dependency `memory`
4
- // provider and the real core MetricsRegistry / HealthCheckRegistry:
5
- //
6
- // - the facade tracks live stats (uploads/downloads/bytes/active/failed/usage/
7
- // multipart/resumable) surfaced by `storage.stats()` (23.2);
8
- // - `storage.probe()` delegates to the driver's probe or returns a sensible
9
- // default when the driver has no probe (23.3);
10
- // - registerStorageObservability registers metrics idempotently against the
11
- // existing MetricsRegistry (23.1, 23.2, 23.4) and a health check against the
12
- // existing HealthCheckRegistry sourced from probe() (23.3);
13
- // - configuring config.metrics/config.health wires observability on the facade
14
- // and drives the counters/gauges as operations occur.
15
- //
16
- // Uses the Node.js built-in test runner (node:test); executed via
17
- // `node --test dist/tests/*.test.js`.
18
- //
19
- // Requirements: 23.1, 23.2, 23.3, 23.4
20
- import test from "node:test";
21
- import assert from "node:assert/strict";
22
- import { HealthCheckRegistry, MetricsRegistry, Counter, Gauge, Histogram } from "streetjs";
23
- import { createStorage, registerStorageObservability, STORAGE_HEALTH_CHECK_NAME, STORAGE_UPLOADS_METRIC, STORAGE_DOWNLOADS_METRIC, STORAGE_BYTES_UPLOADED_METRIC, STORAGE_BYTES_DOWNLOADED_METRIC, STORAGE_ACTIVE_UPLOADS_METRIC, STORAGE_FAILED_UPLOADS_METRIC, STORAGE_USAGE_METRIC, STORAGE_LATENCY_METRIC, STORAGE_MULTIPART_METRIC, STORAGE_RESUMABLE_METRIC, } from "../index.js";
24
- test("stats() starts zeroed and is available without any registry (Req 23.2)", async () => {
25
- const storage = createStorage({ provider: "memory" });
26
- assert.deepEqual(storage.stats(), {
27
- uploads: 0,
28
- downloads: 0,
29
- bytesUploaded: 0,
30
- bytesDownloaded: 0,
31
- activeUploads: 0,
32
- failedUploads: 0,
33
- storageUsage: 0,
34
- multipartUploads: 0,
35
- resumableSessions: 0,
36
- });
37
- });
38
- test("put/get advance uploads/downloads and byte counters (Req 23.2)", async () => {
39
- const storage = createStorage({ provider: "memory" });
40
- await storage.put("a.txt", "hello"); // 5 bytes
41
- await storage.put("b.txt", "worldd"); // 6 bytes
42
- const got = await storage.get("a.txt");
43
- assert.equal(got.found, true);
44
- const stats = storage.stats();
45
- assert.equal(stats.uploads, 2);
46
- assert.equal(stats.bytesUploaded, 11);
47
- assert.equal(stats.storageUsage, 11);
48
- assert.equal(stats.downloads, 1);
49
- assert.equal(stats.bytesDownloaded, 5);
50
- assert.equal(stats.failedUploads, 0);
51
- });
52
- test("a failed upload (rejected by validation) increments failedUploads (Req 23.2)", async () => {
53
- const storage = createStorage({
54
- provider: "memory",
55
- validation: { maxSize: 3 },
56
- });
57
- await assert.rejects(() => storage.put("big.txt", "too-large"));
58
- const stats = storage.stats();
59
- assert.equal(stats.failedUploads, 1);
60
- assert.equal(stats.uploads, 0);
61
- });
62
- test("multipart and resumable operations advance their counters (Req 23.2)", async () => {
63
- const storage = createStorage({ provider: "memory" });
64
- await storage.createMultipartUpload("m1");
65
- await storage.createMultipartUpload("m2");
66
- await storage.startUpload("r1");
67
- const stats = storage.stats();
68
- assert.equal(stats.multipartUploads, 2);
69
- assert.equal(stats.resumableSessions, 1);
70
- });
71
- test("activeUploads returns to zero after a stream upload completes (Req 23.2)", async () => {
72
- const storage = createStorage({ provider: "memory" });
73
- const { Readable } = await import("node:stream");
74
- await storage.putStream("s.txt", Readable.from([Buffer.from("streamed")]));
75
- const stats = storage.stats();
76
- assert.equal(stats.activeUploads, 0);
77
- assert.equal(stats.uploads, 1);
78
- assert.equal(stats.bytesUploaded, 8);
79
- });
80
- test("probe() returns an all-available default when the driver has no probe (Req 23.3)", async () => {
81
- const storage = createStorage({ provider: "memory" });
82
- const probe = await storage.probe();
83
- assert.deepEqual(probe, {
84
- connectivity: true,
85
- writable: true,
86
- readable: true,
87
- quotaAvailable: true,
88
- });
89
- });
90
- test("probe() delegates to the driver's probe when present (Req 23.3)", async () => {
91
- const driverProbe = {
92
- connectivity: true,
93
- writable: false,
94
- readable: true,
95
- quotaAvailable: true,
96
- };
97
- // A minimal driver implementing the mandatory primitives + probe.
98
- const driver = {
99
- name: "fake",
100
- async put() {
101
- return {
102
- key: "k",
103
- size: 0,
104
- contentType: "application/octet-stream",
105
- etag: "e",
106
- checksum: "c",
107
- accessLevel: "private",
108
- createdAt: 0,
109
- updatedAt: 0,
110
- custom: {},
111
- };
112
- },
113
- async get() {
114
- return { found: false };
115
- },
116
- async exists() {
117
- return false;
118
- },
119
- async delete() { },
120
- async stat() {
121
- return null;
122
- },
123
- async list() {
124
- return [];
125
- },
126
- async putStream() {
127
- throw new Error("unused");
128
- },
129
- async getStream() {
130
- throw new Error("unused");
131
- },
132
- async probe() {
133
- return driverProbe;
134
- },
135
- };
136
- const storage = createStorage({ provider: "fake", driver });
137
- assert.deepEqual(await storage.probe(), driverProbe);
138
- });
139
- test("config.metrics registers all storage metrics of the correct kind and reflects live counts (Req 23.1, 23.2)", async () => {
140
- const metrics = new MetricsRegistry();
141
- const storage = createStorage({ provider: "memory", metrics });
142
- // All metrics registered with the correct kind.
143
- assert.ok(metrics.get(STORAGE_UPLOADS_METRIC) instanceof Counter);
144
- assert.ok(metrics.get(STORAGE_DOWNLOADS_METRIC) instanceof Counter);
145
- assert.ok(metrics.get(STORAGE_BYTES_UPLOADED_METRIC) instanceof Counter);
146
- assert.ok(metrics.get(STORAGE_BYTES_DOWNLOADED_METRIC) instanceof Counter);
147
- assert.ok(metrics.get(STORAGE_FAILED_UPLOADS_METRIC) instanceof Counter);
148
- assert.ok(metrics.get(STORAGE_MULTIPART_METRIC) instanceof Counter);
149
- assert.ok(metrics.get(STORAGE_RESUMABLE_METRIC) instanceof Counter);
150
- assert.ok(metrics.get(STORAGE_ACTIVE_UPLOADS_METRIC) instanceof Gauge);
151
- assert.ok(metrics.get(STORAGE_USAGE_METRIC) instanceof Gauge);
152
- assert.ok(metrics.get(STORAGE_LATENCY_METRIC) instanceof Histogram);
153
- await storage.put("a.txt", "hello"); // 5 bytes
154
- await storage.get("a.txt");
155
- assert.match(metrics.get(STORAGE_UPLOADS_METRIC).render(), /storage_uploads_total 1/);
156
- assert.match(metrics.get(STORAGE_DOWNLOADS_METRIC).render(), /storage_downloads_total 1/);
157
- assert.match(metrics.get(STORAGE_BYTES_UPLOADED_METRIC).render(), /storage_bytes_uploaded_total 5/);
158
- assert.match(metrics.get(STORAGE_BYTES_DOWNLOADED_METRIC).render(), /storage_bytes_downloaded_total 5/);
159
- assert.match(metrics.get(STORAGE_USAGE_METRIC).render(), /storage_usage_bytes 5/);
160
- assert.match(metrics.get(STORAGE_LATENCY_METRIC).render(), /storage_operation_latency_seconds_count 2/);
161
- await storage.close();
162
- });
163
- test("config.health registers the storage health check reporting up over the memory driver (Req 23.3)", async () => {
164
- const health = new HealthCheckRegistry();
165
- const storage = createStorage({ provider: "memory", health });
166
- const live = await health.runLiveness();
167
- assert.ok(STORAGE_HEALTH_CHECK_NAME in live.checks);
168
- const check = live.checks[STORAGE_HEALTH_CHECK_NAME];
169
- assert.equal(check.status, "up");
170
- assert.equal(check.details.connectivity, true);
171
- assert.equal(check.details.writable, true);
172
- assert.equal(check.details.readable, true);
173
- assert.equal(check.details.quotaAvailable, true);
174
- await storage.close();
175
- });
176
- test("the health check reports down when the driver probe reports a failing dimension (Req 23.3)", async () => {
177
- const health = new HealthCheckRegistry();
178
- const driver = {
179
- name: "fake",
180
- async put() {
181
- throw new Error("unused");
182
- },
183
- async get() {
184
- return { found: false };
185
- },
186
- async exists() {
187
- return false;
188
- },
189
- async delete() { },
190
- async stat() {
191
- return null;
192
- },
193
- async list() {
194
- return [];
195
- },
196
- async putStream() {
197
- throw new Error("unused");
198
- },
199
- async getStream() {
200
- throw new Error("unused");
201
- },
202
- async probe() {
203
- return { connectivity: true, writable: false, readable: true, quotaAvailable: true };
204
- },
205
- };
206
- const storage = createStorage({ provider: "fake", driver, health });
207
- const live = await health.runLiveness();
208
- assert.equal(live.checks[STORAGE_HEALTH_CHECK_NAME].status, "down");
209
- assert.equal(live.checks[STORAGE_HEALTH_CHECK_NAME].details.writable, false);
210
- await storage.close();
211
- });
212
- test("registration is idempotent against a shared registry (Req 23.1)", async () => {
213
- const metrics = new MetricsRegistry();
214
- const first = registerStorageObservability({ metrics });
215
- // A second registration against the same registry must not throw.
216
- let second;
217
- assert.doesNotThrow(() => {
218
- second = registerStorageObservability({ metrics });
219
- });
220
- const storage = createStorage({ provider: "memory", metrics });
221
- first.attach(storage);
222
- second.attach(storage);
223
- await storage.put("k", "v");
224
- assert.doesNotThrow(() => {
225
- first.refresh();
226
- second.refresh();
227
- metrics.collect();
228
- });
229
- first.close();
230
- second.close();
231
- await storage.close();
232
- });
233
- test("with no registries, operations proceed and telemetry is a complete no-op (Req 23.4)", async () => {
234
- const storage = createStorage({ provider: "memory" });
235
- const metadata = await storage.put("k", "v");
236
- assert.equal(metadata.key, "k");
237
- assert.equal(storage.stats().uploads, 1);
238
- await storage.close();
239
- });
240
- //# sourceMappingURL=observability.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observability.test.js","sourceRoot":"","sources":["../../src/tests/observability.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=plugin.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.test.d.ts","sourceRoot":"","sources":["../../src/tests/plugin.test.ts"],"names":[],"mappings":""}
@@ -1,112 +0,0 @@
1
- // src/tests/plugin.test.js
2
- // Unit tests for StoragePlugin load/unload (task 23.2).
3
- //
4
- // These cover the two behaviors the task mandates:
5
- //
6
- // 1. After `onLoad`, the plugin exposes the live Storage facade through its
7
- // `storage` accessor and that facade is usable (put/get round-trips)
8
- // (Requirements 20.1, 20.3).
9
- // 2. After `onUnload`, resources are released: the `storage` accessor becomes
10
- // `undefined`, the facade's `close()` is called (which stops the
11
- // observability refresh timer), and any declarative `wireBridges` detach
12
- // functions are invoked (Requirement 20.3).
13
- //
14
- // A minimal SandboxedApp-like stub is passed to the hooks — the plugin ignores
15
- // the app beyond the hook signatures, resolving its metrics/health registries
16
- // from the plugin options instead. Uses the Node.js built-in test runner
17
- // (node:test); executed via `node --test dist/tests/*.test.js`.
18
- //
19
- // Requirements: 20.1, 20.3
20
- import test from "node:test";
21
- import assert from "node:assert/strict";
22
- import { HealthCheckRegistry, MetricsRegistry } from "streetjs";
23
- import { StoragePlugin, STORAGE_HEALTH_CHECK_NAME, STORAGE_UPLOADS_METRIC, } from "../index.js";
24
- /** A minimal SandboxedApp-like stub: exposes only `use` / `on`. */
25
- function fakeApp() {
26
- return { use() { }, on() { } };
27
- }
28
- test("onLoad exposes a usable Storage facade via the `storage` accessor (Req 20.1, 20.3)", async () => {
29
- const plugin = new StoragePlugin({ provider: "memory" });
30
- // No facade before load.
31
- assert.equal(plugin.storage, undefined, "no facade before load");
32
- await plugin.onLoad(fakeApp());
33
- // The accessor now exposes the live facade.
34
- assert.ok(plugin.storage, "facade exposed after load");
35
- const storage = plugin.storage;
36
- // The exposed facade is actually usable — a put/get round-trips.
37
- const written = await storage.put("greeting.txt", "hello world");
38
- assert.equal(written.key, "greeting.txt");
39
- const read = await storage.get("greeting.txt");
40
- assert.equal(read.found, true);
41
- assert.equal(Buffer.from(read.bytes).toString("utf8"), "hello world");
42
- await plugin.onUnload(fakeApp());
43
- });
44
- test("onUnload releases resources: accessor cleared, close() called, detachers invoked (Req 20.3)", async () => {
45
- let attached = 0;
46
- let detached = 0;
47
- let bridgedStorage;
48
- const plugin = new StoragePlugin({
49
- provider: "memory",
50
- wireBridges: [
51
- (storage) => {
52
- attached += 1;
53
- bridgedStorage = storage;
54
- // Returning a detach function that MUST be called on unload.
55
- return () => {
56
- detached += 1;
57
- };
58
- },
59
- () => {
60
- attached += 1;
61
- // A bridge that returns nothing is allowed (no detach registered).
62
- },
63
- ],
64
- });
65
- await plugin.onLoad(fakeApp());
66
- assert.equal(attached, 2, "both wireBridges attach fns ran on load");
67
- assert.equal(bridgedStorage, plugin.storage, "the attach fn received the live facade");
68
- assert.equal(detached, 0, "detach not called before unload");
69
- // Spy on the facade's close() so we can assert it is called on unload.
70
- const facade = plugin.storage;
71
- assert.ok(facade, "facade exposed after load");
72
- let closeCalls = 0;
73
- const originalClose = facade.close.bind(facade);
74
- facade.close = async () => {
75
- closeCalls += 1;
76
- return originalClose();
77
- };
78
- await plugin.onUnload(fakeApp());
79
- // The accessor is cleared, close() ran exactly once, and the returned detach
80
- // function was invoked.
81
- assert.equal(plugin.storage, undefined, "facade accessor cleared after unload");
82
- assert.equal(closeCalls, 1, "facade close() called on unload");
83
- assert.equal(detached, 1, "the returned detach function was called on unload");
84
- });
85
- test("observability from plugin-option registries loads and unloads cleanly (Req 20.3)", async () => {
86
- const metrics = new MetricsRegistry();
87
- const health = new HealthCheckRegistry();
88
- const plugin = new StoragePlugin({ provider: "memory", metrics, health });
89
- await plugin.onLoad(fakeApp());
90
- // Observability wired from the plugin-option registries on load: the storage
91
- // health check is registered and the storage metrics are present.
92
- const live = await health.runLiveness();
93
- assert.ok(STORAGE_HEALTH_CHECK_NAME in live.checks, "storage health check registered on load");
94
- assert.equal(metrics.has(STORAGE_UPLOADS_METRIC), true, "storage metrics registered on load");
95
- // Unload releases cleanly (stops the observability refresh timer) without throwing.
96
- await assert.doesNotReject(() => plugin.onUnload(fakeApp()));
97
- assert.equal(plugin.storage, undefined, "facade cleared after unload");
98
- });
99
- test("onLoad is idempotent — a second load reuses the same facade", async () => {
100
- const plugin = new StoragePlugin({ provider: "memory" });
101
- await plugin.onLoad(fakeApp());
102
- const first = plugin.storage;
103
- await plugin.onLoad(fakeApp());
104
- assert.equal(plugin.storage, first, "facade identity unchanged on a second onLoad");
105
- await plugin.onUnload(fakeApp());
106
- });
107
- test("onUnload is a no-op when never loaded", async () => {
108
- const plugin = new StoragePlugin({ provider: "memory" });
109
- await assert.doesNotReject(() => plugin.onUnload(fakeApp()));
110
- assert.equal(plugin.storage, undefined);
111
- });
112
- //# sourceMappingURL=plugin.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.test.js","sourceRoot":"","sources":["../../src/tests/plugin.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-concurrent.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-concurrent.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-concurrent.test.ts"],"names":[],"mappings":""}
@@ -1,59 +0,0 @@
1
- // Property-based test for concurrent write isolation on the storage facade.
2
- //
3
- // Feature: unified-storage-framework, Property 17: Concurrent uploads never
4
- // corrupt data.
5
- //
6
- // For an arbitrary set of DISTINCT keys, each paired with its own byte content,
7
- // performing all `put` operations CONCURRENTLY (`Promise.all`) against a single
8
- // storage instance results in every key holding exactly its own content. No
9
- // key observes another key's bytes (no cross-contamination), and no bytes are
10
- // corrupted: reading each key back yields bytes exactly equal to the content
11
- // that was intended for that key.
12
- //
13
- // Uses the Node.js built-in test runner (node:test) and fast-check at
14
- // `{ numRuns: 100 }`, exercising the public facade via
15
- // `createStorage({ provider: 'memory' })` imported from the built package
16
- // entry point (`../index.js`), executed via `node --test dist/tests/*.test.js`.
17
- //
18
- // Validates: Requirements 26.6
19
- import test from "node:test";
20
- import assert from "node:assert/strict";
21
- import fc from "fast-check";
22
- import { createStorage } from "../index.js";
23
- /** A fixed clock so object timestamps are deterministic across runs. */
24
- const fixedClock = () => 1_700_000_000_000;
25
- /**
26
- * An arbitrary set of distinct keys each mapped to its own byte content.
27
- *
28
- * `fc.uniqueArray` on non-empty keys guarantees the keys are DISTINCT, so each
29
- * concurrent `put` targets a different object and the property genuinely tests
30
- * cross-key isolation rather than last-writer-wins on a shared key. `minLength:
31
- * 2` ensures there is always genuine concurrency to exercise.
32
- */
33
- const distinctEntriesArb = fc
34
- .uniqueArray(fc.string({ minLength: 1, maxLength: 40 }), {
35
- minLength: 2,
36
- maxLength: 25,
37
- })
38
- .chain((keys) => fc.tuple(fc.constant(keys), fc.array(fc.uint8Array({ minLength: 0, maxLength: 256 }), {
39
- minLength: keys.length,
40
- maxLength: keys.length,
41
- })))
42
- .map(([keys, contents]) => keys.map((key, index) => [key, contents[index]]));
43
- test("Feature: unified-storage-framework, Property 17: Concurrent uploads never corrupt data", async () => {
44
- await fc.assert(fc.asyncProperty(distinctEntriesArb, async (entries) => {
45
- // A single shared storage instance receives every concurrent write.
46
- const storage = createStorage({ provider: "memory", clock: fixedClock });
47
- // Fire all puts CONCURRENTLY against the one instance.
48
- await Promise.all(entries.map(([key, content]) => storage.put(key, content)));
49
- // Every key must hold exactly its own content — read them all back
50
- // concurrently and assert byte-for-byte equality with the intended value.
51
- await Promise.all(entries.map(async ([key, content]) => {
52
- const result = await storage.get(key);
53
- assert.equal(result.found, true, `key ${JSON.stringify(key)} must be present after concurrent writes`);
54
- assert.deepEqual(result.bytes, content, `key ${JSON.stringify(key)} must hold exactly its own content (no cross-contamination)`);
55
- }));
56
- await storage.close();
57
- }), { numRuns: 100 });
58
- });
59
- //# sourceMappingURL=prop-concurrent.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-concurrent.test.js","sourceRoot":"","sources":["../../src/tests/prop-concurrent.test.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,4EAA4E;AAC5E,gBAAgB;AAChB,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,kCAAkC;AAClC,EAAE;AACF,sEAAsE;AACtE,uDAAuD;AACvD,0EAA0E;AAC1E,gFAAgF;AAChF,EAAE;AACF,+BAA+B;AAE/B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wEAAwE;AACxE,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,EAAE;KAC1B,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE;IACvD,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,EAAE;CACd,CAAC;KACD,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CACd,EAAE,CAAC,KAAK,CACN,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EACjB,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE;IACxD,SAAS,EAAE,IAAI,CAAC,MAAM;IACtB,SAAS,EAAE,IAAI,CAAC,MAAM;CACvB,CAAC,CACH,CACF;KACA,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CACxB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAwB,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CACvE,CAAC;AAEJ,IAAI,CAAC,wFAAwF,EAAE,KAAK,IAAI,EAAE;IACxG,MAAM,EAAE,CAAC,MAAM,CACb,EAAE,CAAC,aAAa,CAAC,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACrD,oEAAoE;QACpE,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QAEzE,uDAAuD;QACvD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAE9E,mEAAmE;QACnE,0EAA0E;QAC1E,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACvG,MAAM,CAAC,SAAS,CACd,MAAM,CAAC,KAAK,EACZ,OAAO,EACP,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6DAA6D,CACxF,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC,CAAC,EACF,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-copy.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-copy.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-copy.test.ts"],"names":[],"mappings":""}
@@ -1,63 +0,0 @@
1
- // Property-based test for the storage facade `copy` operation.
2
- //
3
- // Feature: unified-storage-framework, Property 2: Copy is non-mutating and
4
- // duplicates content.
5
- //
6
- // For arbitrary, distinct source/destination keys and arbitrary content, after
7
- // `put(source, bytes)` followed by `copy(source, dest)`:
8
- // - the source still returns the original bytes (unchanged),
9
- // - the destination returns bytes equal to the source content, and
10
- // - the copy result is `{ copied: true }`.
11
- // Additionally, copying a source key that was never written returns
12
- // `{ copied: false }` and creates nothing at the destination.
13
- //
14
- // Uses the Node.js built-in test runner (node:test) and fast-check at
15
- // `{ numRuns: 100 }`, exercising the public facade via
16
- // `createStorage({ provider: 'memory' })` imported from the built package
17
- // entry point (`../index.js`), executed via `node --test dist/tests/*.test.js`.
18
- //
19
- // Validates: Requirements 4.5, 26.3
20
- import test from "node:test";
21
- import assert from "node:assert/strict";
22
- import fc from "fast-check";
23
- import { createStorage } from "../index.js";
24
- /** A fixed clock so object timestamps are deterministic across runs. */
25
- const fixedClock = () => 1_700_000_000_000;
26
- /**
27
- * Arbitrary object content: arbitrary byte arrays (including empty) mapped to a
28
- * Uint8Array, which is what the facade/driver persists.
29
- */
30
- const contentArb = fc.uint8Array({ minLength: 0, maxLength: 256 });
31
- /**
32
- * Two distinct, non-empty object keys. Keys are constrained to non-empty
33
- * strings and the pair is filtered so the source and destination never collide
34
- * (a copy onto itself is a different scenario than "duplicate to a new key").
35
- */
36
- const distinctKeysArb = fc
37
- .tuple(fc.string({ minLength: 1, maxLength: 40 }), fc.string({ minLength: 1, maxLength: 40 }))
38
- .filter(([source, dest]) => source !== dest);
39
- test("Feature: unified-storage-framework, Property 2: Copy is non-mutating and duplicates content", async () => {
40
- await fc.assert(fc.asyncProperty(distinctKeysArb, contentArb, async ([source, dest], content) => {
41
- // A fresh storage instance per case keeps runs independent.
42
- const storage = createStorage({ provider: "memory", clock: fixedClock });
43
- // ── Copy of a missing source: no-op that creates nothing ────────────────
44
- const missing = await storage.copy(source, dest);
45
- assert.equal(missing.copied, false, "copy of a missing source must report copied:false");
46
- assert.equal(await storage.exists(source), false, "missing source must not be created by copy");
47
- assert.equal(await storage.exists(dest), false, "destination must not be created when source is missing");
48
- // ── Copy after a real write: duplicates content, source unchanged ───────
49
- await storage.put(source, content);
50
- const result = await storage.copy(source, dest);
51
- assert.equal(result.copied, true, "copy of an existing source must report copied:true");
52
- // Source still returns the original bytes (non-mutating).
53
- const afterSource = await storage.get(source);
54
- assert.equal(afterSource.found, true, "source must still exist after copy");
55
- assert.deepEqual(afterSource.bytes, content, "source bytes must be unchanged after copy");
56
- // Destination returns bytes equal to the source content (duplicated).
57
- const afterDest = await storage.get(dest);
58
- assert.equal(afterDest.found, true, "destination must exist after copy");
59
- assert.deepEqual(afterDest.bytes, content, "destination bytes must equal the source content");
60
- await storage.close();
61
- }), { numRuns: 100 });
62
- });
63
- //# sourceMappingURL=prop-copy.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-copy.test.js","sourceRoot":"","sources":["../../src/tests/prop-copy.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-delete.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-delete.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-delete.test.ts"],"names":[],"mappings":""}
@@ -1,35 +0,0 @@
1
- // Property-based test for the storage facade's delete semantics.
2
- //
3
- // Property 4: Delete removes visibility. For any stored object, after
4
- // `put(key, bytes)` then `delete(key)`, the object becomes invisible through
5
- // every read surface: `exists(key)` is false, `get(key)` reports not-found,
6
- // and `stat(key)` returns null.
7
- //
8
- // Backed by the zero-dependency in-memory provider via `createStorage({
9
- // provider: 'memory' })`, exercised across arbitrary keys and byte contents
10
- // with fast-check at { numRuns: 100 }. Executed via the Node.js built-in test
11
- // runner (`node --test dist/tests/*.test.js`).
12
- //
13
- // Feature: unified-storage-framework, Property 4
14
- // Validates: Requirements 4.4, 26.4
15
- import test from "node:test";
16
- import assert from "node:assert/strict";
17
- import fc from "fast-check";
18
- import { createStorage } from "../index.js";
19
- test("Feature: unified-storage-framework, Property 4 — delete removes visibility", async () => {
20
- await fc.assert(fc.asyncProperty(
21
- // Arbitrary non-empty keys and arbitrary byte contents.
22
- fc.string({ minLength: 1 }), fc.uint8Array(), async (key, content) => {
23
- const storage = createStorage({ provider: "memory" });
24
- await storage.put(key, content);
25
- await storage.delete(key);
26
- // exists reports false after delete.
27
- assert.equal(await storage.exists(key), false);
28
- // get reports not-found (never throws).
29
- const result = await storage.get(key);
30
- assert.equal(result.found, false);
31
- // stat returns null for the deleted key.
32
- assert.equal(await storage.stat(key), null);
33
- }), { numRuns: 100 });
34
- });
35
- //# sourceMappingURL=prop-delete.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-delete.test.js","sourceRoot":"","sources":["../../src/tests/prop-delete.test.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,sEAAsE;AACtE,6EAA6E;AAC7E,4EAA4E;AAC5E,gCAAgC;AAChC,EAAE;AACF,wEAAwE;AACxE,4EAA4E;AAC5E,8EAA8E;AAC9E,+CAA+C;AAC/C,EAAE;AACF,iDAAiD;AACjD,oCAAoC;AAEpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,IAAI,CACF,4EAA4E,EAC5E,KAAK,IAAI,EAAE;IACT,MAAM,EAAE,CAAC,MAAM,CACb,EAAE,CAAC,aAAa;IACd,wDAAwD;IACxD,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAC3B,EAAE,CAAC,UAAU,EAAE,EACf,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEtD,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE1B,qCAAqC;QACrC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QAE/C,wCAAwC;QACxC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAElC,yCAAyC;QACzC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC,CACF,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-directory.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-directory.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-directory.test.ts"],"names":[],"mappings":""}