@indigoai-us/hq-cloud 5.45.0 → 5.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/sync-runner.d.ts +12 -0
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js +78 -12
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/bin/sync-runner.test.js +27 -1
- package/dist/bin/sync-runner.test.js.map +1 -1
- package/dist/cli/share.d.ts.map +1 -1
- package/dist/cli/share.js +17 -2
- package/dist/cli/share.js.map +1 -1
- package/dist/cli/share.test.js +2 -0
- package/dist/cli/share.test.js.map +1 -1
- package/dist/cli/sync-scope.test.js +1 -0
- package/dist/cli/sync-scope.test.js.map +1 -1
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +11 -1
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/sync.test.js +1 -0
- package/dist/cli/sync.test.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/object-io.d.ts +218 -0
- package/dist/object-io.d.ts.map +1 -0
- package/dist/object-io.js +588 -0
- package/dist/object-io.js.map +1 -0
- package/dist/object-io.test.d.ts +11 -0
- package/dist/object-io.test.d.ts.map +1 -0
- package/dist/object-io.test.js +568 -0
- package/dist/object-io.test.js.map +1 -0
- package/dist/s3.d.ts +37 -0
- package/dist/s3.d.ts.map +1 -1
- package/dist/s3.js +207 -198
- package/dist/s3.js.map +1 -1
- package/dist/skill-telemetry.d.ts +107 -0
- package/dist/skill-telemetry.d.ts.map +1 -0
- package/dist/skill-telemetry.js +395 -0
- package/dist/skill-telemetry.js.map +1 -0
- package/dist/skill-telemetry.test.d.ts +2 -0
- package/dist/skill-telemetry.test.d.ts.map +1 -0
- package/dist/skill-telemetry.test.js +219 -0
- package/dist/skill-telemetry.test.js.map +1 -0
- package/dist/vault-client.d.ts +91 -0
- package/dist/vault-client.d.ts.map +1 -1
- package/dist/vault-client.js +45 -0
- package/dist/vault-client.js.map +1 -1
- package/package.json +1 -1
- package/scripts/presign-transport-e2e.mjs +203 -0
- package/scripts/vault-rebaseline.sh +275 -0
- package/scripts/vault-rescue.sh +291 -0
- package/src/bin/sync-runner.test.ts +41 -0
- package/src/bin/sync-runner.ts +91 -13
- package/src/cli/share.test.ts +2 -0
- package/src/cli/share.ts +29 -2
- package/src/cli/sync-scope.test.ts +1 -0
- package/src/cli/sync.test.ts +1 -0
- package/src/cli/sync.ts +22 -1
- package/src/index.ts +16 -0
- package/src/object-io.test.ts +663 -0
- package/src/object-io.ts +782 -0
- package/src/s3.ts +259 -233
- package/src/skill-telemetry.test.ts +279 -0
- package/src/skill-telemetry.ts +499 -0
- package/src/vault-client.ts +135 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the ObjectIO transport seam.
|
|
3
|
+
*
|
|
4
|
+
* Focus is the PresignObjectIO path (the new transport): it talks to a
|
|
5
|
+
* VaultClient-shaped stub for URL minting and a mocked global `fetch` for the
|
|
6
|
+
* byte movement. The S3SdkObjectIO path is already covered transitively by
|
|
7
|
+
* s3.test.ts (which exercises s3.ts through the default factory), plus a couple
|
|
8
|
+
* of factory-selection tests here.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
11
|
+
import { PresignObjectIO, S3SdkObjectIO, setObjectIOFactory, resolveObjectIO, presignObjectIOFactory, } from "./object-io.js";
|
|
12
|
+
const COMPANY = "cmp_test";
|
|
13
|
+
function ctx() {
|
|
14
|
+
return {
|
|
15
|
+
uid: COMPANY,
|
|
16
|
+
slug: "test",
|
|
17
|
+
bucketName: "bucket-test",
|
|
18
|
+
region: "us-east-1",
|
|
19
|
+
credentials: {
|
|
20
|
+
accessKeyId: "AKIA",
|
|
21
|
+
secretAccessKey: "secret",
|
|
22
|
+
sessionToken: "token",
|
|
23
|
+
},
|
|
24
|
+
expiresAt: "2099-01-01T00:00:00.000Z",
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Minimal VaultClient stub. Each method returns whatever the per-test config
|
|
29
|
+
* sets; presign records the inputs it was called with so tests can assert the
|
|
30
|
+
* op/metadata/key shape the seam sends.
|
|
31
|
+
*/
|
|
32
|
+
function makeVault() {
|
|
33
|
+
const presignCalls = [];
|
|
34
|
+
let nextPresign = [];
|
|
35
|
+
let nextList = { objects: [], cursor: null, truncated: false };
|
|
36
|
+
const vault = {
|
|
37
|
+
presign: async (input) => {
|
|
38
|
+
presignCalls.push({
|
|
39
|
+
companyUid: input.companyUid,
|
|
40
|
+
op: input.op,
|
|
41
|
+
keys: input.keys,
|
|
42
|
+
});
|
|
43
|
+
return { results: nextPresign, expiresAt: "2099-01-01T00:00:00.000Z" };
|
|
44
|
+
},
|
|
45
|
+
listFiles: async () => nextList,
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
vault,
|
|
49
|
+
presignCalls,
|
|
50
|
+
setPresign: (rows) => {
|
|
51
|
+
nextPresign = rows;
|
|
52
|
+
},
|
|
53
|
+
setList: (v) => {
|
|
54
|
+
nextList = v;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
describe("factory selection", () => {
|
|
59
|
+
afterEach(() => setObjectIOFactory(null));
|
|
60
|
+
it("defaults to the S3 SDK transport", () => {
|
|
61
|
+
const io = resolveObjectIO(ctx());
|
|
62
|
+
expect(io).toBeInstanceOf(S3SdkObjectIO);
|
|
63
|
+
});
|
|
64
|
+
it("setObjectIOFactory(null) resets to the default", () => {
|
|
65
|
+
const { vault } = makeVault();
|
|
66
|
+
setObjectIOFactory(presignObjectIOFactory(vault));
|
|
67
|
+
expect(resolveObjectIO(ctx())).toBeInstanceOf(PresignObjectIO);
|
|
68
|
+
setObjectIOFactory(null);
|
|
69
|
+
expect(resolveObjectIO(ctx())).toBeInstanceOf(S3SdkObjectIO);
|
|
70
|
+
});
|
|
71
|
+
it("presign factory derives companyUid from ctx.uid", async () => {
|
|
72
|
+
const { vault, presignCalls, setPresign } = makeVault();
|
|
73
|
+
setPresign([{ key: "k", op: "get", url: "https://x/get" }]);
|
|
74
|
+
vi.stubGlobal("fetch", vi.fn(async () => new Response(Buffer.from("body"), { status: 200 })));
|
|
75
|
+
const io = presignObjectIOFactory(vault)(ctx());
|
|
76
|
+
await io.getObject("k");
|
|
77
|
+
expect(presignCalls[0].companyUid).toBe(COMPANY);
|
|
78
|
+
vi.unstubAllGlobals();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("PresignObjectIO.putObject", () => {
|
|
82
|
+
let fetchMock;
|
|
83
|
+
beforeEach(() => {
|
|
84
|
+
fetchMock = vi.fn();
|
|
85
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
86
|
+
});
|
|
87
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
88
|
+
it("sends op:put with metadata and replays the signed headers verbatim", async () => {
|
|
89
|
+
const { vault, presignCalls, setPresign } = makeVault();
|
|
90
|
+
setPresign([
|
|
91
|
+
{
|
|
92
|
+
key: "shared/a.md",
|
|
93
|
+
op: "put",
|
|
94
|
+
url: "https://s3/put-url",
|
|
95
|
+
headers: {
|
|
96
|
+
"content-type": "text/markdown",
|
|
97
|
+
"x-amz-server-side-encryption": "aws:kms",
|
|
98
|
+
"x-amz-meta-created-by": "me@getindigo.ai",
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
]);
|
|
102
|
+
fetchMock.mockResolvedValue(new Response(null, { status: 200, headers: { etag: '"abc123"' } }));
|
|
103
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
104
|
+
const res = await io.putObject({
|
|
105
|
+
key: "shared/a.md",
|
|
106
|
+
body: Buffer.from("hello"),
|
|
107
|
+
contentType: "text/markdown",
|
|
108
|
+
metadata: { "created-by": "me@getindigo.ai" },
|
|
109
|
+
});
|
|
110
|
+
// Presign request carried op + per-key metadata.
|
|
111
|
+
expect(presignCalls[0].op).toBe("put");
|
|
112
|
+
expect(presignCalls[0].keys[0]).toMatchObject({
|
|
113
|
+
key: "shared/a.md",
|
|
114
|
+
op: "put",
|
|
115
|
+
contentType: "text/markdown",
|
|
116
|
+
metadata: { "created-by": "me@getindigo.ai" },
|
|
117
|
+
});
|
|
118
|
+
// PUT replays the exact signed headers.
|
|
119
|
+
const [url, init] = fetchMock.mock.calls[0];
|
|
120
|
+
expect(url).toBe("https://s3/put-url");
|
|
121
|
+
expect(init.method).toBe("PUT");
|
|
122
|
+
expect(init.headers).toEqual({
|
|
123
|
+
"content-type": "text/markdown",
|
|
124
|
+
"x-amz-server-side-encryption": "aws:kms",
|
|
125
|
+
"x-amz-meta-created-by": "me@getindigo.ai",
|
|
126
|
+
});
|
|
127
|
+
// ETag returned with quotes stripped.
|
|
128
|
+
expect(res.etag).toBe("abc123");
|
|
129
|
+
});
|
|
130
|
+
it("throws on a per-key denial (error row)", async () => {
|
|
131
|
+
const { vault, setPresign } = makeVault();
|
|
132
|
+
setPresign([
|
|
133
|
+
{ key: "secret/x", op: "put", error: "forbidden", code: "ACL_DENY" },
|
|
134
|
+
]);
|
|
135
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
136
|
+
await expect(io.putObject({
|
|
137
|
+
key: "secret/x",
|
|
138
|
+
body: Buffer.from("z"),
|
|
139
|
+
contentType: "text/plain",
|
|
140
|
+
})).rejects.toThrow(/denied for secret\/x.*forbidden.*ACL_DENY/);
|
|
141
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
142
|
+
});
|
|
143
|
+
it("throws when the PUT itself fails", async () => {
|
|
144
|
+
const { vault, setPresign } = makeVault();
|
|
145
|
+
setPresign([{ key: "k", op: "put", url: "https://s3/put" }]);
|
|
146
|
+
fetchMock.mockResolvedValue(new Response("AccessDenied", { status: 403 }));
|
|
147
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
148
|
+
await expect(io.putObject({ key: "k", body: Buffer.from("z"), contentType: "x" })).rejects.toThrow(/presigned PUT failed for k: 403/);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
describe("PresignObjectIO.getObject", () => {
|
|
152
|
+
let fetchMock;
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
fetchMock = vi.fn();
|
|
155
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
156
|
+
});
|
|
157
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
158
|
+
it("returns body bytes + x-amz-meta-* metadata", async () => {
|
|
159
|
+
const { vault, presignCalls, setPresign } = makeVault();
|
|
160
|
+
setPresign([{ key: "shared/a.md", op: "get", url: "https://s3/get" }]);
|
|
161
|
+
fetchMock.mockResolvedValue(new Response(Buffer.from("file-bytes"), {
|
|
162
|
+
status: 200,
|
|
163
|
+
headers: {
|
|
164
|
+
"x-amz-meta-created-by": "me@getindigo.ai",
|
|
165
|
+
"x-amz-meta-hq-mode": "640",
|
|
166
|
+
"content-type": "text/markdown",
|
|
167
|
+
},
|
|
168
|
+
}));
|
|
169
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
170
|
+
const res = await io.getObject("shared/a.md");
|
|
171
|
+
expect(presignCalls[0].op).toBe("get");
|
|
172
|
+
expect(res.body.toString("utf-8")).toBe("file-bytes");
|
|
173
|
+
expect(res.metadata).toEqual({
|
|
174
|
+
"created-by": "me@getindigo.ai",
|
|
175
|
+
"hq-mode": "640",
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
it("throws a NotFound-named error on 404 (so s3.ts catch sites match)", async () => {
|
|
179
|
+
const { vault, setPresign } = makeVault();
|
|
180
|
+
setPresign([{ key: "gone", op: "get", url: "https://s3/get" }]);
|
|
181
|
+
fetchMock.mockResolvedValue(new Response("", { status: 404 }));
|
|
182
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
183
|
+
await expect(io.getObject("gone")).rejects.toMatchObject({
|
|
184
|
+
name: "NotFound",
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe("PresignObjectIO.listObjects", () => {
|
|
189
|
+
it("maps listFiles rows into the RemoteObject shape (etag, Date)", async () => {
|
|
190
|
+
const { vault, setList } = makeVault();
|
|
191
|
+
setList({
|
|
192
|
+
objects: [
|
|
193
|
+
{
|
|
194
|
+
key: "shared/a.md",
|
|
195
|
+
size: 12,
|
|
196
|
+
lastModified: "2026-01-01T00:00:00.000Z",
|
|
197
|
+
etag: "deadbeef",
|
|
198
|
+
permission: "read",
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
key: "shared/b.md",
|
|
202
|
+
size: 0,
|
|
203
|
+
lastModified: null,
|
|
204
|
+
etag: null,
|
|
205
|
+
permission: "write",
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
cursor: "next-token",
|
|
209
|
+
truncated: true,
|
|
210
|
+
});
|
|
211
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
212
|
+
const res = await io.listObjects({ prefix: "shared/" });
|
|
213
|
+
expect(res.nextContinuationToken).toBe("next-token");
|
|
214
|
+
expect(res.objects[0]).toEqual({
|
|
215
|
+
key: "shared/a.md",
|
|
216
|
+
size: 12,
|
|
217
|
+
lastModified: new Date("2026-01-01T00:00:00.000Z"),
|
|
218
|
+
etag: "deadbeef",
|
|
219
|
+
});
|
|
220
|
+
// null etag → "" ; null lastModified → a Date (not crash).
|
|
221
|
+
expect(res.objects[1].etag).toBe("");
|
|
222
|
+
expect(res.objects[1].lastModified).toBeInstanceOf(Date);
|
|
223
|
+
});
|
|
224
|
+
it("exhausted listing yields undefined nextContinuationToken", async () => {
|
|
225
|
+
const { vault, setList } = makeVault();
|
|
226
|
+
setList({ objects: [], cursor: null, truncated: false });
|
|
227
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
228
|
+
const res = await io.listObjects({});
|
|
229
|
+
expect(res.nextContinuationToken).toBeUndefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe("PresignObjectIO.deleteObject", () => {
|
|
233
|
+
let fetchMock;
|
|
234
|
+
beforeEach(() => {
|
|
235
|
+
fetchMock = vi.fn();
|
|
236
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
237
|
+
});
|
|
238
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
239
|
+
it("sends op:delete and DELETEs the signed URL", async () => {
|
|
240
|
+
const { vault, presignCalls, setPresign } = makeVault();
|
|
241
|
+
setPresign([{ key: "shared/a.md", op: "delete", url: "https://s3/del" }]);
|
|
242
|
+
fetchMock.mockResolvedValue(new Response(null, { status: 204 }));
|
|
243
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
244
|
+
await io.deleteObject("shared/a.md");
|
|
245
|
+
expect(presignCalls[0].op).toBe("delete");
|
|
246
|
+
expect(fetchMock.mock.calls[0][1].method).toBe("DELETE");
|
|
247
|
+
});
|
|
248
|
+
it("treats a 404 DELETE as success (idempotent)", async () => {
|
|
249
|
+
const { vault, setPresign } = makeVault();
|
|
250
|
+
setPresign([{ key: "gone", op: "delete", url: "https://s3/del" }]);
|
|
251
|
+
fetchMock.mockResolvedValue(new Response("", { status: 404 }));
|
|
252
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
253
|
+
await expect(io.deleteObject("gone")).resolves.toBeUndefined();
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
describe("PresignObjectIO.headObject", () => {
|
|
257
|
+
let fetchMock;
|
|
258
|
+
beforeEach(() => {
|
|
259
|
+
fetchMock = vi.fn();
|
|
260
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
261
|
+
});
|
|
262
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
263
|
+
it("reads headers (etag/size/lastModified/metadata) via a presigned GET", async () => {
|
|
264
|
+
const { vault, setPresign } = makeVault();
|
|
265
|
+
setPresign([{ key: "shared/a.md", op: "get", url: "https://s3/get" }]);
|
|
266
|
+
fetchMock.mockResolvedValue(new Response(Buffer.from("ignored-body"), {
|
|
267
|
+
status: 200,
|
|
268
|
+
headers: {
|
|
269
|
+
etag: '"feedface"',
|
|
270
|
+
"content-length": "123",
|
|
271
|
+
"last-modified": "Wed, 01 Jan 2026 00:00:00 GMT",
|
|
272
|
+
"x-amz-meta-created-at": "2026-01-01T00:00:00.000Z",
|
|
273
|
+
},
|
|
274
|
+
}));
|
|
275
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
276
|
+
const head = await io.headObject("shared/a.md");
|
|
277
|
+
expect(head).not.toBeNull();
|
|
278
|
+
expect(head.etag).toBe("feedface");
|
|
279
|
+
expect(head.size).toBe(123);
|
|
280
|
+
expect(head.metadata).toEqual({
|
|
281
|
+
"created-at": "2026-01-01T00:00:00.000Z",
|
|
282
|
+
});
|
|
283
|
+
expect(head.lastModified.getTime()).toBe(Date.parse("Wed, 01 Jan 2026 00:00:00 GMT"));
|
|
284
|
+
});
|
|
285
|
+
it("returns null on 404", async () => {
|
|
286
|
+
const { vault, setPresign } = makeVault();
|
|
287
|
+
setPresign([{ key: "gone", op: "get", url: "https://s3/get" }]);
|
|
288
|
+
fetchMock.mockResolvedValue(new Response("", { status: 404 }));
|
|
289
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
290
|
+
expect(await io.headObject("gone")).toBeNull();
|
|
291
|
+
});
|
|
292
|
+
it("returns null when presign denies the key (no usable head)", async () => {
|
|
293
|
+
const { vault, setPresign } = makeVault();
|
|
294
|
+
setPresign([{ key: "secret/x", op: "get", error: "forbidden" }]);
|
|
295
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
296
|
+
expect(await io.headObject("secret/x")).toBeNull();
|
|
297
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
/**
|
|
301
|
+
* Echo vault: presign returns one signed row per requested key (url derived
|
|
302
|
+
* from op+key) and records call count + total keys, so prime/cache tests can
|
|
303
|
+
* assert "N files → ceil(N/100) presign calls, then zero".
|
|
304
|
+
*/
|
|
305
|
+
function makeEchoVault() {
|
|
306
|
+
let calls = 0;
|
|
307
|
+
let totalKeys = 0;
|
|
308
|
+
const vault = {
|
|
309
|
+
presign: async (input) => {
|
|
310
|
+
calls++;
|
|
311
|
+
totalKeys += input.keys.length;
|
|
312
|
+
return {
|
|
313
|
+
results: input.keys.map((k) => ({
|
|
314
|
+
key: k.key,
|
|
315
|
+
op: k.op ?? input.op ?? "get",
|
|
316
|
+
url: `https://signed/${k.op ?? input.op}/${encodeURIComponent(k.key)}`,
|
|
317
|
+
...(k.op === "put" || input.op === "put"
|
|
318
|
+
? { headers: { "content-type": "text/plain" } }
|
|
319
|
+
: {}),
|
|
320
|
+
expiresIn: input.expiresIn ?? 900,
|
|
321
|
+
})),
|
|
322
|
+
expiresAt: "2099-01-01T00:00:00.000Z",
|
|
323
|
+
};
|
|
324
|
+
},
|
|
325
|
+
listFiles: async () => ({ objects: [], cursor: null, truncated: false }),
|
|
326
|
+
};
|
|
327
|
+
return {
|
|
328
|
+
vault,
|
|
329
|
+
calls: () => calls,
|
|
330
|
+
totalKeys: () => totalKeys,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
describe("PresignObjectIO.prime — batch URL cache", () => {
|
|
334
|
+
let fetchMock;
|
|
335
|
+
beforeEach(() => {
|
|
336
|
+
fetchMock = vi.fn(async () => new Response(Buffer.from("x"), { status: 200 }));
|
|
337
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
338
|
+
});
|
|
339
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
340
|
+
it("chunks at 1000 keys per presign call (the server batch cap)", async () => {
|
|
341
|
+
const { vault, calls, totalKeys } = makeEchoVault();
|
|
342
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
343
|
+
const keys = Array.from({ length: 2500 }, (_, i) => ({ key: `k${i}` }));
|
|
344
|
+
await io.prime("get", keys);
|
|
345
|
+
expect(calls()).toBe(3); // 1000 + 1000 + 500
|
|
346
|
+
expect(totalKeys()).toBe(2500);
|
|
347
|
+
});
|
|
348
|
+
it("primed getObject reuses the cache — zero extra presign calls", async () => {
|
|
349
|
+
const { vault, calls } = makeEchoVault();
|
|
350
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
351
|
+
const keys = Array.from({ length: 5 }, (_, i) => ({ key: `f${i}` }));
|
|
352
|
+
await io.prime("get", keys);
|
|
353
|
+
const afterPrime = calls(); // 1 chunk
|
|
354
|
+
for (const k of keys)
|
|
355
|
+
await io.getObject(k.key);
|
|
356
|
+
expect(calls()).toBe(afterPrime); // no new presign calls
|
|
357
|
+
expect(fetchMock).toHaveBeenCalledTimes(5); // but the bytes were fetched
|
|
358
|
+
// The fetched URL is the primed (cached) one.
|
|
359
|
+
expect(fetchMock.mock.calls[0][0]).toBe("https://signed/get/f0");
|
|
360
|
+
});
|
|
361
|
+
it("primed GET cache also serves headObject (HEAD reuses GET URLs)", async () => {
|
|
362
|
+
const { vault, calls } = makeEchoVault();
|
|
363
|
+
fetchMock.mockResolvedValue(new Response(Buffer.from(""), {
|
|
364
|
+
status: 200,
|
|
365
|
+
headers: { etag: '"e"', "content-length": "0" },
|
|
366
|
+
}));
|
|
367
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
368
|
+
await io.prime("get", [{ key: "doc.md" }]);
|
|
369
|
+
const afterPrime = calls();
|
|
370
|
+
const head = await io.headObject("doc.md");
|
|
371
|
+
expect(head).not.toBeNull();
|
|
372
|
+
expect(calls()).toBe(afterPrime); // head used the cached GET url, no presign
|
|
373
|
+
});
|
|
374
|
+
it("a key NOT primed falls back to a single presign", async () => {
|
|
375
|
+
const { vault, calls } = makeEchoVault();
|
|
376
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
377
|
+
await io.prime("get", [{ key: "primed" }]);
|
|
378
|
+
const afterPrime = calls();
|
|
379
|
+
await io.getObject("not-primed");
|
|
380
|
+
expect(calls()).toBe(afterPrime + 1);
|
|
381
|
+
});
|
|
382
|
+
it("empty prime is a no-op (no presign call)", async () => {
|
|
383
|
+
const { vault, calls } = makeEchoVault();
|
|
384
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
385
|
+
await io.prime("get", []);
|
|
386
|
+
expect(calls()).toBe(0);
|
|
387
|
+
});
|
|
388
|
+
it("a chunk that throws doesn't fail prime; those keys fall back per-file", async () => {
|
|
389
|
+
let calls = 0;
|
|
390
|
+
const vault = {
|
|
391
|
+
presign: async (input) => {
|
|
392
|
+
calls++;
|
|
393
|
+
if (calls === 1)
|
|
394
|
+
throw new Error("transient");
|
|
395
|
+
return {
|
|
396
|
+
results: input.keys.map((k) => ({
|
|
397
|
+
key: k.key,
|
|
398
|
+
op: "get",
|
|
399
|
+
url: `https://signed/get/${k.key}`,
|
|
400
|
+
expiresIn: 900,
|
|
401
|
+
})),
|
|
402
|
+
expiresAt: "2099-01-01T00:00:00.000Z",
|
|
403
|
+
};
|
|
404
|
+
},
|
|
405
|
+
listFiles: async () => ({ objects: [], cursor: null, truncated: false }),
|
|
406
|
+
};
|
|
407
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
408
|
+
// Single chunk that throws — prime resolves anyway, key stays uncached.
|
|
409
|
+
await expect(io.prime("get", [{ key: "k" }])).resolves.toBeUndefined();
|
|
410
|
+
// getObject then single-presigns (call #2 succeeds).
|
|
411
|
+
await io.getObject("k");
|
|
412
|
+
expect(calls).toBe(2);
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
describe("presignObjectIOFactory — memoization", () => {
|
|
416
|
+
afterEach(() => setObjectIOFactory(null));
|
|
417
|
+
it("returns the SAME instance per companyUid so prime + transfer share a cache", () => {
|
|
418
|
+
const { vault } = makeEchoVault();
|
|
419
|
+
const factory = presignObjectIOFactory(vault);
|
|
420
|
+
const a1 = factory(ctx());
|
|
421
|
+
const a2 = factory(ctx());
|
|
422
|
+
expect(a1).toBe(a2); // same company → same instance
|
|
423
|
+
const other = factory({ ...ctx(), uid: "cmp_other" });
|
|
424
|
+
expect(other).not.toBe(a1); // different company → different instance
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
describe("PresignObjectIO — transient-failure retry (SDK parity)", () => {
|
|
428
|
+
afterEach(() => {
|
|
429
|
+
vi.useRealTimers();
|
|
430
|
+
vi.unstubAllGlobals();
|
|
431
|
+
});
|
|
432
|
+
it("retries a transient 503 then succeeds", async () => {
|
|
433
|
+
vi.useFakeTimers();
|
|
434
|
+
const { vault, setPresign } = makeVault();
|
|
435
|
+
setPresign([{ key: "k", op: "get", url: "https://s3/get" }]);
|
|
436
|
+
const fetchMock = vi
|
|
437
|
+
.fn()
|
|
438
|
+
.mockResolvedValueOnce(new Response("SlowDown", { status: 503 }))
|
|
439
|
+
.mockResolvedValueOnce(new Response(Buffer.from("ok"), { status: 200 }));
|
|
440
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
441
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
442
|
+
const pr = io.getObject("k");
|
|
443
|
+
await vi.runAllTimersAsync();
|
|
444
|
+
const res = await pr;
|
|
445
|
+
expect(res.body.toString("utf-8")).toBe("ok");
|
|
446
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
447
|
+
});
|
|
448
|
+
it("retries a network error (fetch throws) then succeeds", async () => {
|
|
449
|
+
vi.useFakeTimers();
|
|
450
|
+
const { vault, setPresign } = makeVault();
|
|
451
|
+
setPresign([{ key: "k", op: "get", url: "https://s3/get" }]);
|
|
452
|
+
const fetchMock = vi
|
|
453
|
+
.fn()
|
|
454
|
+
.mockRejectedValueOnce(new Error("socket hang up"))
|
|
455
|
+
.mockResolvedValueOnce(new Response(Buffer.from("ok"), { status: 200 }));
|
|
456
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
457
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
458
|
+
const pr = io.getObject("k");
|
|
459
|
+
await vi.runAllTimersAsync();
|
|
460
|
+
const res = await pr;
|
|
461
|
+
expect(res.body.toString("utf-8")).toBe("ok");
|
|
462
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
463
|
+
});
|
|
464
|
+
it("throws after exhausting retries on persistent 503 (initial + 3 retries = 4)", async () => {
|
|
465
|
+
vi.useFakeTimers();
|
|
466
|
+
const { vault, setPresign } = makeVault();
|
|
467
|
+
setPresign([{ key: "k", op: "get", url: "https://s3/get" }]);
|
|
468
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response("err", { status: 503 }));
|
|
469
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
470
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
471
|
+
const pr = io.getObject("k").catch((e) => e);
|
|
472
|
+
await vi.runAllTimersAsync();
|
|
473
|
+
const err = await pr;
|
|
474
|
+
expect(String(err)).toMatch(/503/);
|
|
475
|
+
expect(fetchMock).toHaveBeenCalledTimes(4);
|
|
476
|
+
});
|
|
477
|
+
it("does NOT retry a definitive 404", async () => {
|
|
478
|
+
const { vault, setPresign } = makeVault();
|
|
479
|
+
setPresign([{ key: "gone", op: "get", url: "https://s3/get" }]);
|
|
480
|
+
const fetchMock = vi.fn().mockResolvedValue(new Response("", { status: 404 }));
|
|
481
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
482
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
483
|
+
await expect(io.getObject("gone")).rejects.toMatchObject({ name: "NotFound" });
|
|
484
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
import { VaultClientError } from "./vault-client.js";
|
|
488
|
+
describe("PresignObjectIO — 429 circuit breaker", () => {
|
|
489
|
+
afterEach(() => vi.unstubAllGlobals());
|
|
490
|
+
it("trips on a 429: uncached keys fail fast (no further presign), primed keys still work", async () => {
|
|
491
|
+
let presignCalls = 0;
|
|
492
|
+
const vault = {
|
|
493
|
+
presign: async (input) => {
|
|
494
|
+
presignCalls++;
|
|
495
|
+
if (input.keys.some((k) => k.key === "primed")) {
|
|
496
|
+
return {
|
|
497
|
+
results: input.keys.map((k) => ({
|
|
498
|
+
key: k.key,
|
|
499
|
+
op: k.op ?? "get",
|
|
500
|
+
url: `https://s/${k.key}`,
|
|
501
|
+
expiresIn: 900,
|
|
502
|
+
})),
|
|
503
|
+
expiresAt: "2099-01-01T00:00:00.000Z",
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
throw new VaultClientError("Rate limit exceeded: 100 requests per hour", 429);
|
|
507
|
+
},
|
|
508
|
+
listFiles: async () => ({ objects: [], cursor: null, truncated: false }),
|
|
509
|
+
};
|
|
510
|
+
vi.stubGlobal("fetch", vi.fn(async () => new Response(Buffer.from("x"), { status: 200 })));
|
|
511
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
512
|
+
await io.prime("get", [{ key: "primed" }]); // caches "primed"
|
|
513
|
+
await expect(io.getObject("uncached1")).rejects.toMatchObject({
|
|
514
|
+
name: "RateLimited",
|
|
515
|
+
});
|
|
516
|
+
const afterTrip = presignCalls;
|
|
517
|
+
// Second uncached key fails fast — NO new presign call.
|
|
518
|
+
await expect(io.getObject("uncached2")).rejects.toMatchObject({
|
|
519
|
+
name: "RateLimited",
|
|
520
|
+
});
|
|
521
|
+
expect(presignCalls).toBe(afterTrip);
|
|
522
|
+
// The primed key still resolves from cache (no presign needed).
|
|
523
|
+
const r = await io.getObject("primed");
|
|
524
|
+
expect(r.body.toString("utf-8")).toBe("x");
|
|
525
|
+
});
|
|
526
|
+
it("prime stops minting once a chunk 429s (breaker trips, remaining chunks skipped)", async () => {
|
|
527
|
+
let calls = 0;
|
|
528
|
+
const vault = {
|
|
529
|
+
presign: async () => {
|
|
530
|
+
calls++;
|
|
531
|
+
throw new VaultClientError("rate", 429);
|
|
532
|
+
},
|
|
533
|
+
listFiles: async () => ({ objects: [], cursor: null, truncated: false }),
|
|
534
|
+
};
|
|
535
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
536
|
+
// 10 chunks (10k keys @ 1000); concurrency is 4, so at most the first
|
|
537
|
+
// concurrent batch fires before the breaker trips — far fewer than 10.
|
|
538
|
+
await io.prime("get", Array.from({ length: 10_000 }, (_, i) => ({ key: `k${i}` })));
|
|
539
|
+
expect(calls).toBeLessThanOrEqual(4);
|
|
540
|
+
expect(calls).toBeLessThan(10);
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
describe("PresignObjectIO.hasPrimedPut", () => {
|
|
544
|
+
it("reflects a put prime", async () => {
|
|
545
|
+
const { vault } = makeEchoVault();
|
|
546
|
+
const io = new PresignObjectIO(vault, COMPANY);
|
|
547
|
+
expect(io.hasPrimedPut("k")).toBe(false);
|
|
548
|
+
await io.prime("put", [
|
|
549
|
+
{ key: "k", op: "put", contentType: "text/plain", metadata: { "hq-mode": "644" } },
|
|
550
|
+
]);
|
|
551
|
+
expect(io.hasPrimedPut("k")).toBe(true);
|
|
552
|
+
// A different, unprimed key stays false.
|
|
553
|
+
expect(io.hasPrimedPut("other")).toBe(false);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
describe("presignObjectIOFactory — personal vaults route to S3 SDK", () => {
|
|
557
|
+
it("routes a person entity (prs_*) to S3SdkObjectIO, a company (cmp_*) to presign", () => {
|
|
558
|
+
const { vault } = makeEchoVault();
|
|
559
|
+
const factory = presignObjectIOFactory(vault);
|
|
560
|
+
const company = factory({ ...ctx(), uid: "cmp_real" });
|
|
561
|
+
const personal = factory({ ...ctx(), uid: "prs_real" });
|
|
562
|
+
expect(company).toBeInstanceOf(PresignObjectIO);
|
|
563
|
+
// Personal vaults use the membership-less vend-self model; the
|
|
564
|
+
// membership-gated presign endpoints 403 for them, so they stay on STS.
|
|
565
|
+
expect(personal).toBeInstanceOf(S3SdkObjectIO);
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
//# sourceMappingURL=object-io.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-io.test.js","sourceRoot":"","sources":["../src/object-io.test.ts"],"names":[],"mappings":"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"}
|
package/dist/s3.d.ts
CHANGED
|
@@ -168,6 +168,43 @@ export declare const FILE_BTIME_META_KEY = "hq-btime";
|
|
|
168
168
|
* duplicating the prefix string.
|
|
169
169
|
*/
|
|
170
170
|
export declare function encodeSymlinkBody(target: string): Buffer;
|
|
171
|
+
/**
|
|
172
|
+
* Batch pre-mint transport URLs for `keys` under `op` so the subsequent
|
|
173
|
+
* per-file transfer calls (downloadFile/headRemoteFile/…) reuse them instead
|
|
174
|
+
* of presigning one key at a time. On the presigned-URL transport this turns
|
|
175
|
+
* an N-file leg from N presign requests into ceil(N/100) — the difference
|
|
176
|
+
* between completing a bulk pull and 429ing past the 100-req/hr limit. No-op
|
|
177
|
+
* on the S3 SDK transport (which has no presign step) and harmless if called
|
|
178
|
+
* with an empty list. Best-effort: a prime failure never propagates — the
|
|
179
|
+
* per-file path falls back to a single presign.
|
|
180
|
+
*
|
|
181
|
+
* Call it once, right before a transfer loop, with the full key set the loop
|
|
182
|
+
* will touch. The presigned transport memoizes one IO instance per company for
|
|
183
|
+
* the run, so the warmed cache is the same one the loop drains.
|
|
184
|
+
*/
|
|
185
|
+
export declare function primeObjectTransport(ctx: EntityContext, op: "get" | "put" | "delete", keys: string[]): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* One upload's identity for {@link primeUploads}: the vault key, the local
|
|
188
|
+
* path (to lstat for mode/mtime), whether it's a symlink, and the author.
|
|
189
|
+
*/
|
|
190
|
+
export interface UploadPrimeItem {
|
|
191
|
+
key: string;
|
|
192
|
+
localPath: string;
|
|
193
|
+
isSymlink: boolean;
|
|
194
|
+
author?: UploadAuthor;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Batch pre-mint PUT URLs (+ the created-at HEADs they depend on) for a set of
|
|
198
|
+
* uploads, signing the SAME metadata uploadFile/uploadSymlink would compute so
|
|
199
|
+
* the transfer loop can replay the cached headers. Turns an N-file push from
|
|
200
|
+
* ~N presign calls (1 per PUT, sometimes 2-3 with HEADs) into ceil(N/1000) GET
|
|
201
|
+
* + ceil(N/1000) PUT — the difference between completing a bulk push and 429ing
|
|
202
|
+
* past the 100/hr limit. No-op on the S3 SDK transport; best-effort.
|
|
203
|
+
*
|
|
204
|
+
* The per-item created-at HEADs run over the GET cache primed first, so they
|
|
205
|
+
* cost S3 round-trips but NO extra presign calls (not counted against 100/hr).
|
|
206
|
+
*/
|
|
207
|
+
export declare function primeUploads(ctx: EntityContext, items: UploadPrimeItem[]): Promise<void>;
|
|
171
208
|
export declare function uploadFile(ctx: EntityContext, localPath: string, key: string, author?: UploadAuthor): Promise<{
|
|
172
209
|
etag: string;
|
|
173
210
|
}>;
|