@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.
- package/dist/drivers/local.d.ts +8 -0
- package/dist/drivers/local.d.ts.map +1 -1
- package/dist/drivers/local.js +18 -3
- package/dist/drivers/local.js.map +1 -1
- package/package.json +12 -6
- package/dist/tests/access.test.d.ts +0 -2
- package/dist/tests/access.test.d.ts.map +0 -1
- package/dist/tests/access.test.js +0 -270
- package/dist/tests/access.test.js.map +0 -1
- package/dist/tests/azure-driver.test.d.ts +0 -2
- package/dist/tests/azure-driver.test.d.ts.map +0 -1
- package/dist/tests/azure-driver.test.js +0 -183
- package/dist/tests/azure-driver.test.js.map +0 -1
- package/dist/tests/backblaze-driver.test.d.ts +0 -2
- package/dist/tests/backblaze-driver.test.d.ts.map +0 -1
- package/dist/tests/backblaze-driver.test.js +0 -185
- package/dist/tests/backblaze-driver.test.js.map +0 -1
- package/dist/tests/bridge-degradation.test.d.ts +0 -2
- package/dist/tests/bridge-degradation.test.d.ts.map +0 -1
- package/dist/tests/bridge-degradation.test.js +0 -138
- package/dist/tests/bridge-degradation.test.js.map +0 -1
- package/dist/tests/cli.test.d.ts +0 -2
- package/dist/tests/cli.test.d.ts.map +0 -1
- package/dist/tests/cli.test.js +0 -127
- package/dist/tests/cli.test.js.map +0 -1
- package/dist/tests/contract.d.ts +0 -131
- package/dist/tests/contract.d.ts.map +0 -1
- package/dist/tests/contract.js +0 -222
- package/dist/tests/contract.js.map +0 -1
- package/dist/tests/contract.test.d.ts +0 -2
- package/dist/tests/contract.test.d.ts.map +0 -1
- package/dist/tests/contract.test.js +0 -110
- package/dist/tests/contract.test.js.map +0 -1
- package/dist/tests/directory.test.d.ts +0 -2
- package/dist/tests/directory.test.d.ts.map +0 -1
- package/dist/tests/directory.test.js +0 -125
- package/dist/tests/directory.test.js.map +0 -1
- package/dist/tests/errors.test.d.ts +0 -2
- package/dist/tests/errors.test.d.ts.map +0 -1
- package/dist/tests/errors.test.js +0 -93
- package/dist/tests/errors.test.js.map +0 -1
- package/dist/tests/events-bridge.test.d.ts +0 -2
- package/dist/tests/events-bridge.test.d.ts.map +0 -1
- package/dist/tests/events-bridge.test.js +0 -228
- package/dist/tests/events-bridge.test.js.map +0 -1
- package/dist/tests/example-smoke.test.d.ts +0 -2
- package/dist/tests/example-smoke.test.d.ts.map +0 -1
- package/dist/tests/example-smoke.test.js +0 -34
- package/dist/tests/example-smoke.test.js.map +0 -1
- package/dist/tests/gcs-driver.test.d.ts +0 -2
- package/dist/tests/gcs-driver.test.d.ts.map +0 -1
- package/dist/tests/gcs-driver.test.js +0 -197
- package/dist/tests/gcs-driver.test.js.map +0 -1
- package/dist/tests/image.test.d.ts +0 -2
- package/dist/tests/image.test.d.ts.map +0 -1
- package/dist/tests/image.test.js +0 -102
- package/dist/tests/image.test.js.map +0 -1
- package/dist/tests/lifecycle.test.d.ts +0 -2
- package/dist/tests/lifecycle.test.d.ts.map +0 -1
- package/dist/tests/lifecycle.test.js +0 -171
- package/dist/tests/lifecycle.test.js.map +0 -1
- package/dist/tests/local-driver.test.d.ts +0 -2
- package/dist/tests/local-driver.test.d.ts.map +0 -1
- package/dist/tests/local-driver.test.js +0 -153
- package/dist/tests/local-driver.test.js.map +0 -1
- package/dist/tests/local-streaming.test.d.ts +0 -2
- package/dist/tests/local-streaming.test.d.ts.map +0 -1
- package/dist/tests/local-streaming.test.js +0 -121
- package/dist/tests/local-streaming.test.js.map +0 -1
- package/dist/tests/memory-driver.test.d.ts +0 -2
- package/dist/tests/memory-driver.test.d.ts.map +0 -1
- package/dist/tests/memory-driver.test.js +0 -180
- package/dist/tests/memory-driver.test.js.map +0 -1
- package/dist/tests/memory-streaming.test.d.ts +0 -2
- package/dist/tests/memory-streaming.test.d.ts.map +0 -1
- package/dist/tests/memory-streaming.test.js +0 -92
- package/dist/tests/memory-streaming.test.js.map +0 -1
- package/dist/tests/minio-driver.test.d.ts +0 -2
- package/dist/tests/minio-driver.test.d.ts.map +0 -1
- package/dist/tests/minio-driver.test.js +0 -146
- package/dist/tests/minio-driver.test.js.map +0 -1
- package/dist/tests/non-s3-integration.test.d.ts +0 -2
- package/dist/tests/non-s3-integration.test.d.ts.map +0 -1
- package/dist/tests/non-s3-integration.test.js +0 -201
- package/dist/tests/non-s3-integration.test.js.map +0 -1
- package/dist/tests/observability.registration.test.d.ts +0 -2
- package/dist/tests/observability.registration.test.d.ts.map +0 -1
- package/dist/tests/observability.registration.test.js +0 -103
- package/dist/tests/observability.registration.test.js.map +0 -1
- package/dist/tests/observability.test.d.ts +0 -2
- package/dist/tests/observability.test.d.ts.map +0 -1
- package/dist/tests/observability.test.js +0 -240
- package/dist/tests/observability.test.js.map +0 -1
- package/dist/tests/plugin.test.d.ts +0 -2
- package/dist/tests/plugin.test.d.ts.map +0 -1
- package/dist/tests/plugin.test.js +0 -112
- package/dist/tests/plugin.test.js.map +0 -1
- package/dist/tests/prop-concurrent.test.d.ts +0 -2
- package/dist/tests/prop-concurrent.test.d.ts.map +0 -1
- package/dist/tests/prop-concurrent.test.js +0 -59
- package/dist/tests/prop-concurrent.test.js.map +0 -1
- package/dist/tests/prop-copy.test.d.ts +0 -2
- package/dist/tests/prop-copy.test.d.ts.map +0 -1
- package/dist/tests/prop-copy.test.js +0 -63
- package/dist/tests/prop-copy.test.js.map +0 -1
- package/dist/tests/prop-delete.test.d.ts +0 -2
- package/dist/tests/prop-delete.test.d.ts.map +0 -1
- package/dist/tests/prop-delete.test.js +0 -35
- package/dist/tests/prop-delete.test.js.map +0 -1
- package/dist/tests/prop-directory.test.d.ts +0 -2
- package/dist/tests/prop-directory.test.d.ts.map +0 -1
- package/dist/tests/prop-directory.test.js +0 -118
- package/dist/tests/prop-directory.test.js.map +0 -1
- package/dist/tests/prop-driver-conformance.test.d.ts +0 -2
- package/dist/tests/prop-driver-conformance.test.d.ts.map +0 -1
- package/dist/tests/prop-driver-conformance.test.js +0 -110
- package/dist/tests/prop-driver-conformance.test.js.map +0 -1
- package/dist/tests/prop-driver-equivalence.test.d.ts +0 -2
- package/dist/tests/prop-driver-equivalence.test.d.ts.map +0 -1
- package/dist/tests/prop-driver-equivalence.test.js +0 -163
- package/dist/tests/prop-driver-equivalence.test.js.map +0 -1
- package/dist/tests/prop-lifecycle.test.d.ts +0 -2
- package/dist/tests/prop-lifecycle.test.d.ts.map +0 -1
- package/dist/tests/prop-lifecycle.test.js +0 -83
- package/dist/tests/prop-lifecycle.test.js.map +0 -1
- package/dist/tests/prop-list.test.d.ts +0 -2
- package/dist/tests/prop-list.test.d.ts.map +0 -1
- package/dist/tests/prop-list.test.js +0 -53
- package/dist/tests/prop-list.test.js.map +0 -1
- package/dist/tests/prop-metadata.test.d.ts +0 -2
- package/dist/tests/prop-metadata.test.d.ts.map +0 -1
- package/dist/tests/prop-metadata.test.js +0 -87
- package/dist/tests/prop-metadata.test.js.map +0 -1
- package/dist/tests/prop-move.test.d.ts +0 -2
- package/dist/tests/prop-move.test.d.ts.map +0 -1
- package/dist/tests/prop-move.test.js +0 -67
- package/dist/tests/prop-move.test.js.map +0 -1
- package/dist/tests/prop-multipart-abort.test.d.ts +0 -2
- package/dist/tests/prop-multipart-abort.test.d.ts.map +0 -1
- package/dist/tests/prop-multipart-abort.test.js +0 -48
- package/dist/tests/prop-multipart-abort.test.js.map +0 -1
- package/dist/tests/prop-multipart.test.d.ts +0 -2
- package/dist/tests/prop-multipart.test.d.ts.map +0 -1
- package/dist/tests/prop-multipart.test.js +0 -65
- package/dist/tests/prop-multipart.test.js.map +0 -1
- package/dist/tests/prop-resumable.test.d.ts +0 -2
- package/dist/tests/prop-resumable.test.d.ts.map +0 -1
- package/dist/tests/prop-resumable.test.js +0 -78
- package/dist/tests/prop-resumable.test.js.map +0 -1
- package/dist/tests/prop-search.test.d.ts +0 -2
- package/dist/tests/prop-search.test.d.ts.map +0 -1
- package/dist/tests/prop-search.test.js +0 -120
- package/dist/tests/prop-search.test.js.map +0 -1
- package/dist/tests/prop-signed-url.test.d.ts +0 -2
- package/dist/tests/prop-signed-url.test.d.ts.map +0 -1
- package/dist/tests/prop-signed-url.test.js +0 -74
- package/dist/tests/prop-signed-url.test.js.map +0 -1
- package/dist/tests/prop-streaming.test.d.ts +0 -2
- package/dist/tests/prop-streaming.test.d.ts.map +0 -1
- package/dist/tests/prop-streaming.test.js +0 -34
- package/dist/tests/prop-streaming.test.js.map +0 -1
- package/dist/tests/prop-upload-download.test.d.ts +0 -2
- package/dist/tests/prop-upload-download.test.d.ts.map +0 -1
- package/dist/tests/prop-upload-download.test.js +0 -30
- package/dist/tests/prop-upload-download.test.js.map +0 -1
- package/dist/tests/prop-validation.test.d.ts +0 -2
- package/dist/tests/prop-validation.test.d.ts.map +0 -1
- package/dist/tests/prop-validation.test.js +0 -50
- package/dist/tests/prop-validation.test.js.map +0 -1
- package/dist/tests/prop-versioning.test.d.ts +0 -2
- package/dist/tests/prop-versioning.test.d.ts.map +0 -1
- package/dist/tests/prop-versioning.test.js +0 -74
- package/dist/tests/prop-versioning.test.js.map +0 -1
- package/dist/tests/queue-bridge.test.d.ts +0 -2
- package/dist/tests/queue-bridge.test.d.ts.map +0 -1
- package/dist/tests/queue-bridge.test.js +0 -111
- package/dist/tests/queue-bridge.test.js.map +0 -1
- package/dist/tests/r2-driver.test.d.ts +0 -2
- package/dist/tests/r2-driver.test.d.ts.map +0 -1
- package/dist/tests/r2-driver.test.js +0 -143
- package/dist/tests/r2-driver.test.js.map +0 -1
- package/dist/tests/realtime-bridge.test.d.ts +0 -2
- package/dist/tests/realtime-bridge.test.d.ts.map +0 -1
- package/dist/tests/realtime-bridge.test.js +0 -106
- package/dist/tests/realtime-bridge.test.js.map +0 -1
- package/dist/tests/resumable.test.d.ts +0 -2
- package/dist/tests/resumable.test.d.ts.map +0 -1
- package/dist/tests/resumable.test.js +0 -104
- package/dist/tests/resumable.test.js.map +0 -1
- package/dist/tests/s3-base.test.d.ts +0 -2
- package/dist/tests/s3-base.test.d.ts.map +0 -1
- package/dist/tests/s3-base.test.js +0 -289
- package/dist/tests/s3-base.test.js.map +0 -1
- package/dist/tests/s3-integration.test.d.ts +0 -2
- package/dist/tests/s3-integration.test.d.ts.map +0 -1
- package/dist/tests/s3-integration.test.js +0 -270
- package/dist/tests/s3-integration.test.js.map +0 -1
- package/dist/tests/s3.test.d.ts +0 -2
- package/dist/tests/s3.test.d.ts.map +0 -1
- package/dist/tests/s3.test.js +0 -203
- package/dist/tests/s3.test.js.map +0 -1
- package/dist/tests/scaffold.test.d.ts +0 -2
- package/dist/tests/scaffold.test.d.ts.map +0 -1
- package/dist/tests/scaffold.test.js +0 -13
- package/dist/tests/scaffold.test.js.map +0 -1
- package/dist/tests/search.test.d.ts +0 -2
- package/dist/tests/search.test.d.ts.map +0 -1
- package/dist/tests/search.test.js +0 -106
- package/dist/tests/search.test.js.map +0 -1
- package/dist/tests/supabase-driver.test.d.ts +0 -2
- package/dist/tests/supabase-driver.test.d.ts.map +0 -1
- package/dist/tests/supabase-driver.test.js +0 -196
- package/dist/tests/supabase-driver.test.js.map +0 -1
- package/dist/tests/testing-utilities.test.d.ts +0 -2
- package/dist/tests/testing-utilities.test.d.ts.map +0 -1
- package/dist/tests/testing-utilities.test.js +0 -138
- package/dist/tests/testing-utilities.test.js.map +0 -1
- package/dist/tests/validation.test.d.ts +0 -2
- package/dist/tests/validation.test.d.ts.map +0 -1
- package/dist/tests/validation.test.js +0 -135
- package/dist/tests/validation.test.js.map +0 -1
- package/dist/tests/versioning.test.d.ts +0 -2
- package/dist/tests/versioning.test.d.ts.map +0 -1
- package/dist/tests/versioning.test.js +0 -128
- package/dist/tests/versioning.test.js.map +0 -1
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
// Unit tests for the Realtime integration bridge wired into the storage facade
|
|
2
|
-
// (task 21.3).
|
|
3
|
-
//
|
|
4
|
-
// Verifies the Requirement 19 / 28.3 graceful-degradation semantics over the
|
|
5
|
-
// zero-dependency `memory` provider:
|
|
6
|
-
//
|
|
7
|
-
// - bridgeStorageRealtime broadcasts the correct typed upload event name +
|
|
8
|
-
// payload on the storage upload channel through the structural RealtimeLike
|
|
9
|
-
// bridge (19.1).
|
|
10
|
-
// - a synchronous throw from the realtime layer is fully isolated — never
|
|
11
|
-
// propagates into the caller (19.3).
|
|
12
|
-
// - an asynchronous rejection from the realtime layer is fully isolated (19.3).
|
|
13
|
-
// - with no realtime bridge configured, uploads proceed unaffected (19.3).
|
|
14
|
-
// - a throwing realtime bridge never breaks the streaming/resumable upload path
|
|
15
|
-
// (19.3).
|
|
16
|
-
// - putStream broadcasts upload.started then upload.completed (19.1).
|
|
17
|
-
//
|
|
18
|
-
// Uses the Node.js built-in test runner (node:test); executed via
|
|
19
|
-
// `node --test dist/tests/*.test.js`.
|
|
20
|
-
//
|
|
21
|
-
// Requirements: 19.1, 19.2, 19.3, 28.3
|
|
22
|
-
import test from "node:test";
|
|
23
|
-
import assert from "node:assert/strict";
|
|
24
|
-
import { Readable } from "node:stream";
|
|
25
|
-
import { createStorage, bridgeStorageRealtime, STORAGE_UPLOAD_CHANNEL } from "../index.js";
|
|
26
|
-
/** A recording RealtimeLike double capturing every broadcast (channel, event, payload). */
|
|
27
|
-
function recordingRealtime() {
|
|
28
|
-
const broadcasts = [];
|
|
29
|
-
return {
|
|
30
|
-
broadcasts,
|
|
31
|
-
broadcast(channel, event, payload) {
|
|
32
|
-
broadcasts.push({ channel, event, payload: payload });
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
test("bridgeStorageRealtime broadcasts typed upload events on the upload channel (Req 19.1)", () => {
|
|
37
|
-
const realtime = recordingRealtime();
|
|
38
|
-
const publisher = bridgeStorageRealtime(realtime);
|
|
39
|
-
publisher.started("video.mp4");
|
|
40
|
-
publisher.progress("video.mp4", 512, 1024);
|
|
41
|
-
publisher.completed("video.mp4");
|
|
42
|
-
publisher.failed("video.mp4", "boom");
|
|
43
|
-
assert.deepEqual(realtime.broadcasts.map((b) => b.event), ["upload.started", "upload.progress", "upload.completed", "upload.failed"]);
|
|
44
|
-
// All broadcasts go out on the single upload channel.
|
|
45
|
-
for (const b of realtime.broadcasts) {
|
|
46
|
-
assert.equal(b.channel, STORAGE_UPLOAD_CHANNEL);
|
|
47
|
-
assert.equal(b.payload.key, "video.mp4");
|
|
48
|
-
}
|
|
49
|
-
assert.equal(realtime.broadcasts[1].payload.bytesTransferred, 512);
|
|
50
|
-
assert.equal(realtime.broadcasts[1].payload.totalBytes, 1024);
|
|
51
|
-
assert.equal(realtime.broadcasts[3].payload.error, "boom");
|
|
52
|
-
});
|
|
53
|
-
test("broadcast() passes an already-named event straight through (Req 19.1)", () => {
|
|
54
|
-
const realtime = recordingRealtime();
|
|
55
|
-
const publisher = bridgeStorageRealtime(realtime);
|
|
56
|
-
publisher.broadcast("upload.completed", { key: "k" });
|
|
57
|
-
assert.equal(realtime.broadcasts.length, 1);
|
|
58
|
-
assert.equal(realtime.broadcasts[0].event, "upload.completed");
|
|
59
|
-
assert.equal(realtime.broadcasts[0].payload.key, "k");
|
|
60
|
-
});
|
|
61
|
-
test("a synchronous broadcast failure never throws into the caller (Req 19.3)", () => {
|
|
62
|
-
const publisher = bridgeStorageRealtime({
|
|
63
|
-
broadcast() {
|
|
64
|
-
throw new Error("realtime down");
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
assert.doesNotThrow(() => publisher.started("k"));
|
|
68
|
-
assert.doesNotThrow(() => publisher.completed("k"));
|
|
69
|
-
assert.doesNotThrow(() => publisher.broadcast("upload.failed", { key: "k" }));
|
|
70
|
-
});
|
|
71
|
-
test("an asynchronous broadcast rejection never throws into the caller (Req 19.3)", async () => {
|
|
72
|
-
const publisher = bridgeStorageRealtime({
|
|
73
|
-
broadcast() {
|
|
74
|
-
return Promise.reject(new Error("async realtime down"));
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
assert.doesNotThrow(() => publisher.progress("k", 1, 2));
|
|
78
|
-
// Give any swallowed rejection a tick to settle without an unhandled error.
|
|
79
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
80
|
-
});
|
|
81
|
-
test("facade broadcasts upload.started then upload.completed on putStream (Req 19.1)", async () => {
|
|
82
|
-
const realtime = recordingRealtime();
|
|
83
|
-
const storage = createStorage({ provider: "memory", bridges: { realtime } });
|
|
84
|
-
await storage.putStream("big.bin", Readable.from([Buffer.from("hello world")]));
|
|
85
|
-
assert.deepEqual(realtime.broadcasts.map((b) => b.event), ["upload.started", "upload.completed"]);
|
|
86
|
-
assert.equal(realtime.broadcasts[0].payload.key, "big.bin");
|
|
87
|
-
assert.equal(await storage.exists("big.bin"), true);
|
|
88
|
-
});
|
|
89
|
-
test("a throwing realtime bridge never breaks the upload path (Req 19.3)", async () => {
|
|
90
|
-
const throwingRealtime = {
|
|
91
|
-
broadcast() {
|
|
92
|
-
throw new Error("realtime down");
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
const storage = createStorage({ provider: "memory", bridges: { realtime: throwingRealtime } });
|
|
96
|
-
const metadata = await storage.putStream("k", Readable.from([Buffer.from("data")]));
|
|
97
|
-
assert.equal(metadata.key, "k");
|
|
98
|
-
assert.equal(await storage.exists("k"), true);
|
|
99
|
-
});
|
|
100
|
-
test("with no realtime bridge configured, uploads proceed unaffected (Req 19.3)", async () => {
|
|
101
|
-
const storage = createStorage({ provider: "memory" });
|
|
102
|
-
const metadata = await storage.putStream("k", Readable.from([Buffer.from("data")]));
|
|
103
|
-
assert.equal(metadata.key, "k");
|
|
104
|
-
assert.equal(await storage.exists("k"), true);
|
|
105
|
-
});
|
|
106
|
-
//# sourceMappingURL=realtime-bridge.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-bridge.test.js","sourceRoot":"","sources":["../../src/tests/realtime-bridge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resumable.test.d.ts","sourceRoot":"","sources":["../../src/tests/resumable.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
// Unit tests for the resumable upload manager wired into the storage facade
|
|
2
|
-
// (task 11.1).
|
|
3
|
-
//
|
|
4
|
-
// Verifies the Requirement 7 semantics over the zero-dependency `memory`
|
|
5
|
-
// provider (which has no native `resumable` capability, so the manager
|
|
6
|
-
// simulates offset-tracked sessions over the driver primitives):
|
|
7
|
-
//
|
|
8
|
-
// - startUpload creates a session and returns a session id (7.1).
|
|
9
|
-
// - resumeUpload with the full content creates an object byte-identical to an
|
|
10
|
-
// equivalent single put / uninterrupted upload (7.2, 7.3).
|
|
11
|
-
// - an interrupted resume followed by a second resume with the full content
|
|
12
|
-
// continues from the last persisted offset and yields identical bytes (7.2,
|
|
13
|
-
// 7.3).
|
|
14
|
-
// - cancelUpload before completion discards the session and creates no object
|
|
15
|
-
// (7.4), and a subsequent resume of that session is rejected.
|
|
16
|
-
// - cancelUpload of an already-completing session is ignored so the object is
|
|
17
|
-
// still created (7.5).
|
|
18
|
-
//
|
|
19
|
-
// Uses the Node.js built-in test runner (node:test); executed via
|
|
20
|
-
// `node --test dist/tests/*.test.js`.
|
|
21
|
-
//
|
|
22
|
-
// Requirements: 7.1, 7.2, 7.3, 7.4, 7.5
|
|
23
|
-
import test from "node:test";
|
|
24
|
-
import assert from "node:assert/strict";
|
|
25
|
-
import { Readable } from "node:stream";
|
|
26
|
-
import { createStorage } from "../facade.js";
|
|
27
|
-
import { StorageError } from "../errors.js";
|
|
28
|
-
/** A fixed clock for deterministic timestamps. */
|
|
29
|
-
const fixedClock = () => 1_700_000_000_000;
|
|
30
|
-
test("startUpload returns a session id (Req 7.1)", async () => {
|
|
31
|
-
const storage = createStorage({ provider: "memory", clock: fixedClock });
|
|
32
|
-
const sessionId = await storage.startUpload("uploads/file.bin", { contentType: "text/plain" });
|
|
33
|
-
assert.equal(typeof sessionId, "string");
|
|
34
|
-
assert.ok(sessionId.length > 0);
|
|
35
|
-
});
|
|
36
|
-
test("resumeUpload with the full content equals a single put (Req 7.2, 7.3)", async () => {
|
|
37
|
-
const storage = createStorage({ provider: "memory", clock: fixedClock });
|
|
38
|
-
const payload = Buffer.from("the quick brown fox jumps over the lazy dog");
|
|
39
|
-
const sessionId = await storage.startUpload("k", { contentType: "text/plain" });
|
|
40
|
-
const meta = await storage.resumeUpload(sessionId, Readable.from([payload]));
|
|
41
|
-
assert.equal(meta.key, "k");
|
|
42
|
-
assert.equal(meta.size, payload.byteLength);
|
|
43
|
-
assert.equal(meta.contentType, "text/plain");
|
|
44
|
-
const got = await storage.get("k");
|
|
45
|
-
assert.equal(got.found, true);
|
|
46
|
-
assert.deepEqual(Buffer.from(got.bytes), payload);
|
|
47
|
-
// Byte-identical to an equivalent single, uninterrupted put.
|
|
48
|
-
const reference = createStorage({ provider: "memory", clock: fixedClock });
|
|
49
|
-
const single = await reference.put("k", new Uint8Array(payload), { contentType: "text/plain" });
|
|
50
|
-
assert.equal(meta.checksum, single.checksum);
|
|
51
|
-
assert.equal(meta.size, single.size);
|
|
52
|
-
});
|
|
53
|
-
test("interrupted resume continues from the persisted offset (Req 7.2, 7.3)", async () => {
|
|
54
|
-
const storage = createStorage({ provider: "memory", clock: fixedClock });
|
|
55
|
-
const payload = Buffer.from("0123456789ABCDEFGHIJ");
|
|
56
|
-
const sessionId = await storage.startUpload("resumable/obj", {});
|
|
57
|
-
// First resume is interrupted partway: the source stream errors after
|
|
58
|
-
// emitting the first 8 bytes, so only those 8 bytes are persisted.
|
|
59
|
-
const firstHalf = payload.subarray(0, 8);
|
|
60
|
-
const failing = new Readable({
|
|
61
|
-
read() {
|
|
62
|
-
this.push(firstHalf);
|
|
63
|
-
this.destroy(new Error("network interruption"));
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
await assert.rejects(() => storage.resumeUpload(sessionId, failing), /network interruption/);
|
|
67
|
-
// No final object exists yet.
|
|
68
|
-
assert.equal(await storage.exists("resumable/obj"), false);
|
|
69
|
-
// Resume again with the FULL content: the manager skips the persisted prefix
|
|
70
|
-
// and appends the remainder, completing the upload.
|
|
71
|
-
const meta = await storage.resumeUpload(sessionId, Readable.from([payload]));
|
|
72
|
-
assert.equal(meta.size, payload.byteLength);
|
|
73
|
-
const got = await storage.get("resumable/obj");
|
|
74
|
-
assert.equal(got.found, true);
|
|
75
|
-
assert.deepEqual(Buffer.from(got.bytes), payload);
|
|
76
|
-
});
|
|
77
|
-
test("cancelUpload before completion discards the session (Req 7.4)", async () => {
|
|
78
|
-
const storage = createStorage({ provider: "memory", clock: fixedClock });
|
|
79
|
-
const sessionId = await storage.startUpload("cancel/me", {});
|
|
80
|
-
await storage.cancelUpload(sessionId);
|
|
81
|
-
// No object was created.
|
|
82
|
-
assert.equal(await storage.exists("cancel/me"), false);
|
|
83
|
-
// A cancelled session can no longer be resumed.
|
|
84
|
-
await assert.rejects(() => storage.resumeUpload(sessionId, Readable.from([Buffer.from("data")])), StorageError);
|
|
85
|
-
});
|
|
86
|
-
test("cancelUpload while completing lets the upload finish (Req 7.5)", async () => {
|
|
87
|
-
const storage = createStorage({ provider: "memory", clock: fixedClock });
|
|
88
|
-
const payload = Buffer.from("committing payload");
|
|
89
|
-
const sessionId = await storage.startUpload("committing/obj", {});
|
|
90
|
-
// Start the resume but do not await it yet; a paused stream lets us interleave
|
|
91
|
-
// a cancel. The stream emits its content then ends, driving the session into
|
|
92
|
-
// its completing phase.
|
|
93
|
-
const resumePromise = storage.resumeUpload(sessionId, Readable.from([payload]));
|
|
94
|
-
// Cancel concurrently. Because the manager marks the session completing once
|
|
95
|
-
// the stream is consumed, this cancel is either a no-op (session gone) or
|
|
96
|
-
// ignored (already completing) — either way the object must be created.
|
|
97
|
-
const finalMeta = await resumePromise;
|
|
98
|
-
await storage.cancelUpload(sessionId);
|
|
99
|
-
assert.equal(finalMeta.key, "committing/obj");
|
|
100
|
-
const got = await storage.get("committing/obj");
|
|
101
|
-
assert.equal(got.found, true);
|
|
102
|
-
assert.deepEqual(Buffer.from(got.bytes), payload);
|
|
103
|
-
});
|
|
104
|
-
//# sourceMappingURL=resumable.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resumable.test.js","sourceRoot":"","sources":["../../src/tests/resumable.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"s3-base.test.d.ts","sourceRoot":"","sources":["../../src/tests/s3-base.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
// Unit tests for the shared S3-style driver base and the S3ClientLike contract
|
|
2
|
-
// (task 28.1). A fake in-memory S3ClientLike stands in for a provider SDK so the
|
|
3
|
-
// base can be exercised with no external service and no SDK dependency.
|
|
4
|
-
//
|
|
5
|
-
// Coverage:
|
|
6
|
-
// - mandatory primitives put/get/exists/delete/stat/list mapped onto the client
|
|
7
|
-
// - typed metadata round-trips (owner/tenant/accessLevel/custom/contentType),
|
|
8
|
-
// createdAt preserved on overwrite, computed size/checksum
|
|
9
|
-
// - consistent not-found reporting (get -> found:false, stat -> null,
|
|
10
|
-
// getStream -> NotFoundError)
|
|
11
|
-
// - streaming round-trip via putStream/getStream
|
|
12
|
-
// - native multipart delegation when the client exposes the method set; absent
|
|
13
|
-
// otherwise (facade would simulate)
|
|
14
|
-
// - versioning/lifecycle/signedUrl delegated only when injected via options
|
|
15
|
-
// - the shared driver contract-conformance suite passes against the base
|
|
16
|
-
//
|
|
17
|
-
// Requirements: 2.3, 3.1, 3.3
|
|
18
|
-
import test from "node:test";
|
|
19
|
-
import assert from "node:assert/strict";
|
|
20
|
-
import { S3StyleDriver, createS3StyleDriver, } from "../drivers/s3-base.js";
|
|
21
|
-
import { NotFoundError } from "../errors.js";
|
|
22
|
-
import { registerStorageDriverContractTests } from "./contract.js";
|
|
23
|
-
const FIXED_NOW = 1_700_000_000_000;
|
|
24
|
-
const fixedClock = () => FIXED_NOW;
|
|
25
|
-
function bytes(str) {
|
|
26
|
-
return new TextEncoder().encode(str);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* A minimal in-memory S3ClientLike. `withMultipart` toggles whether the native
|
|
30
|
-
* multipart method set is present so we can assert conditional capability
|
|
31
|
-
* wiring.
|
|
32
|
-
*/
|
|
33
|
-
function makeFakeClient({ withMultipart = false } = {}) {
|
|
34
|
-
const objects = new Map(); // key -> { body, contentType, metadata }
|
|
35
|
-
const uploads = new Map(); // uploadId -> { key, metadata, parts: Map<number, body> }
|
|
36
|
-
let uploadCounterSeed = 0;
|
|
37
|
-
const client = {
|
|
38
|
-
async putObject({ key, body, contentType, metadata }) {
|
|
39
|
-
objects.set(key, {
|
|
40
|
-
body: body.slice(),
|
|
41
|
-
contentType,
|
|
42
|
-
metadata: metadata ? { ...metadata } : undefined,
|
|
43
|
-
});
|
|
44
|
-
return { etag: `"${key}-etag"` };
|
|
45
|
-
},
|
|
46
|
-
async getObject({ key }) {
|
|
47
|
-
const obj = objects.get(key);
|
|
48
|
-
if (obj === undefined) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
body: obj.body.slice(),
|
|
53
|
-
contentType: obj.contentType,
|
|
54
|
-
etag: `"${key}-etag"`,
|
|
55
|
-
size: obj.body.byteLength,
|
|
56
|
-
lastModified: FIXED_NOW,
|
|
57
|
-
metadata: obj.metadata,
|
|
58
|
-
};
|
|
59
|
-
},
|
|
60
|
-
async headObject({ key }) {
|
|
61
|
-
const obj = objects.get(key);
|
|
62
|
-
if (obj === undefined) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
contentType: obj.contentType,
|
|
67
|
-
etag: `"${key}-etag"`,
|
|
68
|
-
size: obj.body.byteLength,
|
|
69
|
-
lastModified: FIXED_NOW,
|
|
70
|
-
metadata: obj.metadata,
|
|
71
|
-
};
|
|
72
|
-
},
|
|
73
|
-
async deleteObject({ key }) {
|
|
74
|
-
objects.delete(key);
|
|
75
|
-
},
|
|
76
|
-
async listObjects({ prefix }) {
|
|
77
|
-
return [...objects.entries()]
|
|
78
|
-
.filter(([key]) => key.startsWith(prefix))
|
|
79
|
-
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
80
|
-
.map(([key, obj]) => ({ key, size: obj.body.byteLength, updatedAt: FIXED_NOW }));
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
if (withMultipart) {
|
|
84
|
-
client.createMultipartUpload = async ({ key, contentType, metadata }) => {
|
|
85
|
-
const uploadId = `upload-${(uploadCounterSeed += 1)}`;
|
|
86
|
-
uploads.set(uploadId, { key, contentType, metadata, parts: new Map() });
|
|
87
|
-
return { uploadId };
|
|
88
|
-
};
|
|
89
|
-
client.uploadPart = async ({ uploadId, partNumber, body }) => {
|
|
90
|
-
uploads.get(uploadId).parts.set(partNumber, body.slice());
|
|
91
|
-
return { etag: `"${uploadId}-${partNumber}"` };
|
|
92
|
-
};
|
|
93
|
-
client.completeMultipartUpload = async ({ uploadId, parts }) => {
|
|
94
|
-
const session = uploads.get(uploadId);
|
|
95
|
-
const ordered = [...parts].sort((a, b) => a.partNumber - b.partNumber);
|
|
96
|
-
const buffers = ordered.map((p) => Buffer.from(session.parts.get(p.partNumber)));
|
|
97
|
-
const body = new Uint8Array(Buffer.concat(buffers));
|
|
98
|
-
objects.set(session.key, {
|
|
99
|
-
body,
|
|
100
|
-
contentType: session.contentType,
|
|
101
|
-
metadata: session.metadata,
|
|
102
|
-
});
|
|
103
|
-
uploads.delete(uploadId);
|
|
104
|
-
return { etag: `"${session.key}-etag"` };
|
|
105
|
-
};
|
|
106
|
-
client.abortMultipartUpload = async ({ uploadId }) => {
|
|
107
|
-
uploads.delete(uploadId);
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
return { client, objects, uploads };
|
|
111
|
-
}
|
|
112
|
-
function makeDriver(opts = {}) {
|
|
113
|
-
const { client } = makeFakeClient(opts);
|
|
114
|
-
return createS3StyleDriver(client, { clock: fixedClock, name: "s3", ...opts.driverOptions });
|
|
115
|
-
}
|
|
116
|
-
// ── primitives ────────────────────────────────────────────────────────────────
|
|
117
|
-
test("put returns typed metadata with computed size/checksum and defaults", async () => {
|
|
118
|
-
const driver = makeDriver();
|
|
119
|
-
const content = bytes("hello world");
|
|
120
|
-
const meta = await driver.put("greetings/hello.txt", content, {});
|
|
121
|
-
assert.equal(meta.key, "greetings/hello.txt");
|
|
122
|
-
assert.equal(meta.size, content.byteLength);
|
|
123
|
-
assert.match(meta.checksum, /^[0-9a-f]{64}$/);
|
|
124
|
-
assert.equal(meta.contentType, "application/octet-stream");
|
|
125
|
-
assert.equal(meta.accessLevel, "private");
|
|
126
|
-
assert.deepEqual(meta.custom, {});
|
|
127
|
-
assert.equal(meta.createdAt, FIXED_NOW);
|
|
128
|
-
assert.equal(meta.updatedAt, FIXED_NOW);
|
|
129
|
-
});
|
|
130
|
-
test("get round-trips bytes and typed metadata across the client boundary", async () => {
|
|
131
|
-
const driver = makeDriver();
|
|
132
|
-
const content = bytes("the quick brown fox");
|
|
133
|
-
await driver.put("docs/fox.txt", content, {
|
|
134
|
-
contentType: "text/plain",
|
|
135
|
-
owner: "user-1",
|
|
136
|
-
tenant: "tenant-a",
|
|
137
|
-
accessLevel: "public",
|
|
138
|
-
custom: { label: "invoice" },
|
|
139
|
-
});
|
|
140
|
-
const result = await driver.get("docs/fox.txt");
|
|
141
|
-
assert.equal(result.found, true);
|
|
142
|
-
assert.deepEqual(result.bytes, content);
|
|
143
|
-
assert.equal(result.metadata.contentType, "text/plain");
|
|
144
|
-
assert.equal(result.metadata.owner, "user-1");
|
|
145
|
-
assert.equal(result.metadata.tenant, "tenant-a");
|
|
146
|
-
assert.equal(result.metadata.accessLevel, "public");
|
|
147
|
-
assert.deepEqual(result.metadata.custom, { label: "invoice" });
|
|
148
|
-
});
|
|
149
|
-
test("get preserves arbitrary binary bytes without mutation", async () => {
|
|
150
|
-
const driver = makeDriver();
|
|
151
|
-
const content = new Uint8Array([0, 255, 1, 254, 127, 128]);
|
|
152
|
-
await driver.put("bin/data", content, {});
|
|
153
|
-
const result = await driver.get("bin/data");
|
|
154
|
-
assert.equal(result.found, true);
|
|
155
|
-
assert.deepEqual(result.bytes, content);
|
|
156
|
-
});
|
|
157
|
-
test("exists reflects presence via the client", async () => {
|
|
158
|
-
const driver = makeDriver();
|
|
159
|
-
await driver.put("present.txt", bytes("here"), {});
|
|
160
|
-
assert.equal(await driver.exists("present.txt"), true);
|
|
161
|
-
assert.equal(await driver.exists("absent.txt"), false);
|
|
162
|
-
});
|
|
163
|
-
test("delete removes visibility", async () => {
|
|
164
|
-
const driver = makeDriver();
|
|
165
|
-
await driver.put("temp/file.txt", bytes("bye"), {});
|
|
166
|
-
await driver.delete("temp/file.txt");
|
|
167
|
-
assert.equal(await driver.exists("temp/file.txt"), false);
|
|
168
|
-
const result = await driver.get("temp/file.txt");
|
|
169
|
-
assert.equal(result.found, false);
|
|
170
|
-
});
|
|
171
|
-
test("stat returns metadata without content and null for a missing key", async () => {
|
|
172
|
-
const driver = makeDriver();
|
|
173
|
-
await driver.put("stat/key.txt", bytes("stat me"), { contentType: "text/plain" });
|
|
174
|
-
const meta = await driver.stat("stat/key.txt");
|
|
175
|
-
assert.notEqual(meta, null);
|
|
176
|
-
assert.ok(meta);
|
|
177
|
-
assert.equal(meta.key, "stat/key.txt");
|
|
178
|
-
assert.equal(meta.contentType, "text/plain");
|
|
179
|
-
assert.equal(meta.bytes, undefined);
|
|
180
|
-
assert.equal(await driver.stat("no/such/key"), null);
|
|
181
|
-
});
|
|
182
|
-
test("list returns prefix-matching items with size and updatedAt", async () => {
|
|
183
|
-
const driver = makeDriver();
|
|
184
|
-
await driver.put("photos/b.png", bytes("bb"), {});
|
|
185
|
-
await driver.put("photos/a.png", bytes("a"), {});
|
|
186
|
-
await driver.put("docs/readme.md", bytes("doc"), {});
|
|
187
|
-
const items = await driver.list("photos/");
|
|
188
|
-
assert.deepEqual(items.map((item) => item.key), ["photos/a.png", "photos/b.png"]);
|
|
189
|
-
assert.equal(items[0].size, 1);
|
|
190
|
-
assert.equal(items[0].updatedAt, FIXED_NOW);
|
|
191
|
-
});
|
|
192
|
-
// ── createdAt preservation on overwrite ────────────────────────────────────────
|
|
193
|
-
test("overwrite preserves createdAt and advances updatedAt", async () => {
|
|
194
|
-
let now = 1000;
|
|
195
|
-
const { client } = makeFakeClient();
|
|
196
|
-
const driver = createS3StyleDriver(client, { clock: () => now });
|
|
197
|
-
const first = await driver.put("k", bytes("v1"), {});
|
|
198
|
-
assert.equal(first.createdAt, 1000);
|
|
199
|
-
now = 2000;
|
|
200
|
-
const second = await driver.put("k", bytes("v2-longer"), {});
|
|
201
|
-
assert.equal(second.createdAt, 1000, "createdAt must be preserved on overwrite");
|
|
202
|
-
assert.equal(second.updatedAt, 2000, "updatedAt must advance");
|
|
203
|
-
});
|
|
204
|
-
// ── not-found semantics ────────────────────────────────────────────────────────
|
|
205
|
-
test("get on a missing key reports found:false (not an error)", async () => {
|
|
206
|
-
const driver = makeDriver();
|
|
207
|
-
const result = await driver.get("missing");
|
|
208
|
-
assert.equal(result.found, false);
|
|
209
|
-
});
|
|
210
|
-
test("getStream on a missing key throws NotFoundError", async () => {
|
|
211
|
-
const driver = makeDriver();
|
|
212
|
-
await assert.rejects(() => driver.getStream("missing"), NotFoundError);
|
|
213
|
-
});
|
|
214
|
-
// ── streaming ──────────────────────────────────────────────────────────────────
|
|
215
|
-
test("putStream + getStream round-trips content", async () => {
|
|
216
|
-
const { Readable } = await import("node:stream");
|
|
217
|
-
const driver = makeDriver();
|
|
218
|
-
const content = bytes("streamed content across chunks");
|
|
219
|
-
await driver.putStream("stream/file.txt", Readable.from([Buffer.from(content.slice(0, 10)), Buffer.from(content.slice(10))]), { contentType: "text/plain" });
|
|
220
|
-
const stream = await driver.getStream("stream/file.txt");
|
|
221
|
-
const chunks = [];
|
|
222
|
-
for await (const chunk of stream) {
|
|
223
|
-
chunks.push(Buffer.from(chunk));
|
|
224
|
-
}
|
|
225
|
-
assert.deepEqual(new Uint8Array(Buffer.concat(chunks)), content);
|
|
226
|
-
});
|
|
227
|
-
// ── capability delegation ───────────────────────────────────────────────────────
|
|
228
|
-
test("multipart capability is undefined when the client lacks multipart methods", () => {
|
|
229
|
-
const { client } = makeFakeClient({ withMultipart: false });
|
|
230
|
-
const driver = createS3StyleDriver(client);
|
|
231
|
-
assert.equal(driver.multipart, undefined);
|
|
232
|
-
});
|
|
233
|
-
test("multipart capability is wired and assembles parts when the client supports it", async () => {
|
|
234
|
-
const { client } = makeFakeClient({ withMultipart: true });
|
|
235
|
-
const driver = createS3StyleDriver(client, { clock: fixedClock });
|
|
236
|
-
assert.notEqual(driver.multipart, undefined);
|
|
237
|
-
const mp = driver.multipart;
|
|
238
|
-
const uploadId = await mp.create("big/file.bin", { contentType: "text/plain" });
|
|
239
|
-
const p1 = await mp.uploadPart(uploadId, 1, bytes("part-one-"));
|
|
240
|
-
const p2 = await mp.uploadPart(uploadId, 2, bytes("part-two"));
|
|
241
|
-
const meta = await mp.complete(uploadId, [p1, p2]);
|
|
242
|
-
assert.equal(meta.key, "big/file.bin");
|
|
243
|
-
const result = await driver.get("big/file.bin");
|
|
244
|
-
assert.equal(result.found, true);
|
|
245
|
-
assert.deepEqual(result.bytes, bytes("part-one-part-two"));
|
|
246
|
-
});
|
|
247
|
-
test("multipart abort discards the upload without creating an object", async () => {
|
|
248
|
-
const { client } = makeFakeClient({ withMultipart: true });
|
|
249
|
-
const driver = createS3StyleDriver(client, { clock: fixedClock });
|
|
250
|
-
const mp = driver.multipart;
|
|
251
|
-
const uploadId = await mp.create("aborted/file.bin", {});
|
|
252
|
-
await mp.uploadPart(uploadId, 1, bytes("data"));
|
|
253
|
-
await mp.abort(uploadId);
|
|
254
|
-
assert.equal(await driver.exists("aborted/file.bin"), false);
|
|
255
|
-
});
|
|
256
|
-
test("versioning/lifecycle/signedUrl are undefined unless injected", () => {
|
|
257
|
-
const { client } = makeFakeClient();
|
|
258
|
-
const bare = createS3StyleDriver(client);
|
|
259
|
-
assert.equal(bare.versioning, undefined);
|
|
260
|
-
assert.equal(bare.lifecycle, undefined);
|
|
261
|
-
assert.equal(bare.signedUrl, undefined);
|
|
262
|
-
});
|
|
263
|
-
test("native versioning/lifecycle/signedUrl capabilities are delegated when injected", () => {
|
|
264
|
-
const { client } = makeFakeClient();
|
|
265
|
-
const versioning = { snapshot: async () => null, list: async () => [], restore: async () => ({}), deleteVersion: async () => { } };
|
|
266
|
-
const lifecycle = { apply: async () => [] };
|
|
267
|
-
const signedUrl = { sign: async () => "url", verify: () => ({ valid: true }) };
|
|
268
|
-
const driver = createS3StyleDriver(client, {
|
|
269
|
-
capabilities: { versioning, lifecycle, signedUrl },
|
|
270
|
-
});
|
|
271
|
-
assert.equal(driver.versioning, versioning);
|
|
272
|
-
assert.equal(driver.lifecycle, lifecycle);
|
|
273
|
-
assert.equal(driver.signedUrl, signedUrl);
|
|
274
|
-
});
|
|
275
|
-
test("driver name defaults to s3 and is configurable", () => {
|
|
276
|
-
const { client } = makeFakeClient();
|
|
277
|
-
assert.equal(createS3StyleDriver(client).name, "s3");
|
|
278
|
-
assert.equal(createS3StyleDriver(client, { name: "r2" }).name, "r2");
|
|
279
|
-
});
|
|
280
|
-
test("S3StyleDriver class is exported and constructible", async () => {
|
|
281
|
-
const { client } = makeFakeClient();
|
|
282
|
-
const driver = new S3StyleDriver(client, { clock: fixedClock, name: "minio" });
|
|
283
|
-
assert.equal(driver.name, "minio");
|
|
284
|
-
const meta = await driver.put("x", bytes("y"), {});
|
|
285
|
-
assert.equal(meta.key, "x");
|
|
286
|
-
});
|
|
287
|
-
// ── shared contract-conformance suite ───────────────────────────────────────────
|
|
288
|
-
registerStorageDriverContractTests("s3-base", () => createS3StyleDriver(makeFakeClient().client, { clock: fixedClock }), test);
|
|
289
|
-
//# sourceMappingURL=s3-base.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"s3-base.test.js","sourceRoot":"","sources":["../../src/tests/s3-base.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"s3-integration.test.d.ts","sourceRoot":"","sources":["../../src/tests/s3-integration.test.ts"],"names":[],"mappings":""}
|