@streetjs/storage 1.0.0 → 1.0.2

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/dist/tests/contract.d.ts +19 -0
  6. package/dist/tests/contract.d.ts.map +1 -1
  7. package/dist/tests/contract.js +28 -0
  8. package/dist/tests/contract.js.map +1 -1
  9. package/package.json +10 -6
  10. package/dist/tests/access.test.d.ts +0 -2
  11. package/dist/tests/access.test.d.ts.map +0 -1
  12. package/dist/tests/access.test.js +0 -270
  13. package/dist/tests/access.test.js.map +0 -1
  14. package/dist/tests/azure-driver.test.d.ts +0 -2
  15. package/dist/tests/azure-driver.test.d.ts.map +0 -1
  16. package/dist/tests/azure-driver.test.js +0 -183
  17. package/dist/tests/azure-driver.test.js.map +0 -1
  18. package/dist/tests/backblaze-driver.test.d.ts +0 -2
  19. package/dist/tests/backblaze-driver.test.d.ts.map +0 -1
  20. package/dist/tests/backblaze-driver.test.js +0 -185
  21. package/dist/tests/backblaze-driver.test.js.map +0 -1
  22. package/dist/tests/bridge-degradation.test.d.ts +0 -2
  23. package/dist/tests/bridge-degradation.test.d.ts.map +0 -1
  24. package/dist/tests/bridge-degradation.test.js +0 -138
  25. package/dist/tests/bridge-degradation.test.js.map +0 -1
  26. package/dist/tests/cli.test.d.ts +0 -2
  27. package/dist/tests/cli.test.d.ts.map +0 -1
  28. package/dist/tests/cli.test.js +0 -127
  29. package/dist/tests/cli.test.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,65 +0,0 @@
