@vercel/kv2 0.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/README.md +87 -0
- package/SKILL.md +65 -0
- package/dist/blob-format.d.ts +35 -0
- package/dist/blob-format.d.ts.map +1 -0
- package/dist/blob-format.js +91 -0
- package/dist/blob-format.js.map +1 -0
- package/dist/blob-store.d.ts +11 -0
- package/dist/blob-store.d.ts.map +1 -0
- package/dist/blob-store.js +32 -0
- package/dist/blob-store.js.map +1 -0
- package/dist/cache.d.ts +33 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +146 -0
- package/dist/cache.js.map +1 -0
- package/dist/cached-kv.d.ts +63 -0
- package/dist/cached-kv.d.ts.map +1 -0
- package/dist/cached-kv.js +891 -0
- package/dist/cached-kv.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +342 -0
- package/dist/cli.js.map +1 -0
- package/dist/create-kv.d.ts +86 -0
- package/dist/create-kv.d.ts.map +1 -0
- package/dist/create-kv.js +125 -0
- package/dist/create-kv.js.map +1 -0
- package/dist/disk-cache.d.ts.map +1 -0
- package/dist/disk-cache.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/indexed-kv.d.ts +44 -0
- package/dist/indexed-kv.d.ts.map +1 -0
- package/dist/indexed-kv.js +373 -0
- package/dist/indexed-kv.js.map +1 -0
- package/dist/manifest-log.d.ts +57 -0
- package/dist/manifest-log.d.ts.map +1 -0
- package/dist/manifest-log.js +128 -0
- package/dist/manifest-log.js.map +1 -0
- package/dist/memory-cache.d.ts +22 -0
- package/dist/memory-cache.d.ts.map +1 -0
- package/dist/memory-cache.js +90 -0
- package/dist/memory-cache.js.map +1 -0
- package/dist/proxy-cache.d.ts +40 -0
- package/dist/proxy-cache.d.ts.map +1 -0
- package/dist/proxy-cache.js +124 -0
- package/dist/proxy-cache.js.map +1 -0
- package/dist/readme.test.d.ts +9 -0
- package/dist/readme.test.d.ts.map +1 -0
- package/dist/readme.test.js +285 -0
- package/dist/readme.test.js.map +1 -0
- package/dist/schema/define-schema.d.ts +35 -0
- package/dist/schema/define-schema.d.ts.map +1 -0
- package/dist/schema/define-schema.js +70 -0
- package/dist/schema/define-schema.js.map +1 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +5 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/key-builders.d.ts +40 -0
- package/dist/schema/key-builders.d.ts.map +1 -0
- package/dist/schema/key-builders.js +124 -0
- package/dist/schema/key-builders.js.map +1 -0
- package/dist/schema/schema-kv.d.ts +48 -0
- package/dist/schema/schema-kv.d.ts.map +1 -0
- package/dist/schema/schema-kv.js +96 -0
- package/dist/schema/schema-kv.js.map +1 -0
- package/dist/schema/tree.d.ts +14 -0
- package/dist/schema/tree.d.ts.map +1 -0
- package/dist/schema/tree.js +135 -0
- package/dist/schema/tree.js.map +1 -0
- package/dist/schema/types.d.ts +135 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +2 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/testing/core-tests.d.ts +30 -0
- package/dist/testing/core-tests.d.ts.map +1 -0
- package/dist/testing/core-tests.js +383 -0
- package/dist/testing/core-tests.js.map +1 -0
- package/dist/testing/create-kv-test-setup.d.ts +21 -0
- package/dist/testing/create-kv-test-setup.d.ts.map +1 -0
- package/dist/testing/create-kv-test-setup.js +25 -0
- package/dist/testing/create-kv-test-setup.js.map +1 -0
- package/dist/testing/debug-manifest.d.ts +2 -0
- package/dist/testing/debug-manifest.d.ts.map +1 -0
- package/dist/testing/debug-manifest.js +14 -0
- package/dist/testing/debug-manifest.js.map +1 -0
- package/dist/testing/fake-blob-store.d.ts +23 -0
- package/dist/testing/fake-blob-store.d.ts.map +1 -0
- package/dist/testing/fake-blob-store.js +158 -0
- package/dist/testing/fake-blob-store.js.map +1 -0
- package/dist/testing/fake-cache.d.ts +54 -0
- package/dist/testing/fake-cache.d.ts.map +1 -0
- package/dist/testing/fake-cache.js +137 -0
- package/dist/testing/fake-cache.js.map +1 -0
- package/dist/testing/index.d.ts +34 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +101 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/manifest-test-setup.d.ts +22 -0
- package/dist/testing/manifest-test-setup.d.ts.map +1 -0
- package/dist/testing/manifest-test-setup.js +43 -0
- package/dist/testing/manifest-test-setup.js.map +1 -0
- package/dist/testing/perf-test.d.ts +13 -0
- package/dist/testing/perf-test.d.ts.map +1 -0
- package/dist/testing/perf-test.js +101 -0
- package/dist/testing/perf-test.js.map +1 -0
- package/dist/testing/run-tests.d.ts +2 -0
- package/dist/testing/run-tests.d.ts.map +1 -0
- package/dist/testing/run-tests.js +141 -0
- package/dist/testing/run-tests.js.map +1 -0
- package/dist/testing/setup.d.ts +2 -0
- package/dist/testing/setup.d.ts.map +1 -0
- package/dist/testing/setup.js +3 -0
- package/dist/testing/setup.js.map +1 -0
- package/dist/testing/test-index.d.ts +28 -0
- package/dist/testing/test-index.d.ts.map +1 -0
- package/dist/testing/test-index.js +35 -0
- package/dist/testing/test-index.js.map +1 -0
- package/dist/testing/test-setup.d.ts +32 -0
- package/dist/testing/test-setup.d.ts.map +1 -0
- package/dist/testing/test-setup.js +72 -0
- package/dist/testing/test-setup.js.map +1 -0
- package/dist/testing/upstream-kv-test-setup.d.ts +30 -0
- package/dist/testing/upstream-kv-test-setup.d.ts.map +1 -0
- package/dist/testing/upstream-kv-test-setup.js +66 -0
- package/dist/testing/upstream-kv-test-setup.js.map +1 -0
- package/dist/testing/vitest-compat.d.ts +92 -0
- package/dist/testing/vitest-compat.d.ts.map +1 -0
- package/dist/testing/vitest-compat.js +601 -0
- package/dist/testing/vitest-compat.js.map +1 -0
- package/dist/tracing.d.ts +71 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +232 -0
- package/dist/tracing.js.map +1 -0
- package/dist/typed-kv.d.ts +120 -0
- package/dist/typed-kv.d.ts.map +1 -0
- package/dist/typed-kv.js +565 -0
- package/dist/typed-kv.js.map +1 -0
- package/dist/typed-upstream-kv.d.ts +17 -0
- package/dist/typed-upstream-kv.d.ts.map +1 -0
- package/dist/typed-upstream-kv.js +38 -0
- package/dist/typed-upstream-kv.js.map +1 -0
- package/dist/types.d.ts +199 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/upstream-kv.d.ts +84 -0
- package/dist/upstream-kv.d.ts.map +1 -0
- package/dist/upstream-kv.js +375 -0
- package/dist/upstream-kv.js.map +1 -0
- package/docs/api-reference.md +222 -0
- package/docs/caching.md +60 -0
- package/docs/cli.md +123 -0
- package/docs/copy-on-write-branches.md +98 -0
- package/docs/getting-started.md +61 -0
- package/docs/indexes.md +122 -0
- package/docs/iterating-and-pagination.md +93 -0
- package/docs/metadata.md +82 -0
- package/docs/optimistic-locking.md +72 -0
- package/docs/schema-and-trees.md +222 -0
- package/docs/streaming.md +61 -0
- package/docs/testing-and-tracing.md +141 -0
- package/docs/typed-stores.md +68 -0
- package/package.json +63 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { BlobPreconditionFailedError, } from "@vercel/blob";
|
|
2
|
+
let etagCounter = 0;
|
|
3
|
+
function generateEtag() {
|
|
4
|
+
return `"fake-etag-${++etagCounter}-${Date.now()}"`;
|
|
5
|
+
}
|
|
6
|
+
async function toBuffer(body) {
|
|
7
|
+
if (typeof body === "string") {
|
|
8
|
+
return Buffer.from(body, "utf-8");
|
|
9
|
+
}
|
|
10
|
+
if (body instanceof Buffer) {
|
|
11
|
+
return body;
|
|
12
|
+
}
|
|
13
|
+
if (body instanceof Blob) {
|
|
14
|
+
const arrayBuffer = await body.arrayBuffer();
|
|
15
|
+
return Buffer.from(arrayBuffer);
|
|
16
|
+
}
|
|
17
|
+
if (body instanceof ArrayBuffer) {
|
|
18
|
+
return Buffer.from(body);
|
|
19
|
+
}
|
|
20
|
+
if (ArrayBuffer.isView(body)) {
|
|
21
|
+
return Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
|
22
|
+
}
|
|
23
|
+
if (body instanceof ReadableStream) {
|
|
24
|
+
const chunks = [];
|
|
25
|
+
const reader = body.getReader();
|
|
26
|
+
while (true) {
|
|
27
|
+
const { done, value } = await reader.read();
|
|
28
|
+
if (done)
|
|
29
|
+
break;
|
|
30
|
+
chunks.push(value);
|
|
31
|
+
}
|
|
32
|
+
return Buffer.concat(chunks);
|
|
33
|
+
}
|
|
34
|
+
throw new Error("Unsupported body type");
|
|
35
|
+
}
|
|
36
|
+
export class FakeBlobStore {
|
|
37
|
+
blobs = new Map();
|
|
38
|
+
async get(pathname, _options) {
|
|
39
|
+
const blob = this.blobs.get(pathname);
|
|
40
|
+
if (!blob) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const content = blob.content;
|
|
44
|
+
const stream = new ReadableStream({
|
|
45
|
+
start(controller) {
|
|
46
|
+
controller.enqueue(new Uint8Array(content));
|
|
47
|
+
controller.close();
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
stream,
|
|
52
|
+
blob: {
|
|
53
|
+
url: `fake://${pathname}`,
|
|
54
|
+
downloadUrl: `fake://${pathname}?download=1`,
|
|
55
|
+
pathname,
|
|
56
|
+
contentType: blob.contentType,
|
|
57
|
+
contentDisposition: `attachment; filename="${pathname.split("/").pop()}"`,
|
|
58
|
+
cacheControl: "public, max-age=31536000, immutable",
|
|
59
|
+
size: blob.size,
|
|
60
|
+
uploadedAt: blob.uploadedAt,
|
|
61
|
+
etag: blob.etag,
|
|
62
|
+
},
|
|
63
|
+
headers: new Headers({
|
|
64
|
+
"content-type": blob.contentType,
|
|
65
|
+
"content-length": String(blob.size),
|
|
66
|
+
etag: blob.etag,
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async put(pathname, body, options) {
|
|
71
|
+
const existingBlob = this.blobs.get(pathname);
|
|
72
|
+
// Check allowOverwrite option (default: true based on @vercel/blob behavior)
|
|
73
|
+
const allowOverwrite = options.allowOverwrite ?? true;
|
|
74
|
+
if (!allowOverwrite && existingBlob) {
|
|
75
|
+
throw new BlobPreconditionFailedError();
|
|
76
|
+
}
|
|
77
|
+
// Check ifMatch (optimistic locking)
|
|
78
|
+
if (options.ifMatch !== undefined) {
|
|
79
|
+
if (!existingBlob) {
|
|
80
|
+
// Real @vercel/blob throws "The specified key does not exist"
|
|
81
|
+
throw new BlobPreconditionFailedError();
|
|
82
|
+
}
|
|
83
|
+
if (existingBlob.etag !== options.ifMatch) {
|
|
84
|
+
throw new BlobPreconditionFailedError();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const content = await toBuffer(body);
|
|
88
|
+
const etag = generateEtag();
|
|
89
|
+
this.blobs.set(pathname, {
|
|
90
|
+
pathname,
|
|
91
|
+
content,
|
|
92
|
+
contentType: options.contentType ?? "application/octet-stream",
|
|
93
|
+
uploadedAt: new Date(),
|
|
94
|
+
size: content.length,
|
|
95
|
+
etag,
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
url: `fake://${pathname}`,
|
|
99
|
+
downloadUrl: `fake://${pathname}?download=1`,
|
|
100
|
+
pathname,
|
|
101
|
+
contentType: options.contentType ?? "application/octet-stream",
|
|
102
|
+
contentDisposition: `attachment; filename="${pathname.split("/").pop()}"`,
|
|
103
|
+
etag,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async del(urlOrPathname) {
|
|
107
|
+
const paths = Array.isArray(urlOrPathname)
|
|
108
|
+
? urlOrPathname
|
|
109
|
+
: [urlOrPathname];
|
|
110
|
+
for (const p of paths) {
|
|
111
|
+
// Handle both URLs and pathnames
|
|
112
|
+
const pathname = p.startsWith("fake://") ? p.slice(7) : p;
|
|
113
|
+
this.blobs.delete(pathname);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async list(options) {
|
|
117
|
+
let entries = [...this.blobs.values()];
|
|
118
|
+
// Filter by prefix
|
|
119
|
+
if (options?.prefix) {
|
|
120
|
+
entries = entries.filter((b) => b.pathname.startsWith(options.prefix));
|
|
121
|
+
}
|
|
122
|
+
// Sort by pathname for consistent ordering
|
|
123
|
+
entries.sort((a, b) => a.pathname.localeCompare(b.pathname));
|
|
124
|
+
// Handle pagination
|
|
125
|
+
const limit = options?.limit ?? 1000;
|
|
126
|
+
const cursorIndex = options?.cursor
|
|
127
|
+
? Number.parseInt(options.cursor, 10)
|
|
128
|
+
: 0;
|
|
129
|
+
const slice = entries.slice(cursorIndex, cursorIndex + limit);
|
|
130
|
+
const hasMore = cursorIndex + limit < entries.length;
|
|
131
|
+
return {
|
|
132
|
+
blobs: slice.map((b) => ({
|
|
133
|
+
url: `fake://${b.pathname}`,
|
|
134
|
+
downloadUrl: `fake://${b.pathname}?download=1`,
|
|
135
|
+
pathname: b.pathname,
|
|
136
|
+
size: b.size,
|
|
137
|
+
uploadedAt: b.uploadedAt,
|
|
138
|
+
etag: b.etag,
|
|
139
|
+
})),
|
|
140
|
+
hasMore,
|
|
141
|
+
cursor: hasMore ? String(cursorIndex + limit) : undefined,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Test helpers
|
|
145
|
+
clear() {
|
|
146
|
+
this.blobs.clear();
|
|
147
|
+
}
|
|
148
|
+
has(pathname) {
|
|
149
|
+
return this.blobs.has(pathname);
|
|
150
|
+
}
|
|
151
|
+
getContent(pathname) {
|
|
152
|
+
return this.blobs.get(pathname)?.content;
|
|
153
|
+
}
|
|
154
|
+
getAll() {
|
|
155
|
+
return new Map(this.blobs);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=fake-blob-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-blob-store.js","sourceRoot":"","sources":["../../src/testing/fake-blob-store.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,2BAA2B,GAO3B,MAAM,cAAc,CAAC;AAYtB,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,SAAS,YAAY;IACpB,OAAO,cAAc,EAAE,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAa;IACpC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,IAAI,YAAY,MAAM,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IACD,IAAI,IAAI,YAAY,cAAc,EAAE,CAAC;QACpC,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,IAAI,EAAE,CAAC;YACb,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,OAAO,aAAa;IACjB,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE9C,KAAK,CAAC,GAAG,CACR,QAAgB,EAChB,QAA2B;QAE3B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,cAAc,CAAa;YAC7C,KAAK,CAAC,UAAU;gBACf,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC5C,UAAU,CAAC,KAAK,EAAE,CAAC;YACpB,CAAC;SACD,CAAC,CAAC;QAEH,OAAO;YACN,MAAM;YACN,IAAI,EAAE;gBACL,GAAG,EAAE,UAAU,QAAQ,EAAE;gBACzB,WAAW,EAAE,UAAU,QAAQ,aAAa;gBAC5C,QAAQ;gBACR,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,kBAAkB,EAAE,yBAAyB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG;gBACzE,YAAY,EAAE,qCAAqC;gBACnD,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;aACf;YACD,OAAO,EAAE,IAAI,OAAO,CAAC;gBACpB,cAAc,EAAE,IAAI,CAAC,WAAW;gBAChC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACnC,IAAI,EAAE,IAAI,CAAC,IAAI;aACf,CAAC;SACF,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CACR,QAAgB,EAChB,IAAa,EACb,OAA0B;QAE1B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE9C,6EAA6E;QAC7E,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;QACtD,IAAI,CAAC,cAAc,IAAI,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,2BAA2B,EAAE,CAAC;QACzC,CAAC;QAED,qCAAqC;QACrC,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACnB,8DAA8D;gBAC9D,MAAM,IAAI,2BAA2B,EAAE,CAAC;YACzC,CAAC;YACD,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC3C,MAAM,IAAI,2BAA2B,EAAE,CAAC;YACzC,CAAC;QACF,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;YACxB,QAAQ;YACR,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,0BAA0B;YAC9D,UAAU,EAAE,IAAI,IAAI,EAAE;YACtB,IAAI,EAAE,OAAO,CAAC,MAAM;YACpB,IAAI;SACJ,CAAC,CAAC;QAEH,OAAO;YACN,GAAG,EAAE,UAAU,QAAQ,EAAE;YACzB,WAAW,EAAE,UAAU,QAAQ,aAAa;YAC5C,QAAQ;YACR,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,0BAA0B;YAC9D,kBAAkB,EAAE,yBAAyB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG;YACzE,IAAI;SACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,aAAgC;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;YACzC,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACvB,iCAAiC;YACjC,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAA4B;QACtC,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAEvC,mBAAmB;QACnB,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YACrB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9B,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,MAAgB,CAAC,CAC/C,CAAC;QACH,CAAC;QAED,2CAA2C;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE7D,oBAAoB;QACpB,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC;QACrC,MAAM,WAAW,GAAG,OAAO,EAAE,MAAM;YAClC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,CAAC,CAAC,CAAC,CAAC;QACL,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,WAAW,GAAG,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;QAErD,OAAO;YACN,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxB,GAAG,EAAE,UAAU,CAAC,CAAC,QAAQ,EAAE;gBAC3B,WAAW,EAAE,UAAU,CAAC,CAAC,QAAQ,aAAa;gBAC9C,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,IAAI,EAAE,CAAC,CAAC,IAAI;aACZ,CAAC,CAAC;YACH,OAAO;YACP,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SACzD,CAAC;IACH,CAAC;IAED,eAAe;IACf,KAAK;QACJ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,GAAG,CAAC,QAAgB;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,QAAgB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC1C,CAAC;IAED,MAAM;QACL,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;CACD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fake cache implementation for testing KVCache without @vercel/functions.
|
|
3
|
+
* Supports programmatic control over success/failure and inspection of calls.
|
|
4
|
+
*/
|
|
5
|
+
import type { CacheLike } from "../types.js";
|
|
6
|
+
export interface CacheCall {
|
|
7
|
+
method: "get" | "set" | "expireTag";
|
|
8
|
+
args: unknown[];
|
|
9
|
+
timestamp: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class FakeCache implements CacheLike {
|
|
12
|
+
private data;
|
|
13
|
+
private tags;
|
|
14
|
+
private calls;
|
|
15
|
+
private getError;
|
|
16
|
+
private setError;
|
|
17
|
+
private expireTagError;
|
|
18
|
+
private getErrorOnce;
|
|
19
|
+
private setErrorOnce;
|
|
20
|
+
private expireTagErrorOnce;
|
|
21
|
+
get(key: string): Promise<unknown>;
|
|
22
|
+
set(key: string, value: unknown, options?: {
|
|
23
|
+
tags?: string[];
|
|
24
|
+
ttl?: number;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
expireTag(tag: string): Promise<void>;
|
|
27
|
+
/** Set a value directly (bypassing set() tracking) */
|
|
28
|
+
inject(key: string, value: unknown): void;
|
|
29
|
+
/** Clear all data and call history */
|
|
30
|
+
clear(): void;
|
|
31
|
+
/** Get all recorded calls */
|
|
32
|
+
getCalls(): CacheCall[];
|
|
33
|
+
/** Get calls for a specific method */
|
|
34
|
+
getCallsFor(method: "get" | "set" | "expireTag"): CacheCall[];
|
|
35
|
+
/** Clear call history only */
|
|
36
|
+
clearCalls(): void;
|
|
37
|
+
/** Make get() always throw */
|
|
38
|
+
failGet(error: Error): void;
|
|
39
|
+
/** Make set() always throw */
|
|
40
|
+
failSet(error: Error): void;
|
|
41
|
+
/** Make expireTag() always throw */
|
|
42
|
+
failExpireTag(error: Error): void;
|
|
43
|
+
/** Make get() throw once, then succeed */
|
|
44
|
+
failGetOnce(error: Error): void;
|
|
45
|
+
/** Make set() throw once, then succeed */
|
|
46
|
+
failSetOnce(error: Error): void;
|
|
47
|
+
/** Make expireTag() throw once, then succeed */
|
|
48
|
+
failExpireTagOnce(error: Error): void;
|
|
49
|
+
/** Check if a key exists */
|
|
50
|
+
has(key: string): boolean;
|
|
51
|
+
/** Get raw data (for inspection) */
|
|
52
|
+
getData(key: string): unknown;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=fake-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-cache.d.ts","sourceRoot":"","sources":["../../src/testing/fake-cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,SAAS;IACzB,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,WAAW,CAAC;IACpC,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAU,YAAW,SAAS;IAC1C,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,KAAK,CAAmB;IAGhC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,kBAAkB,CAAe;IAEnC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAelC,GAAG,CACR,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACzC,OAAO,CAAC,IAAI,CAAC;IA6BV,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B3C,sDAAsD;IACtD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIzC,sCAAsC;IACtC,KAAK,IAAI,IAAI;IAYb,6BAA6B;IAC7B,QAAQ,IAAI,SAAS,EAAE;IAIvB,sCAAsC;IACtC,WAAW,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,WAAW,GAAG,SAAS,EAAE;IAI7D,8BAA8B;IAC9B,UAAU,IAAI,IAAI;IAIlB,8BAA8B;IAC9B,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI3B,8BAA8B;IAC9B,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI3B,oCAAoC;IACpC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIjC,0CAA0C;IAC1C,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI/B,0CAA0C;IAC1C,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI/B,gDAAgD;IAChD,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIrC,4BAA4B;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,oCAAoC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAG7B"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fake cache implementation for testing KVCache without @vercel/functions.
|
|
3
|
+
* Supports programmatic control over success/failure and inspection of calls.
|
|
4
|
+
*/
|
|
5
|
+
export class FakeCache {
|
|
6
|
+
data = new Map();
|
|
7
|
+
tags = new Map(); // tag -> keys
|
|
8
|
+
calls = [];
|
|
9
|
+
// Control behavior
|
|
10
|
+
getError = null;
|
|
11
|
+
setError = null;
|
|
12
|
+
expireTagError = null;
|
|
13
|
+
getErrorOnce = [];
|
|
14
|
+
setErrorOnce = [];
|
|
15
|
+
expireTagErrorOnce = [];
|
|
16
|
+
async get(key) {
|
|
17
|
+
this.calls.push({ method: "get", args: [key], timestamp: Date.now() });
|
|
18
|
+
if (this.getErrorOnce.length > 0) {
|
|
19
|
+
const error = this.getErrorOnce[0];
|
|
20
|
+
this.getErrorOnce.shift();
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
if (this.getError) {
|
|
24
|
+
throw this.getError;
|
|
25
|
+
}
|
|
26
|
+
return this.data.get(key) ?? null;
|
|
27
|
+
}
|
|
28
|
+
async set(key, value, options) {
|
|
29
|
+
this.calls.push({
|
|
30
|
+
method: "set",
|
|
31
|
+
args: [key, value, options],
|
|
32
|
+
timestamp: Date.now(),
|
|
33
|
+
});
|
|
34
|
+
if (this.setErrorOnce.length > 0) {
|
|
35
|
+
const error = this.setErrorOnce[0];
|
|
36
|
+
this.setErrorOnce.shift();
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
if (this.setError) {
|
|
40
|
+
throw this.setError;
|
|
41
|
+
}
|
|
42
|
+
this.data.set(key, value);
|
|
43
|
+
// Track tags
|
|
44
|
+
if (options?.tags) {
|
|
45
|
+
for (const tag of options.tags) {
|
|
46
|
+
if (!this.tags.has(tag)) {
|
|
47
|
+
this.tags.set(tag, new Set());
|
|
48
|
+
}
|
|
49
|
+
this.tags.get(tag)?.add(key);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async expireTag(tag) {
|
|
54
|
+
this.calls.push({
|
|
55
|
+
method: "expireTag",
|
|
56
|
+
args: [tag],
|
|
57
|
+
timestamp: Date.now(),
|
|
58
|
+
});
|
|
59
|
+
if (this.expireTagErrorOnce.length > 0) {
|
|
60
|
+
const error = this.expireTagErrorOnce[0];
|
|
61
|
+
this.expireTagErrorOnce.shift();
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
if (this.expireTagError) {
|
|
65
|
+
throw this.expireTagError;
|
|
66
|
+
}
|
|
67
|
+
const keys = this.tags.get(tag);
|
|
68
|
+
if (keys) {
|
|
69
|
+
for (const key of keys) {
|
|
70
|
+
this.data.delete(key);
|
|
71
|
+
}
|
|
72
|
+
this.tags.delete(tag);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Test helpers
|
|
76
|
+
/** Set a value directly (bypassing set() tracking) */
|
|
77
|
+
inject(key, value) {
|
|
78
|
+
this.data.set(key, value);
|
|
79
|
+
}
|
|
80
|
+
/** Clear all data and call history */
|
|
81
|
+
clear() {
|
|
82
|
+
this.data.clear();
|
|
83
|
+
this.tags.clear();
|
|
84
|
+
this.calls = [];
|
|
85
|
+
this.getError = null;
|
|
86
|
+
this.setError = null;
|
|
87
|
+
this.expireTagError = null;
|
|
88
|
+
this.getErrorOnce = [];
|
|
89
|
+
this.setErrorOnce = [];
|
|
90
|
+
this.expireTagErrorOnce = [];
|
|
91
|
+
}
|
|
92
|
+
/** Get all recorded calls */
|
|
93
|
+
getCalls() {
|
|
94
|
+
return [...this.calls];
|
|
95
|
+
}
|
|
96
|
+
/** Get calls for a specific method */
|
|
97
|
+
getCallsFor(method) {
|
|
98
|
+
return this.calls.filter((c) => c.method === method);
|
|
99
|
+
}
|
|
100
|
+
/** Clear call history only */
|
|
101
|
+
clearCalls() {
|
|
102
|
+
this.calls = [];
|
|
103
|
+
}
|
|
104
|
+
/** Make get() always throw */
|
|
105
|
+
failGet(error) {
|
|
106
|
+
this.getError = error;
|
|
107
|
+
}
|
|
108
|
+
/** Make set() always throw */
|
|
109
|
+
failSet(error) {
|
|
110
|
+
this.setError = error;
|
|
111
|
+
}
|
|
112
|
+
/** Make expireTag() always throw */
|
|
113
|
+
failExpireTag(error) {
|
|
114
|
+
this.expireTagError = error;
|
|
115
|
+
}
|
|
116
|
+
/** Make get() throw once, then succeed */
|
|
117
|
+
failGetOnce(error) {
|
|
118
|
+
this.getErrorOnce.push(error);
|
|
119
|
+
}
|
|
120
|
+
/** Make set() throw once, then succeed */
|
|
121
|
+
failSetOnce(error) {
|
|
122
|
+
this.setErrorOnce.push(error);
|
|
123
|
+
}
|
|
124
|
+
/** Make expireTag() throw once, then succeed */
|
|
125
|
+
failExpireTagOnce(error) {
|
|
126
|
+
this.expireTagErrorOnce.push(error);
|
|
127
|
+
}
|
|
128
|
+
/** Check if a key exists */
|
|
129
|
+
has(key) {
|
|
130
|
+
return this.data.has(key);
|
|
131
|
+
}
|
|
132
|
+
/** Get raw data (for inspection) */
|
|
133
|
+
getData(key) {
|
|
134
|
+
return this.data.get(key);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=fake-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-cache.js","sourceRoot":"","sources":["../../src/testing/fake-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { KV2 } from "../cached-kv.js";
|
|
2
|
+
import type { BlobStore, KV2Options, PrefixString, Tracer } from "../types.js";
|
|
3
|
+
export { FakeBlobStore } from "./fake-blob-store.js";
|
|
4
|
+
export { FakeCache } from "./fake-cache.js";
|
|
5
|
+
export { runTests, resetTestState, getRegisteredTests, type TestResult, type RunResult, type RunTestsOptions, } from "./vitest-compat.js";
|
|
6
|
+
/** Get the shared stats tracer for integration tests */
|
|
7
|
+
export declare function getStatsTracer(): Tracer;
|
|
8
|
+
/** Print timing statistics summary */
|
|
9
|
+
export declare function printTimingStats(): void;
|
|
10
|
+
/** Clear timing statistics */
|
|
11
|
+
export declare function clearTimingStats(): void;
|
|
12
|
+
/** Get timing statistics for a specific operation or overall */
|
|
13
|
+
export declare function getTimingStats(operation?: string): import("../tracing.js").TimingStats | null;
|
|
14
|
+
/** Whether to use real blob store (set INTEGRATION_TEST=1) */
|
|
15
|
+
export declare function useRealBlobStore(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Validate environment for integration tests.
|
|
18
|
+
* Throws if required env vars are missing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateIntegrationTestEnv(): void;
|
|
21
|
+
export interface TestKVResult<M> {
|
|
22
|
+
kv: KV2<M>;
|
|
23
|
+
blobStore: BlobStore;
|
|
24
|
+
isReal: boolean;
|
|
25
|
+
cleanup: () => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a KV2 for testing.
|
|
29
|
+
* Uses fake blob store by default, or real blob store if INTEGRATION_TEST=1.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createTestKV<M = Record<string, unknown>>(options?: Partial<KV2Options>): TestKVResult<M>;
|
|
32
|
+
export declare function uniqueTestPrefix(): PrefixString;
|
|
33
|
+
export declare function cleanupTestBlobs(prefix: string, blobStore?: BlobStore): Promise<void>;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EACN,QAAQ,EACR,cAAc,EACd,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC;AAK5B,wDAAwD;AACxD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,sCAAsC;AACtC,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,8BAA8B;AAC9B,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,8CAEhD;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAoBjD;AACD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvD,OAAO,GAAE,OAAO,CAAC,UAAU,CAAM,GAC/B,YAAY,CAAC,CAAC,CAAC,CAgCjB;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAI/C;AAED,wBAAsB,gBAAgB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,SAAS,GACnB,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { VercelBlobStore } from "../blob-store.js";
|
|
2
|
+
import { KV2 } from "../cached-kv.js";
|
|
3
|
+
import { createStatsTracer } from "../tracing.js";
|
|
4
|
+
import { FakeBlobStore } from "./fake-blob-store.js";
|
|
5
|
+
export { FakeBlobStore } from "./fake-blob-store.js";
|
|
6
|
+
export { FakeCache } from "./fake-cache.js";
|
|
7
|
+
// Test runner exports
|
|
8
|
+
export { runTests, resetTestState, getRegisteredTests, } from "./vitest-compat.js";
|
|
9
|
+
// Shared stats tracer for integration tests
|
|
10
|
+
const statsTracer = createStatsTracer();
|
|
11
|
+
/** Get the shared stats tracer for integration tests */
|
|
12
|
+
export function getStatsTracer() {
|
|
13
|
+
return statsTracer.tracer;
|
|
14
|
+
}
|
|
15
|
+
/** Print timing statistics summary */
|
|
16
|
+
export function printTimingStats() {
|
|
17
|
+
statsTracer.printStats();
|
|
18
|
+
}
|
|
19
|
+
/** Clear timing statistics */
|
|
20
|
+
export function clearTimingStats() {
|
|
21
|
+
statsTracer.clear();
|
|
22
|
+
}
|
|
23
|
+
/** Get timing statistics for a specific operation or overall */
|
|
24
|
+
export function getTimingStats(operation) {
|
|
25
|
+
return statsTracer.getStats(operation);
|
|
26
|
+
}
|
|
27
|
+
/** Whether to use real blob store (set INTEGRATION_TEST=1) */
|
|
28
|
+
export function useRealBlobStore() {
|
|
29
|
+
return process.env.INTEGRATION_TEST === "1";
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validate environment for integration tests.
|
|
33
|
+
* Throws if required env vars are missing.
|
|
34
|
+
*/
|
|
35
|
+
export function validateIntegrationTestEnv() {
|
|
36
|
+
if (process.env.INTEGRATION_TEST !== "1") {
|
|
37
|
+
return; // Not running integration tests, no validation needed
|
|
38
|
+
}
|
|
39
|
+
const missing = [];
|
|
40
|
+
if (!process.env.BLOB_READ_WRITE_TOKEN) {
|
|
41
|
+
missing.push("BLOB_READ_WRITE_TOKEN");
|
|
42
|
+
}
|
|
43
|
+
if (!process.env.PROTECTION_BYPASS) {
|
|
44
|
+
missing.push("PROTECTION_BYPASS");
|
|
45
|
+
}
|
|
46
|
+
if (missing.length > 0) {
|
|
47
|
+
throw new Error(`Integration tests require these environment variables: ${missing.join(", ")}\nSet them in .env.local or export them before running tests.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a KV2 for testing.
|
|
52
|
+
* Uses fake blob store by default, or real blob store if INTEGRATION_TEST=1.
|
|
53
|
+
*/
|
|
54
|
+
export function createTestKV(options = {}) {
|
|
55
|
+
const prefix = options.prefix ?? uniqueTestPrefix();
|
|
56
|
+
if (useRealBlobStore()) {
|
|
57
|
+
// Env validation happens at test startup via validateIntegrationTestEnv()
|
|
58
|
+
const blobStore = new VercelBlobStore();
|
|
59
|
+
const kv = new KV2({
|
|
60
|
+
...options,
|
|
61
|
+
prefix,
|
|
62
|
+
blobStore,
|
|
63
|
+
tracer: statsTracer.tracer,
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
kv,
|
|
67
|
+
blobStore,
|
|
68
|
+
isReal: true,
|
|
69
|
+
cleanup: () => cleanupTestBlobs(prefix, blobStore),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const blobStore = new FakeBlobStore();
|
|
73
|
+
const kv = new KV2({
|
|
74
|
+
...options,
|
|
75
|
+
prefix,
|
|
76
|
+
blobStore,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
kv,
|
|
80
|
+
blobStore,
|
|
81
|
+
isReal: false,
|
|
82
|
+
cleanup: async () => blobStore.clear(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export function uniqueTestPrefix() {
|
|
86
|
+
const timestamp = Date.now();
|
|
87
|
+
const random = Math.random().toString(36).slice(2, 8);
|
|
88
|
+
return `test-${timestamp}-${random}/`;
|
|
89
|
+
}
|
|
90
|
+
export async function cleanupTestBlobs(prefix, blobStore) {
|
|
91
|
+
const store = blobStore ?? new VercelBlobStore();
|
|
92
|
+
let cursor;
|
|
93
|
+
do {
|
|
94
|
+
const result = await store.list({ prefix: `cached-kv/${prefix}`, cursor });
|
|
95
|
+
if (result.blobs.length > 0) {
|
|
96
|
+
await store.del(result.blobs.map((b) => b.pathname));
|
|
97
|
+
}
|
|
98
|
+
cursor = result.cursor;
|
|
99
|
+
} while (cursor);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ManifestLog } from "../manifest-log.js";
|
|
2
|
+
import type { BlobStore } from "../types.js";
|
|
3
|
+
import { type TestContext as BaseTestContext } from "./vitest-compat.js";
|
|
4
|
+
/** Context available to each ManifestLog test */
|
|
5
|
+
export interface ManifestTestContext extends BaseTestContext {
|
|
6
|
+
blobStore: BlobStore;
|
|
7
|
+
manifest: ManifestLog;
|
|
8
|
+
manifestPrefix: string;
|
|
9
|
+
cleanup?: () => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Sets up a ManifestLog test context.
|
|
13
|
+
* Each test gets its own isolated FakeBlobStore and ManifestLog.
|
|
14
|
+
* Uses real blob store if INTEGRATION_TEST=1.
|
|
15
|
+
*/
|
|
16
|
+
export declare function setupManifestTestContext(): void;
|
|
17
|
+
/** Typed test function that receives ManifestTestContext */
|
|
18
|
+
type TypedTestFn = (ctx: ManifestTestContext) => Promise<void> | void;
|
|
19
|
+
/** Typed `it` that provides ManifestTestContext to tests */
|
|
20
|
+
export declare const it: (name: string, fn: TypedTestFn) => void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=manifest-test-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-test-setup.d.ts","sourceRoot":"","sources":["../../src/testing/manifest-test-setup.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AASxD,OAAO,EACN,KAAK,WAAW,IAAI,eAAe,EAInC,MAAM,oBAAoB,CAAC;AAE5B,iDAAiD;AACjD,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC3D,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAkC/C;AAED,4DAA4D;AAC5D,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEtE,4DAA4D;AAC5D,eAAO,MAAM,EAAE,GAAI,MAAM,MAAM,EAAE,IAAI,WAAW,KAAG,IAElD,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { VercelBlobStore } from "../blob-store.js";
|
|
2
|
+
import { ManifestLog } from "../manifest-log.js";
|
|
3
|
+
import { FakeBlobStore } from "./fake-blob-store.js";
|
|
4
|
+
import { FakeCache } from "./fake-cache.js";
|
|
5
|
+
import { cleanupTestBlobs, uniqueTestPrefix, useRealBlobStore, } from "./index.js";
|
|
6
|
+
import { afterEach, it as baseIt, beforeEach, } from "./vitest-compat.js";
|
|
7
|
+
/**
|
|
8
|
+
* Sets up a ManifestLog test context.
|
|
9
|
+
* Each test gets its own isolated FakeBlobStore and ManifestLog.
|
|
10
|
+
* Uses real blob store if INTEGRATION_TEST=1.
|
|
11
|
+
*/
|
|
12
|
+
export function setupManifestTestContext() {
|
|
13
|
+
beforeEach((ctx) => {
|
|
14
|
+
const testCtx = ctx;
|
|
15
|
+
if (useRealBlobStore()) {
|
|
16
|
+
// Integration test: use real blob store with unique prefix
|
|
17
|
+
const prefix = uniqueTestPrefix();
|
|
18
|
+
testCtx.blobStore = new VercelBlobStore();
|
|
19
|
+
testCtx.manifestPrefix = `${prefix}_manifest/`;
|
|
20
|
+
// No FakeCache in integration - uses real Vercel cache via proxy
|
|
21
|
+
testCtx.manifest = new ManifestLog(testCtx.blobStore, testCtx.manifestPrefix);
|
|
22
|
+
testCtx.cleanup = () => cleanupTestBlobs(prefix, testCtx.blobStore);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Unit test: use fakes
|
|
26
|
+
testCtx.blobStore = new FakeBlobStore();
|
|
27
|
+
testCtx.manifestPrefix = "test/_manifest/";
|
|
28
|
+
const cache = new FakeCache();
|
|
29
|
+
testCtx.manifest = new ManifestLog(testCtx.blobStore, testCtx.manifestPrefix, cache);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
afterEach(async (ctx) => {
|
|
33
|
+
const testCtx = ctx;
|
|
34
|
+
if (testCtx.cleanup) {
|
|
35
|
+
await testCtx.cleanup();
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Typed `it` that provides ManifestTestContext to tests */
|
|
40
|
+
export const it = (name, fn) => {
|
|
41
|
+
baseIt(name, fn);
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=manifest-test-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-test-setup.js","sourceRoot":"","sources":["../../src/testing/manifest-test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACN,gBAAgB,EAEhB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEN,SAAS,EACT,EAAE,IAAI,MAAM,EACZ,UAAU,GACV,MAAM,oBAAoB,CAAC;AAU5B;;;;GAIG;AACH,MAAM,UAAU,wBAAwB;IACvC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE;QAClB,MAAM,OAAO,GAAG,GAA0B,CAAC;QAE3C,IAAI,gBAAgB,EAAE,EAAE,CAAC;YACxB,2DAA2D;YAC3D,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;YAClC,OAAO,CAAC,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;YAC1C,OAAO,CAAC,cAAc,GAAG,GAAG,MAAM,YAAY,CAAC;YAC/C,iEAAiE;YACjE,OAAO,CAAC,QAAQ,GAAG,IAAI,WAAW,CACjC,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,cAAc,CACtB,CAAC;YACF,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACP,uBAAuB;YACvB,OAAO,CAAC,SAAS,GAAG,IAAI,aAAa,EAAE,CAAC;YACxC,OAAO,CAAC,cAAc,GAAG,iBAAiB,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,WAAW,CACjC,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,cAAc,EACtB,KAAK,CACL,CAAC;QACH,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvB,MAAM,OAAO,GAAG,GAA0B,CAAC;QAC3C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAKD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAY,EAAE,EAAe,EAAQ,EAAE;IACzD,MAAM,CAAC,IAAI,EAAE,EAAoD,CAAC,CAAC;AACpE,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance comparison test: raw blob access vs cached reads
|
|
3
|
+
*/
|
|
4
|
+
export interface PerfResult {
|
|
5
|
+
rawBlobReads: number[];
|
|
6
|
+
cachedReads: number[];
|
|
7
|
+
rawBlobAvg: number;
|
|
8
|
+
cachedAvg: number;
|
|
9
|
+
speedup: number;
|
|
10
|
+
summary: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runPerfTest(iterations?: number): Promise<PerfResult>;
|
|
13
|
+
//# sourceMappingURL=perf-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf-test.d.ts","sourceRoot":"","sources":["../../src/testing/perf-test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,UAAU;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAmBD,wBAAsB,WAAW,CAAC,UAAU,SAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAwFtE"}
|