1
- // Property-based test for the storage facade's multipart upload guarantee.
2
- //
3
- // Property 8 (Multipart equals a single upload): for arbitrary content split
4
- // into arbitrary ordered parts, performing a multipart upload
5
- // (`createMultipartUpload` → `uploadPart` for each part in order →
6
- // `completeMultipartUpload`) produces an object whose bytes are exactly equal
7
- // to a single `put` of the concatenation of those parts. Equality is checked
8
- // both by the raw stored bytes and by the content checksum the drivers compute,
9
- // so the multipart assembly path is proven observationally identical to the
10
- // single-shot write path (Requirement 6.3). Both uploads run over the
11
- // zero-dependency `memory` provider — the identical code path every provider
12
- // shares — exercised via the public facade.
13
- //
14
- // Uses the Node.js built-in test runner (node:test) with fast-check for input
15
- // generation, executed via `node --test dist/tests/*.test.js`. fast-check is
16
- // configured with { numRuns: 100 } per the design's property-testing contract.
17
- //
18
- // Feature: unified-storage-framework, Property 8: Multipart equals a single upload
19
- //
20
- // Validates: Requirements 6.3, 26.5
21
- import test from "node:test";
22
- import assert from "node:assert/strict";
23
- import { Buffer } from "node:buffer";
24
- import fc from "fast-check";
25
- import { createStorage } from "../facade.js";
26
- test("Feature: unified-storage-framework, Property 8: Multipart equals a single upload", async () => {
27
- await fc.assert(fc.asyncProperty(
28
- // A key for both objects and an arbitrary ordered list of parts. At
29
- // least one part is generated so there is always something to upload;
30
- // individual parts may be empty, exercising the assembly of zero-length
31
- // segments.
32
- fc.string(), fc.array(fc.uint8Array(), { minLength: 1, maxLength: 8 }), async (key, parts) => {
33
- // A fresh store per run keeps each key/parts pair independent.
34
- const storage = createStorage({ provider: "memory" });
35
- // The concatenation of the parts, in the order they will be uploaded,
36
- // is the exact byte sequence a single `put` would persist.
37
- const concatenated = Buffer.concat(parts.map((part) => Buffer.from(part)));
38
- // ── Multipart upload path ─────────────────────────────────────────
39
- const multipartKey = `${key}/multipart`;
40
- const uploadId = await storage.createMultipartUpload(multipartKey);
41
- const storedParts = [];
42
- for (let index = 0; index < parts.length; index += 1) {
43
- // Part numbers are 1-based positive integers assigned in order.
44
- const stored = await storage.uploadPart(uploadId, index + 1, parts[index]);
45
- storedParts.push(stored);
46
- }
47
- const multipartMeta = await storage.completeMultipartUpload(uploadId, storedParts);
48
- // ── Single upload path ────────────────────────────────────────────
49
- const singleKey = `${key}/single`;
50
- const singleMeta = await storage.put(singleKey, concatenated);
51
- // The assembled object must equal a single put of the concatenation,
52
- // both in raw bytes and in the computed content checksum.
53
- const multipartResult = await storage.get(multipartKey);
54
- const singleResult = await storage.get(singleKey);
55
- assert.equal(multipartResult.found, true);
56
- assert.equal(singleResult.found, true);
57
- assert.ok(multipartResult.bytes);
58
- assert.ok(singleResult.bytes);
59
- assert.deepEqual(Buffer.from(multipartResult.bytes), Buffer.from(singleResult.bytes));
60
- assert.deepEqual(Buffer.from(multipartResult.bytes), concatenated);
61
- assert.equal(multipartMeta.checksum, singleMeta.checksum);
62
- assert.equal(multipartMeta.size, singleMeta.size);
63
- }), { numRuns: 100 });
64
- });
65
- //# sourceMappingURL=prop-multipart.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-multipart.test.js","sourceRoot":"","sources":["../../src/tests/prop-multipart.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-resumable.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-resumable.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-resumable.test.ts"],"names":[],"mappings":""}
@@ -1,78 +0,0 @@
1
- // Property-based test for the resumable upload equivalence guarantee.
2
- //
3
- // Property 10 (Resumable equals uninterrupted): for arbitrary content, a
4
- // resumable upload — optionally interrupted partway (a first `resumeUpload`
5
- // whose source stream errors after emitting a prefix) and then resumed with the
6
- // object's full content — produces an object byte-identical to an equivalent
7
- // single, uninterrupted `put` of the same content on a separate store. The
8
- // upload is driven through `startUpload` → (optional failing `resumeUpload`) →
9
- // `resumeUpload(full stream)`; the resulting bytes and checksum are compared
10
- // against a plain `put` on an independent `memory` store.
11
- //
12
- // This exercises the facade's ResumableManager over the zero-dependency
13
- // `memory` provider, driving the identical offset-tracked resume code path
14
- // every provider shares (Requirements 7.2, 7.3), and asserts the cross-path
15
- // determinism the framework guarantees (Requirement 26.5).
16
- //
17
- // Uses the Node.js built-in test runner (node:test) with fast-check for input
18
- // generation, executed via `node --test dist/tests/*.test.js`. fast-check is
19
- // configured with { numRuns: 100 } per the design's property-testing contract.
20
- //
21
- // Feature: unified-storage-framework, Property 10: Resumable equals uninterrupted
22
- //
23
- // Validates: Requirements 7.2, 7.3, 26.5
24
- import test from "node:test";
25
- import assert from "node:assert/strict";
26
- import { Readable } from "node:stream";
27
- import { Buffer } from "node:buffer";
28
- import fc from "fast-check";
29
- import { createStorage } from "../facade.js";
30
- test("Feature: unified-storage-framework, Property 10: Resumable equals uninterrupted", async () => {
31
- await fc.assert(fc.asyncProperty(fc.string(), fc.uint8Array(),
32
- // `interrupt` decides whether the upload is interrupted before its
33
- // final resume; `prefixLen` (bounded to the content) picks how many
34
- // bytes the interrupted resume persists before erroring.
35
- fc.boolean(), fc.nat(), async (key, content, interrupt, prefixLen) => {
36
- const payload = Buffer.from(content);
37
- // The resumable store: start a session, optionally interrupt, then
38
- // resume with the FULL content.
39
- const resumableStore = createStorage({ provider: "memory" });
40
- const sessionId = await resumableStore.startUpload(key, {});
41
- if (interrupt && payload.byteLength > 0) {
42
- // Emit a prefix of the content then error partway, simulating a
43
- // network interruption. Only the prefix is persisted (Req 7.2).
44
- const cut = prefixLen % payload.byteLength;
45
- const prefix = payload.subarray(0, cut);
46
- const failing = new Readable({
47
- read() {
48
- if (prefix.byteLength > 0) {
49
- this.push(prefix);
50
- }
51
- this.destroy(new Error("network interruption"));
52
- },
53
- });
54
- await assert.rejects(() => resumableStore.resumeUpload(sessionId, failing), /network interruption/);
55
- // No final object exists yet after an interrupted resume.
56
- assert.equal(await resumableStore.exists(key), false);
57
- }
58
- // Resume with the full content: the manager appends only the bytes
59
- // beyond the persisted offset and completes (Req 7.3).
60
- const resumedMeta = await resumableStore.resumeUpload(sessionId, Readable.from([payload]));
61
- // The reference store: a single, uninterrupted put of the same bytes.
62
- const referenceStore = createStorage({ provider: "memory" });
63
- const singleMeta = await referenceStore.put(key, new Uint8Array(payload), {});
64
- // Byte-identical object: same size and checksum as the single put.
65
- assert.equal(resumedMeta.size, singleMeta.size);
66
- assert.equal(resumedMeta.checksum, singleMeta.checksum);
67
- // And the stored bytes read back equal on both stores.
68
- const resumedGet = await resumableStore.get(key);
69
- const referenceGet = await referenceStore.get(key);
70
- assert.equal(resumedGet.found, true);
71
- assert.equal(referenceGet.found, true);
72
- assert.ok(resumedGet.bytes);
73
- assert.ok(referenceGet.bytes);
74
- assert.deepEqual(Buffer.from(resumedGet.bytes), payload);
75
- assert.deepEqual(Buffer.from(resumedGet.bytes), Buffer.from(referenceGet.bytes));
76
- }), { numRuns: 100 });
77
- });
78
- //# sourceMappingURL=prop-resumable.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-resumable.test.js","sourceRoot":"","sources":["../../src/tests/prop-resumable.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-search.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-search.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-search.test.ts"],"names":[],"mappings":""}
@@ -1,120 +0,0 @@
1
- // Property-based test for the storage facade `search(filters)` operation.
2
- //
3
- // Feature: unified-storage-framework, Property 15 — Search returns exactly the
4
- // matching objects. For an arbitrary set of stored objects (with varied
5
- // owner/tenant/contentType/size/custom metadata) and an arbitrary combination
6
- // of SearchFilters, `storage.search(filters)` returns EXACTLY the set of
7
- // objects that satisfy EVERY supplied filter (conjunctive / AND semantics):
8
- // no matching object is missing and no non-matching object is included. When
9
- // no object satisfies the filters, the result is the empty set.
10
- //
11
- // The expected set is computed independently of the implementation and
12
- // compared for exact set equality.
13
- //
14
- // Uses the public facade via `createStorage({ provider: 'memory' })`, the
15
- // Node.js built-in test runner (node:test), and fast-check configured with
16
- // { numRuns: 100 }. Executed via `node --test dist/tests/*.test.js`.
17
- //
18
- // Validates: Requirements 16.2, 16.3
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
- // UTF-8 byte length, matching how the facade encodes string payloads before
24
- // the driver records `size`.
25
- const byteSize = (content) => new TextEncoder().encode(content).length;
26
- // Domains kept small so filters match frequently, exercising both the
27
- // "matches" and "excludes nothing/everything" branches.
28
- const ownerArb = fc.option(fc.constantFrom("alice", "bob"), { nil: undefined });
29
- const tenantArb = fc.option(fc.constantFrom("acme", "globex"), { nil: undefined });
30
- const contentTypeArb = fc.constantFrom("image/jpeg", "image/png", "text/plain");
31
- const categoryArb = fc.option(fc.constantFrom("invoice", "receipt"), { nil: undefined });
32
- // Keys drawn from a small alphabet so shared prefixes arise often. The alphabet
33
- // excludes '.', so no key collides with the reserved internal key spaces.
34
- const keyArb = fc.stringMatching(/^[a-c/]{1,6}$/).filter((k) => k.length > 0);
35
- // An object to store: a key, content (whose byte length gives size), and
36
- // varied metadata.
37
- const objectArb = fc.record({
38
- key: keyArb,
39
- content: fc.string({ maxLength: 6 }),
40
- owner: ownerArb,
41
- tenant: tenantArb,
42
- contentType: contentTypeArb,
43
- category: categoryArb,
44
- });
45
- // Arbitrary SearchFilters. Every field is optional (undefined => no
46
- // constraint). Filter domains deliberately include values that may match
47
- // nothing (e.g. owner "carol") so the empty-result case is covered.
48
- const filtersArb = fc.record({
49
- prefix: fc.option(fc.stringMatching(/^[a-c/]{0,3}$/), { nil: undefined }),
50
- contentType: fc.option(fc.constantFrom("image/jpeg", "image/png", "text/plain", "application/pdf"), {
51
- nil: undefined,
52
- }),
53
- owner: fc.option(fc.constantFrom("alice", "bob", "carol"), { nil: undefined }),
54
- tenant: fc.option(fc.constantFrom("acme", "globex", "initech"), { nil: undefined }),
55
- minSize: fc.option(fc.integer({ min: 0, max: 6 }), { nil: undefined }),
56
- maxSize: fc.option(fc.integer({ min: 0, max: 6 }), { nil: undefined }),
57
- metadata: fc.option(fc.constantFrom({ category: "invoice" }, { category: "receipt" }), {
58
- nil: undefined,
59
- }),
60
- });
61
- // Independent reference implementation of the AND-semantics filter, evaluated
62
- // against the known write-time metadata of a stored object.
63
- function satisfies(obj, filters) {
64
- const size = byteSize(obj.content);
65
- const custom = obj.category !== undefined ? { category: obj.category } : {};
66
- if (filters.prefix !== undefined && !obj.key.startsWith(filters.prefix))
67
- return false;
68
- if (filters.contentType !== undefined && obj.contentType !== filters.contentType)
69
- return false;
70
- if (filters.owner !== undefined && obj.owner !== filters.owner)
71
- return false;
72
- if (filters.tenant !== undefined && obj.tenant !== filters.tenant)
73
- return false;
74
- if (filters.minSize !== undefined && size < filters.minSize)
75
- return false;
76
- if (filters.maxSize !== undefined && size > filters.maxSize)
77
- return false;
78
- if (filters.metadata !== undefined) {
79
- for (const [field, value] of Object.entries(filters.metadata)) {
80
- if (custom[field] !== value)
81
- return false;
82
- }
83
- }
84
- return true;
85
- }
86
- test("Feature: unified-storage-framework, Property 15 — search returns exactly the matching objects", async () => {
87
- await fc.assert(fc.asyncProperty(fc.uniqueArray(objectArb, {
88
- selector: (obj) => obj.key,
89
- minLength: 0,
90
- maxLength: 12,
91
- }), filtersArb, async (objects, filters) => {
92
- const storage = createStorage({ provider: "memory" });
93
- for (const obj of objects) {
94
- const metadata = {
95
- contentType: obj.contentType,
96
- };
97
- if (obj.owner !== undefined)
98
- metadata.owner = obj.owner;
99
- if (obj.tenant !== undefined)
100
- metadata.tenant = obj.tenant;
101
- if (obj.category !== undefined)
102
- metadata.custom = { category: obj.category };
103
- await storage.put(obj.key, obj.content, metadata);
104
- }
105
- const result = await storage.search(filters);
106
- const observed = new Set(result.map((item) => item.key));
107
- // Expected: exactly the stored keys whose object satisfies every filter.
108
- const expected = new Set(objects.filter((obj) => satisfies(obj, filters)).map((obj) => obj.key));
109
- // Exact set equality: same cardinality + same membership (no extras,
110
- // none missing). An empty expected set implies an empty result.
111
- assert.equal(observed.size, expected.size, `size mismatch: observed ${[...observed]} vs expected ${[...expected]}`);
112
- for (const key of expected) {
113
- assert.ok(observed.has(key), `missing matching key: ${key}`);
114
- }
115
- for (const key of observed) {
116
- assert.ok(expected.has(key), `unexpected non-matching key: ${key}`);
117
- }
118
- }), { numRuns: 100 });
119
- });
120
- //# sourceMappingURL=prop-search.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-search.test.js","sourceRoot":"","sources":["../../src/tests/prop-search.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-signed-url.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-signed-url.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-signed-url.test.ts"],"names":[],"mappings":""}
@@ -1,74 +0,0 @@
1
- // Property-based test for the storage facade's signed URL expiry guarantee.
2
- //
3
- // Property 11 (Signed URL expiry is honored): for an arbitrary key, operation
4
- // (GET/PUT/DELETE), and expiry window, a signed URL minted at time T with
5
- // `expiresInMs = E` verifies as VALID for its authorized operation when checked
6
- // at any instant strictly before `T + E`, and verifies as INVALID with reason
7
- // `'expired'` when checked at any instant at or after `T + E`.
8
- //
9
- // Time is made deterministic with an injected, controllable clock passed to
10
- // `createStorage({ provider: 'memory', signingSecret, clock })`. The facade
11
- // mints the URL over the zero-dependency memory provider (which has no native
12
- // signed-URL capability, so the HMAC simulation path runs). A second
13
- // `SignedUrlService` constructed with the SAME signing secret verifies the URL
14
- // at an explicit check time via its `verify(url, op, now)` path, exercising the
15
- // same code every provider shares (Requirements 8.1, 8.3, 8.4, 26.6).
16
- //
17
- // Uses the Node.js built-in test runner (node:test) with fast-check for input
18
- // generation, executed via `node --test dist/tests/*.test.js`, configured with
19
- // { numRuns: 100 } per the design's property-testing contract.
20
- //
21
- // Feature: unified-storage-framework, Property 11: Signed URL expiry is honored
22
- //
23
- // Validates: Requirements 8.1, 8.3, 8.4, 26.6
24
- import test from "node:test";
25
- import assert from "node:assert/strict";
26
- import fc from "fast-check";
27
- import { createStorage } from "../facade.js";
28
- import { SignedUrlService } from "../signed-url.js";
29
- const SIGNING_SECRET = "prop-11-signing-secret";
30
- test("Feature: unified-storage-framework, Property 11: Signed URL expiry is honored", async () => {
31
- await fc.assert(fc.asyncProperty(
32
- // An arbitrary object key.
33
- fc.string(),
34
- // The single operation the URL authorizes (Requirement 8.1).
35
- fc.constantFrom("GET", "PUT", "DELETE"),
36
- // The mint instant T as epoch milliseconds.
37
- fc.integer({ min: 0, max: 2 ** 40 }),
38
- // A strictly-positive expiry window E, so the URL is valid at mint time.
39
- fc.integer({ min: 1, max: 2 ** 32 }),
40
- // An offset relative to the expiry instant (T + E). A negative offset
41
- // lands strictly before expiry (must be VALID); a non-negative offset
42
- // lands at or after expiry (must be 'expired'). The range straddles zero
43
- // so both branches are exercised across the 100 runs.
44
- fc.integer({ min: -(2 ** 20), max: 2 ** 20 }), async (key, op, mintTime, expiresInMs, offsetFromExpiry) => {
45
- // A controllable clock so minting stamps expiry as T + E deterministically.
46
- let now = mintTime;
47
- const clock = () => now;
48
- const storage = createStorage({
49
- provider: "memory",
50
- signingSecret: SIGNING_SECRET,
51
- clock,
52
- });
53
- // Mint through the facade at time T; expiry = T + E.
54
- const url = await storage.signedUrl(key, op, { expiresInMs });
55
- const expiry = mintTime + expiresInMs;
56
- // Independent verifier sharing only the secret; the check time is
57
- // supplied explicitly so expiry is driven deterministically.
58
- const verifier = new SignedUrlService({ signingSecret: SIGNING_SECRET });
59
- const checkTime = expiry + offsetFromExpiry;
60
- const verification = verifier.verify(url, op, checkTime);
61
- if (checkTime < expiry) {
62
- // Strictly before T + E: the URL is valid for its authorized op.
63
- assert.equal(verification.valid, true);
64
- assert.equal(verification.key, key);
65
- assert.equal(verification.op, op);
66
- }
67
- else {
68
- // At or after T + E: the URL is invalid, specifically 'expired'.
69
- assert.equal(verification.valid, false);
70
- assert.equal(verification.reason, "expired");
71
- }
72
- }), { numRuns: 100 });
73
- });
74
- //# sourceMappingURL=prop-signed-url.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-signed-url.test.js","sourceRoot":"","sources":["../../src/tests/prop-signed-url.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-streaming.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-streaming.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-streaming.test.ts"],"names":[],"mappings":""}
@@ -1,34 +0,0 @@
1
- // Property-based test for the storage facade streaming round-trip guarantee.
2
- //
3
- // Property 7 (Streaming preserves bytes): for arbitrary keys and byte contents,
4
- // persisting bytes with `putStream(key, Readable.from([bytes]))` and then
5
- // reading them back with `getStream(key)` (collecting every emitted chunk)
6
- // yields content bytes exactly equal to the original input. This exercises the
7
- // facade over the zero-dependency `memory` provider, driving the identical
8
- // streaming code path every provider shares (Requirement 5.1, 5.2, 5.4).
9
- //
10
- // Uses the Node.js built-in test runner (node:test) with fast-check for input
11
- // generation, executed via `node --test dist/tests/*.test.js`. fast-check is
12
- // configured with { numRuns: 100 } per the design's property-testing contract.
13
- //
14
- // Feature: unified-storage-framework, Property 7: Streaming preserves bytes
15
- //
16
- // Validates: Requirements 5.1, 5.2, 5.4
17
- import test from "node:test";
18
- import assert from "node:assert/strict";
19
- import { Readable } from "node:stream";
20
- import { buffer as streamToBuffer } from "node:stream/consumers";
21
- import fc from "fast-check";
22
- import { createStorage } from "../facade.js";
23
- test("Feature: unified-storage-framework, Property 7: Streaming preserves bytes", async () => {
24
- await fc.assert(fc.asyncProperty(fc.string(), fc.uint8Array(), async (key, content) => {
25
- // A fresh store per run keeps each key/content pair independent.
26
- const storage = createStorage({ provider: "memory" });
27
- // Build the source stream from the raw bytes and stream it in.
28
- await storage.putStream(key, Readable.from([Buffer.from(content)]));
29
- // Collect all emitted chunks from the readable back into a buffer.
30
- const out = await streamToBuffer(await storage.getStream(key));
31
- assert.deepEqual(new Uint8Array(out), content);
32
- }), { numRuns: 100 });
33
- });
34
- //# sourceMappingURL=prop-streaming.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-streaming.test.js","sourceRoot":"","sources":["../../src/tests/prop-streaming.test.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,EAAE;AACF,gFAAgF;AAChF,0EAA0E;AAC1E,2EAA2E;AAC3E,+EAA+E;AAC/E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,EAAE;AACF,4EAA4E;AAC5E,EAAE;AACF,wCAAwC;AAExC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,IAAI,CACF,2EAA2E,EAC3E,KAAK,IAAI,EAAE;IACT,MAAM,EAAE,CAAC,MAAM,CACb,EAAE,CAAC,aAAa,CACd,EAAE,CAAC,MAAM,EAAE,EACX,EAAE,CAAC,UAAU,EAAE,EACf,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QACrB,iEAAiE;QACjE,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEtD,+DAA+D;QAC/D,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAEpE,mEAAmE;QACnE,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAE/D,MAAM,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC,CACF,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-upload-download.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-upload-download.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-upload-download.test.ts"],"names":[],"mappings":""}
@@ -1,30 +0,0 @@
1
- // Property-based test for the storage facade round-trip guarantee.
2
- //
3
- // Property 1 (Upload/download preserves bytes): for arbitrary keys and byte
4
- // contents, persisting bytes with `put(key, bytes)` and then reading them back
5
- // with `get(key)` yields `found: true` and content bytes exactly equal to the
6
- // original input. This exercises the facade over the zero-dependency `memory`
7
- // provider, driving the identical code path every provider shares.
8
- //
9
- // Uses the Node.js built-in test runner (node:test) with fast-check for input
10
- // generation, executed via `node --test dist/tests/*.test.js`. fast-check is
11
- // configured with { numRuns: 100 } per the design's property-testing contract.
12
- //
13
- // Feature: unified-storage-framework, Property 1: Upload/download preserves bytes
14
- //
15
- // Validates: Requirements 4.1, 4.2, 26.2
16
- import test from "node:test";
17
- import assert from "node:assert/strict";
18
- import fc from "fast-check";
19
- import { createStorage } from "../facade.js";
20
- test("Feature: unified-storage-framework, Property 1: Upload/download preserves bytes", async () => {
21
- await fc.assert(fc.asyncProperty(fc.string(), fc.uint8Array(), async (key, content) => {
22
- // A fresh store per run keeps each key/content pair independent.
23
- const storage = createStorage({ provider: "memory" });
24
- await storage.put(key, content);
25
- const result = await storage.get(key);
26
- assert.equal(result.found, true);
27
- assert.deepEqual(result.bytes, content);
28
- }), { numRuns: 100 });
29
- });
30
- //# sourceMappingURL=prop-upload-download.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-upload-download.test.js","sourceRoot":"","sources":["../../src/tests/prop-upload-download.test.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,8EAA8E;AAC9E,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,EAAE;AACF,kFAAkF;AAClF,EAAE;AACF,yCAAyC;AAEzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,IAAI,CACF,iFAAiF,EACjF,KAAK,IAAI,EAAE;IACT,MAAM,EAAE,CAAC,MAAM,CACb,EAAE,CAAC,aAAa,CACd,EAAE,CAAC,MAAM,EAAE,EACX,EAAE,CAAC,UAAU,EAAE,EACf,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QACrB,iEAAiE;QACjE,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,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CACF,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-validation.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-validation.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-validation.test.ts"],"names":[],"mappings":""}
@@ -1,50 +0,0 @@
1
- // Property-based test for the storage facade's validation pipeline guarantee.
2
- //
3
- // Property 12 (Validation rejects leave no partial object): a Storage instance
4
- // configured with a size validator (`validation: { maxSize: N }`) must, for any
5
- // upload whose byte length exceeds `N`, reject the `put` with a `ValidationError`
6
- // AND leave no partial object behind (`exists(key)` is false afterward). For any
7
- // upload within the limit, `put` succeeds and the object then exists. Because the
8
- // facade runs the validation pipeline before any bytes reach the driver, a
9
- // rejection can never persist content (Requirements 9.3, 9.4).
10
- //
11
- // Backed by the zero-dependency in-memory provider via `createStorage({
12
- // provider: 'memory', validation: { maxSize } })`, exercised across arbitrary
13
- // keys, byte contents, and size limits with fast-check at { numRuns: 100 }.
14
- // Executed via the Node.js built-in test runner (`node --test dist/tests/*.test.js`).
15
- //
16
- // Feature: unified-storage-framework, Property 12
17
- // Validates: Requirements 9.3, 9.4
18
- import test from "node:test";
19
- import assert from "node:assert/strict";
20
- import fc from "fast-check";
21
- import { createStorage } from "../index.js";
22
- import { ValidationError } from "../errors.js";
23
- test("Feature: unified-storage-framework, Property 12 — validation rejects leave no partial object", async () => {
24
- await fc.assert(fc.asyncProperty(
25
- // Arbitrary non-empty keys and arbitrary byte contents.
26
- fc.string({ minLength: 1 }), fc.uint8Array(),
27
- // A non-negative size limit; chosen from a range that straddles typical
28
- // fast-check byte-array lengths so both accepted and rejected inputs are
29
- // generated across the 100 runs.
30
- fc.nat({ max: 16 }), async (key, content, maxSize) => {
31
- // A fresh store per run keeps each key/content pair independent.
32
- const storage = createStorage({
33
- provider: "memory",
34
- validation: { maxSize },
35
- });
36
- const violatesLimit = content.byteLength > maxSize;
37
- if (violatesLimit) {
38
- // The oversized upload must be rejected with a ValidationError...
39
- await assert.rejects(() => storage.put(key, content), (error) => error instanceof ValidationError);
40
- // ...and must leave no partial object stored.
41
- assert.equal(await storage.exists(key), false);
42
- }
43
- else {
44
- // A within-limit upload succeeds and the object then exists.
45
- await storage.put(key, content);
46
- assert.equal(await storage.exists(key), true);
47
- }
48
- }), { numRuns: 100 });
49
- });
50
- //# sourceMappingURL=prop-validation.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-validation.test.js","sourceRoot":"","sources":["../../src/tests/prop-validation.test.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,kFAAkF;AAClF,iFAAiF;AACjF,kFAAkF;AAClF,2EAA2E;AAC3E,+DAA+D;AAC/D,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,sFAAsF;AACtF,EAAE;AACF,kDAAkD;AAClD,mCAAmC;AAEnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,IAAI,CACF,8FAA8F,EAC9F,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;IACf,wEAAwE;IACxE,yEAAyE;IACzE,iCAAiC;IACjC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EACnB,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAC9B,iEAAiE;QACjE,MAAM,OAAO,GAAG,aAAa,CAAC;YAC5B,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,EAAE,OAAO,EAAE;SACxB,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;QAEnD,IAAI,aAAa,EAAE,CAAC;YAClB,kEAAkE;YAClE,MAAM,MAAM,CAAC,OAAO,CAClB,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,EAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,eAAe,CAC5C,CAAC;YACF,8CAA8C;YAC9C,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,6DAA6D;YAC7D,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CACF,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CACjB,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=prop-versioning.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prop-versioning.test.d.ts","sourceRoot":"","sources":["../../src/tests/prop-versioning.test.ts"],"names":[],"mappings":""}