@dexto/storage 1.6.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/LICENSE +44 -0
- package/README.md +80 -0
- package/dist/blob/factories/index.cjs +31 -0
- package/dist/blob/factories/index.d.cts +6 -0
- package/dist/blob/factories/index.d.ts +6 -0
- package/dist/blob/factories/index.d.ts.map +1 -0
- package/dist/blob/factories/index.js +6 -0
- package/dist/blob/factories/local.cjs +38 -0
- package/dist/blob/factories/local.d.cts +21 -0
- package/dist/blob/factories/local.d.ts +17 -0
- package/dist/blob/factories/local.d.ts.map +1 -0
- package/dist/blob/factories/local.js +14 -0
- package/dist/blob/factories/memory.cjs +44 -0
- package/dist/blob/factories/memory.d.cts +21 -0
- package/dist/blob/factories/memory.d.ts +17 -0
- package/dist/blob/factories/memory.d.ts.map +1 -0
- package/dist/blob/factories/memory.js +20 -0
- package/dist/blob/factory.cjs +16 -0
- package/dist/blob/factory.d.cts +36 -0
- package/dist/blob/factory.d.ts +35 -0
- package/dist/blob/factory.d.ts.map +1 -0
- package/dist/blob/factory.js +0 -0
- package/dist/blob/index.cjs +45 -0
- package/dist/blob/index.d.cts +8 -0
- package/dist/blob/index.d.ts +26 -0
- package/dist/blob/index.d.ts.map +1 -0
- package/dist/blob/index.js +19 -0
- package/dist/blob/local-blob-store.cjs +532 -0
- package/dist/blob/local-blob-store.d.cts +56 -0
- package/dist/blob/local-blob-store.d.ts +54 -0
- package/dist/blob/local-blob-store.d.ts.map +1 -0
- package/dist/blob/local-blob-store.js +498 -0
- package/dist/blob/memory-blob-store.cjs +327 -0
- package/dist/blob/memory-blob-store.d.cts +69 -0
- package/dist/blob/memory-blob-store.d.ts +67 -0
- package/dist/blob/memory-blob-store.d.ts.map +1 -0
- package/dist/blob/memory-blob-store.js +303 -0
- package/dist/blob/schemas.cjs +52 -0
- package/dist/blob/schemas.d.cts +87 -0
- package/dist/blob/schemas.d.ts +86 -0
- package/dist/blob/schemas.d.ts.map +1 -0
- package/dist/blob/schemas.js +25 -0
- package/dist/blob/types.cjs +16 -0
- package/dist/blob/types.d.cts +1 -0
- package/dist/blob/types.d.ts +2 -0
- package/dist/blob/types.d.ts.map +1 -0
- package/dist/blob/types.js +0 -0
- package/dist/cache/factories/index.cjs +31 -0
- package/dist/cache/factories/index.d.cts +6 -0
- package/dist/cache/factories/index.d.ts +6 -0
- package/dist/cache/factories/index.d.ts.map +1 -0
- package/dist/cache/factories/index.js +6 -0
- package/dist/cache/factories/memory.cjs +39 -0
- package/dist/cache/factories/memory.d.cts +21 -0
- package/dist/cache/factories/memory.d.ts +17 -0
- package/dist/cache/factories/memory.d.ts.map +1 -0
- package/dist/cache/factories/memory.js +15 -0
- package/dist/cache/factories/redis.cjs +65 -0
- package/dist/cache/factories/redis.d.cts +24 -0
- package/dist/cache/factories/redis.d.ts +20 -0
- package/dist/cache/factories/redis.d.ts.map +1 -0
- package/dist/cache/factories/redis.js +31 -0
- package/dist/cache/factory.cjs +16 -0
- package/dist/cache/factory.d.cts +42 -0
- package/dist/cache/factory.d.ts +41 -0
- package/dist/cache/factory.d.ts.map +1 -0
- package/dist/cache/factory.js +0 -0
- package/dist/cache/index.cjs +42 -0
- package/dist/cache/index.d.cts +7 -0
- package/dist/cache/index.d.ts +25 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +17 -0
- package/dist/cache/memory-cache-store.cjs +106 -0
- package/dist/cache/memory-cache-store.d.cts +27 -0
- package/dist/cache/memory-cache-store.d.ts +25 -0
- package/dist/cache/memory-cache-store.d.ts.map +1 -0
- package/dist/cache/memory-cache-store.js +82 -0
- package/dist/cache/redis-store.cjs +176 -0
- package/dist/cache/redis-store.d.cts +34 -0
- package/dist/cache/redis-store.d.ts +32 -0
- package/dist/cache/redis-store.d.ts.map +1 -0
- package/dist/cache/redis-store.js +152 -0
- package/dist/cache/schemas.cjs +70 -0
- package/dist/cache/schemas.d.cts +93 -0
- package/dist/cache/schemas.d.ts +91 -0
- package/dist/cache/schemas.d.ts.map +1 -0
- package/dist/cache/schemas.js +43 -0
- package/dist/cache/types.cjs +16 -0
- package/dist/cache/types.d.cts +1 -0
- package/dist/cache/types.d.ts +2 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +0 -0
- package/dist/database/factories/index.cjs +34 -0
- package/dist/database/factories/index.d.cts +7 -0
- package/dist/database/factories/index.d.ts +7 -0
- package/dist/database/factories/index.d.ts.map +1 -0
- package/dist/database/factories/index.js +8 -0
- package/dist/database/factories/memory.cjs +39 -0
- package/dist/database/factories/memory.d.cts +20 -0
- package/dist/database/factories/memory.d.ts +16 -0
- package/dist/database/factories/memory.d.ts.map +1 -0
- package/dist/database/factories/memory.js +15 -0
- package/dist/database/factories/postgres.cjs +61 -0
- package/dist/database/factories/postgres.d.cts +23 -0
- package/dist/database/factories/postgres.d.ts +19 -0
- package/dist/database/factories/postgres.d.ts.map +1 -0
- package/dist/database/factories/postgres.js +27 -0
- package/dist/database/factories/sqlite.cjs +65 -0
- package/dist/database/factories/sqlite.d.cts +24 -0
- package/dist/database/factories/sqlite.d.ts +20 -0
- package/dist/database/factories/sqlite.d.ts.map +1 -0
- package/dist/database/factories/sqlite.js +31 -0
- package/dist/database/factory.cjs +16 -0
- package/dist/database/factory.d.cts +42 -0
- package/dist/database/factory.d.ts +41 -0
- package/dist/database/factory.d.ts.map +1 -0
- package/dist/database/factory.js +0 -0
- package/dist/database/index.cjs +46 -0
- package/dist/database/index.d.cts +8 -0
- package/dist/database/index.d.ts +26 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +24 -0
- package/dist/database/memory-database-store.cjs +121 -0
- package/dist/database/memory-database-store.d.cts +30 -0
- package/dist/database/memory-database-store.d.ts +28 -0
- package/dist/database/memory-database-store.d.ts.map +1 -0
- package/dist/database/memory-database-store.js +97 -0
- package/dist/database/postgres-store.cjs +342 -0
- package/dist/database/postgres-store.d.cts +57 -0
- package/dist/database/postgres-store.d.ts +55 -0
- package/dist/database/postgres-store.d.ts.map +1 -0
- package/dist/database/postgres-store.js +318 -0
- package/dist/database/schemas.cjs +82 -0
- package/dist/database/schemas.d.cts +127 -0
- package/dist/database/schemas.d.ts +125 -0
- package/dist/database/schemas.d.ts.map +1 -0
- package/dist/database/schemas.js +54 -0
- package/dist/database/sqlite-store.cjs +270 -0
- package/dist/database/sqlite-store.d.cts +35 -0
- package/dist/database/sqlite-store.d.ts +33 -0
- package/dist/database/sqlite-store.d.ts.map +1 -0
- package/dist/database/sqlite-store.js +236 -0
- package/dist/database/types.cjs +16 -0
- package/dist/database/types.d.cts +1 -0
- package/dist/database/types.d.ts +2 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +0 -0
- package/dist/index.cjs +82 -0
- package/dist/index.d.cts +24 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/schemas.cjs +67 -0
- package/dist/schemas.d.cts +72 -0
- package/dist/schemas.d.ts +70 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +46 -0
- package/package.json +55 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
2
|
+
import { Readable } from "stream";
|
|
3
|
+
import { DextoLogComponent, StorageError } from "@dexto/core";
|
|
4
|
+
import { InMemoryBlobStoreSchema } from "./schemas.js";
|
|
5
|
+
const MemoryBlobStoreOptionsSchema = InMemoryBlobStoreSchema.omit({ type: true });
|
|
6
|
+
class MemoryBlobStore {
|
|
7
|
+
config;
|
|
8
|
+
blobs = /* @__PURE__ */ new Map();
|
|
9
|
+
connected = false;
|
|
10
|
+
logger;
|
|
11
|
+
constructor(options, logger) {
|
|
12
|
+
this.config = MemoryBlobStoreOptionsSchema.parse(options);
|
|
13
|
+
this.logger = logger.createChild(DextoLogComponent.STORAGE);
|
|
14
|
+
}
|
|
15
|
+
async connect() {
|
|
16
|
+
if (this.connected) return;
|
|
17
|
+
this.connected = true;
|
|
18
|
+
this.logger.debug("MemoryBlobStore connected");
|
|
19
|
+
}
|
|
20
|
+
async disconnect() {
|
|
21
|
+
this.blobs.clear();
|
|
22
|
+
this.connected = false;
|
|
23
|
+
this.logger.debug("MemoryBlobStore disconnected");
|
|
24
|
+
}
|
|
25
|
+
isConnected() {
|
|
26
|
+
return this.connected;
|
|
27
|
+
}
|
|
28
|
+
getStoreType() {
|
|
29
|
+
return "in-memory";
|
|
30
|
+
}
|
|
31
|
+
async store(input, metadata = {}) {
|
|
32
|
+
if (!this.connected) {
|
|
33
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
34
|
+
}
|
|
35
|
+
const buffer = await this.inputToBuffer(input);
|
|
36
|
+
if (buffer.length > this.config.maxBlobSize) {
|
|
37
|
+
throw StorageError.blobSizeExceeded(buffer.length, this.config.maxBlobSize);
|
|
38
|
+
}
|
|
39
|
+
const hash = createHash("sha256").update(buffer).digest("hex").substring(0, 16);
|
|
40
|
+
const id = hash;
|
|
41
|
+
const existing = this.blobs.get(id);
|
|
42
|
+
if (existing) {
|
|
43
|
+
this.logger.debug(
|
|
44
|
+
`Blob ${id} already exists, returning existing reference (deduplication)`
|
|
45
|
+
);
|
|
46
|
+
return {
|
|
47
|
+
id,
|
|
48
|
+
uri: `blob:${id}`,
|
|
49
|
+
metadata: existing.metadata
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const currentSize = this.getTotalSize();
|
|
53
|
+
if (currentSize + buffer.length > this.config.maxTotalSize) {
|
|
54
|
+
throw StorageError.blobTotalSizeExceeded(
|
|
55
|
+
currentSize + buffer.length,
|
|
56
|
+
this.config.maxTotalSize
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
const storedMetadata = {
|
|
60
|
+
id,
|
|
61
|
+
mimeType: metadata.mimeType || this.detectMimeType(buffer, metadata.originalName),
|
|
62
|
+
originalName: metadata.originalName,
|
|
63
|
+
createdAt: metadata.createdAt || /* @__PURE__ */ new Date(),
|
|
64
|
+
source: metadata.source || "system",
|
|
65
|
+
size: buffer.length,
|
|
66
|
+
hash
|
|
67
|
+
};
|
|
68
|
+
this.blobs.set(id, { data: buffer, metadata: storedMetadata });
|
|
69
|
+
this.logger.debug(`Stored blob ${id} (${buffer.length} bytes, ${storedMetadata.mimeType})`);
|
|
70
|
+
return {
|
|
71
|
+
id,
|
|
72
|
+
uri: `blob:${id}`,
|
|
73
|
+
metadata: storedMetadata
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async retrieve(reference, format = "base64") {
|
|
77
|
+
if (!this.connected) {
|
|
78
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
79
|
+
}
|
|
80
|
+
const id = this.parseReference(reference);
|
|
81
|
+
const blob = this.blobs.get(id);
|
|
82
|
+
if (!blob) {
|
|
83
|
+
throw StorageError.blobNotFound(reference);
|
|
84
|
+
}
|
|
85
|
+
switch (format) {
|
|
86
|
+
case "base64":
|
|
87
|
+
return {
|
|
88
|
+
format: "base64",
|
|
89
|
+
data: blob.data.toString("base64"),
|
|
90
|
+
metadata: blob.metadata
|
|
91
|
+
};
|
|
92
|
+
case "buffer":
|
|
93
|
+
return {
|
|
94
|
+
format: "buffer",
|
|
95
|
+
data: Buffer.from(blob.data),
|
|
96
|
+
metadata: { ...blob.metadata }
|
|
97
|
+
};
|
|
98
|
+
case "path":
|
|
99
|
+
throw new Error(
|
|
100
|
+
"Path format not supported for in-memory blobs. Use local blob storage for filesystem paths."
|
|
101
|
+
);
|
|
102
|
+
case "stream": {
|
|
103
|
+
const stream = Readable.from(blob.data);
|
|
104
|
+
return {
|
|
105
|
+
format: "stream",
|
|
106
|
+
data: stream,
|
|
107
|
+
metadata: blob.metadata
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
case "url": {
|
|
111
|
+
const base64 = blob.data.toString("base64");
|
|
112
|
+
const mimeType = blob.metadata.mimeType || "application/octet-stream";
|
|
113
|
+
const dataUrl = `data:${mimeType};base64,${base64}`;
|
|
114
|
+
return {
|
|
115
|
+
format: "url",
|
|
116
|
+
data: dataUrl,
|
|
117
|
+
metadata: blob.metadata
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
throw StorageError.blobInvalidInput(format, `Unsupported format: ${format}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async exists(reference) {
|
|
125
|
+
if (!this.connected) {
|
|
126
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
127
|
+
}
|
|
128
|
+
const id = this.parseReference(reference);
|
|
129
|
+
return this.blobs.has(id);
|
|
130
|
+
}
|
|
131
|
+
async delete(reference) {
|
|
132
|
+
if (!this.connected) {
|
|
133
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
134
|
+
}
|
|
135
|
+
const id = this.parseReference(reference);
|
|
136
|
+
if (!this.blobs.has(id)) {
|
|
137
|
+
throw StorageError.blobNotFound(reference);
|
|
138
|
+
}
|
|
139
|
+
this.blobs.delete(id);
|
|
140
|
+
this.logger.debug(`Deleted blob: ${id}`);
|
|
141
|
+
}
|
|
142
|
+
async cleanup(olderThan) {
|
|
143
|
+
if (!this.connected) {
|
|
144
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
145
|
+
}
|
|
146
|
+
const cutoffDate = olderThan || new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
|
|
147
|
+
let deletedCount = 0;
|
|
148
|
+
for (const [id, { metadata }] of this.blobs.entries()) {
|
|
149
|
+
if (metadata.createdAt < cutoffDate) {
|
|
150
|
+
this.blobs.delete(id);
|
|
151
|
+
deletedCount++;
|
|
152
|
+
this.logger.debug(`Cleaned up old blob: ${id}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (deletedCount > 0) {
|
|
156
|
+
this.logger.info(`Blob cleanup: removed ${deletedCount} old blobs from memory`);
|
|
157
|
+
}
|
|
158
|
+
return deletedCount;
|
|
159
|
+
}
|
|
160
|
+
async getStats() {
|
|
161
|
+
if (!this.connected) {
|
|
162
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
count: this.blobs.size,
|
|
166
|
+
totalSize: this.getTotalSize(),
|
|
167
|
+
backendType: "in-memory",
|
|
168
|
+
storePath: "memory://"
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
async listBlobs() {
|
|
172
|
+
if (!this.connected) {
|
|
173
|
+
throw StorageError.blobBackendNotConnected("in-memory");
|
|
174
|
+
}
|
|
175
|
+
return Array.from(this.blobs.entries()).map(([id, { metadata }]) => ({
|
|
176
|
+
id,
|
|
177
|
+
uri: `blob:${id}`,
|
|
178
|
+
metadata
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
getStoragePath() {
|
|
182
|
+
return void 0;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Calculate total size of all blobs in memory
|
|
186
|
+
*/
|
|
187
|
+
getTotalSize() {
|
|
188
|
+
return Array.from(this.blobs.values()).reduce((sum, { data }) => sum + data.length, 0);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Convert various input types to Buffer.
|
|
192
|
+
* Copied from LocalBlobStore with minor adaptations.
|
|
193
|
+
*/
|
|
194
|
+
async inputToBuffer(input) {
|
|
195
|
+
if (Buffer.isBuffer(input)) {
|
|
196
|
+
return input;
|
|
197
|
+
}
|
|
198
|
+
if (input instanceof Uint8Array) {
|
|
199
|
+
return Buffer.from(input);
|
|
200
|
+
}
|
|
201
|
+
if (input instanceof ArrayBuffer) {
|
|
202
|
+
return Buffer.from(new Uint8Array(input));
|
|
203
|
+
}
|
|
204
|
+
if (typeof input === "string") {
|
|
205
|
+
if (input.startsWith("data:")) {
|
|
206
|
+
const commaIndex = input.indexOf(",");
|
|
207
|
+
if (commaIndex !== -1 && input.includes(";base64,")) {
|
|
208
|
+
const base64Data = input.substring(commaIndex + 1);
|
|
209
|
+
return Buffer.from(base64Data, "base64");
|
|
210
|
+
}
|
|
211
|
+
throw StorageError.blobEncodingError(
|
|
212
|
+
"inputToBuffer",
|
|
213
|
+
"Unsupported data URI format"
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
return Buffer.from(input, "base64");
|
|
218
|
+
} catch {
|
|
219
|
+
throw StorageError.blobEncodingError("inputToBuffer", "Invalid base64 string");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
throw StorageError.blobInvalidInput(input, `Unsupported input type: ${typeof input}`);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Parse blob reference to extract ID.
|
|
226
|
+
* Copied from LocalBlobStore.
|
|
227
|
+
*/
|
|
228
|
+
parseReference(reference) {
|
|
229
|
+
if (!reference) {
|
|
230
|
+
throw StorageError.blobInvalidReference(reference, "Empty reference");
|
|
231
|
+
}
|
|
232
|
+
if (reference.startsWith("blob:")) {
|
|
233
|
+
const id = reference.substring(5);
|
|
234
|
+
if (!id) {
|
|
235
|
+
throw StorageError.blobInvalidReference(reference, "Empty blob ID after prefix");
|
|
236
|
+
}
|
|
237
|
+
return id;
|
|
238
|
+
}
|
|
239
|
+
return reference;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Detect MIME type from buffer content and/or filename.
|
|
243
|
+
* Copied from LocalBlobStore.
|
|
244
|
+
*/
|
|
245
|
+
detectMimeType(buffer, filename) {
|
|
246
|
+
const header = buffer.subarray(0, 16);
|
|
247
|
+
if (header.length >= 3) {
|
|
248
|
+
const jpegSignature = header.subarray(0, 3);
|
|
249
|
+
if (jpegSignature.equals(Buffer.from([255, 216, 255]))) {
|
|
250
|
+
return "image/jpeg";
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (header.length >= 4) {
|
|
254
|
+
const signature = header.subarray(0, 4);
|
|
255
|
+
if (signature.equals(Buffer.from([137, 80, 78, 71]))) return "image/png";
|
|
256
|
+
if (signature.equals(Buffer.from([71, 73, 70, 56]))) return "image/gif";
|
|
257
|
+
if (signature.equals(Buffer.from([37, 80, 68, 70]))) return "application/pdf";
|
|
258
|
+
}
|
|
259
|
+
if (filename) {
|
|
260
|
+
const ext = filename.split(".").pop()?.toLowerCase();
|
|
261
|
+
const mimeTypes = {
|
|
262
|
+
jpg: "image/jpeg",
|
|
263
|
+
jpeg: "image/jpeg",
|
|
264
|
+
png: "image/png",
|
|
265
|
+
gif: "image/gif",
|
|
266
|
+
pdf: "application/pdf",
|
|
267
|
+
txt: "text/plain",
|
|
268
|
+
json: "application/json",
|
|
269
|
+
xml: "text/xml",
|
|
270
|
+
html: "text/html",
|
|
271
|
+
css: "text/css",
|
|
272
|
+
js: "text/javascript",
|
|
273
|
+
md: "text/markdown",
|
|
274
|
+
mp3: "audio/mpeg",
|
|
275
|
+
mp4: "video/mp4",
|
|
276
|
+
wav: "audio/wav"
|
|
277
|
+
};
|
|
278
|
+
if (ext && mimeTypes[ext]) return mimeTypes[ext];
|
|
279
|
+
}
|
|
280
|
+
if (this.isTextBuffer(buffer)) {
|
|
281
|
+
return "text/plain";
|
|
282
|
+
}
|
|
283
|
+
return "application/octet-stream";
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Check if buffer contains text content.
|
|
287
|
+
* Copied from LocalBlobStore.
|
|
288
|
+
*/
|
|
289
|
+
isTextBuffer(buffer) {
|
|
290
|
+
let printableCount = 0;
|
|
291
|
+
const sampleSize = Math.min(512, buffer.length);
|
|
292
|
+
for (let i = 0; i < sampleSize; i++) {
|
|
293
|
+
const byte = buffer[i];
|
|
294
|
+
if (byte !== void 0 && (byte >= 32 && byte <= 126 || byte === 9 || byte === 10 || byte === 13)) {
|
|
295
|
+
printableCount++;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return printableCount / sampleSize > 0.7;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
export {
|
|
302
|
+
MemoryBlobStore
|
|
303
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var schemas_exports = {};
|
|
20
|
+
__export(schemas_exports, {
|
|
21
|
+
BLOB_STORE_TYPES: () => BLOB_STORE_TYPES,
|
|
22
|
+
BlobStoreConfigSchema: () => BlobStoreConfigSchema,
|
|
23
|
+
InMemoryBlobStoreSchema: () => InMemoryBlobStoreSchema,
|
|
24
|
+
LocalBlobStoreSchema: () => LocalBlobStoreSchema
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(schemas_exports);
|
|
27
|
+
var import_zod = require("zod");
|
|
28
|
+
const BLOB_STORE_TYPES = ["in-memory", "local"];
|
|
29
|
+
const InMemoryBlobStoreSchema = import_zod.z.object({
|
|
30
|
+
type: import_zod.z.literal("in-memory").describe("Blob store type identifier"),
|
|
31
|
+
maxBlobSize: import_zod.z.number().int().positive().optional().default(10 * 1024 * 1024).describe("Maximum size per blob in bytes"),
|
|
32
|
+
maxTotalSize: import_zod.z.number().int().positive().optional().default(100 * 1024 * 1024).describe("Maximum total storage size in bytes")
|
|
33
|
+
}).strict();
|
|
34
|
+
const LocalBlobStoreSchema = import_zod.z.object({
|
|
35
|
+
type: import_zod.z.literal("local").describe("Blob store type identifier"),
|
|
36
|
+
storePath: import_zod.z.string().describe(
|
|
37
|
+
"Blob storage directory path (required for local storage - CLI enrichment provides per-agent default)"
|
|
38
|
+
),
|
|
39
|
+
maxBlobSize: import_zod.z.number().int().positive().optional().default(50 * 1024 * 1024).describe("Maximum size per blob in bytes"),
|
|
40
|
+
maxTotalSize: import_zod.z.number().int().positive().optional().default(1024 * 1024 * 1024).describe("Maximum total storage size in bytes"),
|
|
41
|
+
cleanupAfterDays: import_zod.z.number().int().positive().optional().default(30).describe("Auto-cleanup blobs older than N days")
|
|
42
|
+
}).strict();
|
|
43
|
+
const BlobStoreConfigSchema = import_zod.z.object({
|
|
44
|
+
type: import_zod.z.string().describe("Blob store backend type")
|
|
45
|
+
}).passthrough().describe("Blob store configuration (validated by image factory)");
|
|
46
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
+
0 && (module.exports = {
|
|
48
|
+
BLOB_STORE_TYPES,
|
|
49
|
+
BlobStoreConfigSchema,
|
|
50
|
+
InMemoryBlobStoreSchema,
|
|
51
|
+
LocalBlobStoreSchema
|
|
52
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Built-in blob store types shipped by `@dexto/storage`.
|
|
5
|
+
* Custom backends shipped via images are not included in this list.
|
|
6
|
+
*/
|
|
7
|
+
declare const BLOB_STORE_TYPES: readonly ["in-memory", "local"];
|
|
8
|
+
type BlobStoreType = (typeof BLOB_STORE_TYPES)[number];
|
|
9
|
+
/**
|
|
10
|
+
* In-memory blob store configuration
|
|
11
|
+
*/
|
|
12
|
+
declare const InMemoryBlobStoreSchema: z.ZodObject<{
|
|
13
|
+
type: z.ZodLiteral<"in-memory">;
|
|
14
|
+
maxBlobSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
15
|
+
maxTotalSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
16
|
+
}, "strict", z.ZodTypeAny, {
|
|
17
|
+
type: "in-memory";
|
|
18
|
+
maxBlobSize: number;
|
|
19
|
+
maxTotalSize: number;
|
|
20
|
+
}, {
|
|
21
|
+
type: "in-memory";
|
|
22
|
+
maxBlobSize?: number | undefined;
|
|
23
|
+
maxTotalSize?: number | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
type InMemoryBlobStoreConfigInput = z.input<typeof InMemoryBlobStoreSchema>;
|
|
26
|
+
type InMemoryBlobStoreConfig = z.output<typeof InMemoryBlobStoreSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Local filesystem blob store configuration
|
|
29
|
+
*/
|
|
30
|
+
declare const LocalBlobStoreSchema: z.ZodObject<{
|
|
31
|
+
type: z.ZodLiteral<"local">;
|
|
32
|
+
storePath: z.ZodString;
|
|
33
|
+
maxBlobSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
34
|
+
maxTotalSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
35
|
+
cleanupAfterDays: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
36
|
+
}, "strict", z.ZodTypeAny, {
|
|
37
|
+
type: "local";
|
|
38
|
+
maxBlobSize: number;
|
|
39
|
+
maxTotalSize: number;
|
|
40
|
+
storePath: string;
|
|
41
|
+
cleanupAfterDays: number;
|
|
42
|
+
}, {
|
|
43
|
+
type: "local";
|
|
44
|
+
storePath: string;
|
|
45
|
+
maxBlobSize?: number | undefined;
|
|
46
|
+
maxTotalSize?: number | undefined;
|
|
47
|
+
cleanupAfterDays?: number | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
type LocalBlobStoreConfigInput = z.input<typeof LocalBlobStoreSchema>;
|
|
50
|
+
type LocalBlobStoreConfig = z.output<typeof LocalBlobStoreSchema>;
|
|
51
|
+
/**
|
|
52
|
+
* Blob store configuration schema.
|
|
53
|
+
*
|
|
54
|
+
* This schema uses `.passthrough()` to accept any backend-specific configuration.
|
|
55
|
+
* It only validates that a `type` field exists as a string.
|
|
56
|
+
*
|
|
57
|
+
* Detailed validation happens in the product-layer resolver (`@dexto/agent-config`) via
|
|
58
|
+
* each image factory's `configSchema`. Built-in backends are validated by their factory schemas.
|
|
59
|
+
*
|
|
60
|
+
* This approach allows:
|
|
61
|
+
* - Custom backends to be provided by a custom image
|
|
62
|
+
* - Each backend to define its own configuration structure and strict schema
|
|
63
|
+
*
|
|
64
|
+
* Example flow:
|
|
65
|
+
* 1. Config passes this schema (basic structure check)
|
|
66
|
+
* 2. Product layer resolves backend via image + validates against factory schema
|
|
67
|
+
* 3. Core receives a concrete `BlobStore` instance (DI)
|
|
68
|
+
*/
|
|
69
|
+
declare const BlobStoreConfigSchema: z.ZodObject<{
|
|
70
|
+
type: z.ZodString;
|
|
71
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
72
|
+
type: z.ZodString;
|
|
73
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
74
|
+
type: z.ZodString;
|
|
75
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
76
|
+
/**
|
|
77
|
+
* Blob store configuration type.
|
|
78
|
+
*
|
|
79
|
+
* Union type including built-in backends (local, in-memory) and a catch-all
|
|
80
|
+
* for custom backends provided via images at runtime.
|
|
81
|
+
*/
|
|
82
|
+
type BlobStoreConfig = InMemoryBlobStoreConfig | LocalBlobStoreConfig | {
|
|
83
|
+
type: string;
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export { BLOB_STORE_TYPES, type BlobStoreConfig, BlobStoreConfigSchema, type BlobStoreType, type InMemoryBlobStoreConfig, type InMemoryBlobStoreConfigInput, InMemoryBlobStoreSchema, type LocalBlobStoreConfig, type LocalBlobStoreConfigInput, LocalBlobStoreSchema };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in blob store types shipped by `@dexto/storage`.
|
|
4
|
+
* Custom backends shipped via images are not included in this list.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BLOB_STORE_TYPES: readonly ["in-memory", "local"];
|
|
7
|
+
export type BlobStoreType = (typeof BLOB_STORE_TYPES)[number];
|
|
8
|
+
/**
|
|
9
|
+
* In-memory blob store configuration
|
|
10
|
+
*/
|
|
11
|
+
declare const InMemoryBlobStoreSchema: z.ZodObject<{
|
|
12
|
+
type: z.ZodLiteral<"in-memory">;
|
|
13
|
+
maxBlobSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
14
|
+
maxTotalSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
15
|
+
}, "strict", z.ZodTypeAny, {
|
|
16
|
+
type: "in-memory";
|
|
17
|
+
maxBlobSize: number;
|
|
18
|
+
maxTotalSize: number;
|
|
19
|
+
}, {
|
|
20
|
+
type: "in-memory";
|
|
21
|
+
maxBlobSize?: number | undefined;
|
|
22
|
+
maxTotalSize?: number | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
export type InMemoryBlobStoreConfigInput = z.input<typeof InMemoryBlobStoreSchema>;
|
|
25
|
+
export type InMemoryBlobStoreConfig = z.output<typeof InMemoryBlobStoreSchema>;
|
|
26
|
+
/**
|
|
27
|
+
* Local filesystem blob store configuration
|
|
28
|
+
*/
|
|
29
|
+
declare const LocalBlobStoreSchema: z.ZodObject<{
|
|
30
|
+
type: z.ZodLiteral<"local">;
|
|
31
|
+
storePath: z.ZodString;
|
|
32
|
+
maxBlobSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
33
|
+
maxTotalSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
34
|
+
cleanupAfterDays: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
35
|
+
}, "strict", z.ZodTypeAny, {
|
|
36
|
+
type: "local";
|
|
37
|
+
maxBlobSize: number;
|
|
38
|
+
maxTotalSize: number;
|
|
39
|
+
storePath: string;
|
|
40
|
+
cleanupAfterDays: number;
|
|
41
|
+
}, {
|
|
42
|
+
type: "local";
|
|
43
|
+
storePath: string;
|
|
44
|
+
maxBlobSize?: number | undefined;
|
|
45
|
+
maxTotalSize?: number | undefined;
|
|
46
|
+
cleanupAfterDays?: number | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
export type LocalBlobStoreConfigInput = z.input<typeof LocalBlobStoreSchema>;
|
|
49
|
+
export type LocalBlobStoreConfig = z.output<typeof LocalBlobStoreSchema>;
|
|
50
|
+
/**
|
|
51
|
+
* Blob store configuration schema.
|
|
52
|
+
*
|
|
53
|
+
* This schema uses `.passthrough()` to accept any backend-specific configuration.
|
|
54
|
+
* It only validates that a `type` field exists as a string.
|
|
55
|
+
*
|
|
56
|
+
* Detailed validation happens in the product-layer resolver (`@dexto/agent-config`) via
|
|
57
|
+
* each image factory's `configSchema`. Built-in backends are validated by their factory schemas.
|
|
58
|
+
*
|
|
59
|
+
* This approach allows:
|
|
60
|
+
* - Custom backends to be provided by a custom image
|
|
61
|
+
* - Each backend to define its own configuration structure and strict schema
|
|
62
|
+
*
|
|
63
|
+
* Example flow:
|
|
64
|
+
* 1. Config passes this schema (basic structure check)
|
|
65
|
+
* 2. Product layer resolves backend via image + validates against factory schema
|
|
66
|
+
* 3. Core receives a concrete `BlobStore` instance (DI)
|
|
67
|
+
*/
|
|
68
|
+
export declare const BlobStoreConfigSchema: z.ZodObject<{
|
|
69
|
+
type: z.ZodString;
|
|
70
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
71
|
+
type: z.ZodString;
|
|
72
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
73
|
+
type: z.ZodString;
|
|
74
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
75
|
+
/**
|
|
76
|
+
* Blob store configuration type.
|
|
77
|
+
*
|
|
78
|
+
* Union type including built-in backends (local, in-memory) and a catch-all
|
|
79
|
+
* for custom backends provided via images at runtime.
|
|
80
|
+
*/
|
|
81
|
+
export type BlobStoreConfig = InMemoryBlobStoreConfig | LocalBlobStoreConfig | {
|
|
82
|
+
type: string;
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
};
|
|
85
|
+
export { InMemoryBlobStoreSchema, LocalBlobStoreSchema };
|
|
86
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/blob/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,gBAAgB,iCAAkC,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D;;GAEG;AACH,QAAA,MAAM,uBAAuB;;;;;;;;;;;;EAkBhB,CAAC;AAEd,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACnF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE/E;;GAEG;AACH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;EA8Bb,CAAC;AAEd,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC7E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB;;;;;;gCAKoC,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACrB,uBAAuB,GACvB,oBAAoB,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAG/C,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const BLOB_STORE_TYPES = ["in-memory", "local"];
|
|
3
|
+
const InMemoryBlobStoreSchema = z.object({
|
|
4
|
+
type: z.literal("in-memory").describe("Blob store type identifier"),
|
|
5
|
+
maxBlobSize: z.number().int().positive().optional().default(10 * 1024 * 1024).describe("Maximum size per blob in bytes"),
|
|
6
|
+
maxTotalSize: z.number().int().positive().optional().default(100 * 1024 * 1024).describe("Maximum total storage size in bytes")
|
|
7
|
+
}).strict();
|
|
8
|
+
const LocalBlobStoreSchema = z.object({
|
|
9
|
+
type: z.literal("local").describe("Blob store type identifier"),
|
|
10
|
+
storePath: z.string().describe(
|
|
11
|
+
"Blob storage directory path (required for local storage - CLI enrichment provides per-agent default)"
|
|
12
|
+
),
|
|
13
|
+
maxBlobSize: z.number().int().positive().optional().default(50 * 1024 * 1024).describe("Maximum size per blob in bytes"),
|
|
14
|
+
maxTotalSize: z.number().int().positive().optional().default(1024 * 1024 * 1024).describe("Maximum total storage size in bytes"),
|
|
15
|
+
cleanupAfterDays: z.number().int().positive().optional().default(30).describe("Auto-cleanup blobs older than N days")
|
|
16
|
+
}).strict();
|
|
17
|
+
const BlobStoreConfigSchema = z.object({
|
|
18
|
+
type: z.string().describe("Blob store backend type")
|
|
19
|
+
}).passthrough().describe("Blob store configuration (validated by image factory)");
|
|
20
|
+
export {
|
|
21
|
+
BLOB_STORE_TYPES,
|
|
22
|
+
BlobStoreConfigSchema,
|
|
23
|
+
InMemoryBlobStoreSchema,
|
|
24
|
+
LocalBlobStoreSchema
|
|
25
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BlobData, BlobInput, BlobMetadata, BlobReference, BlobStats, BlobStore, StoredBlobMetadata } from '@dexto/core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/blob/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,SAAS,GACZ,MAAM,aAAa,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var factories_exports = {};
|
|
20
|
+
__export(factories_exports, {
|
|
21
|
+
inMemoryCacheFactory: () => import_memory.inMemoryCacheFactory,
|
|
22
|
+
redisCacheFactory: () => import_redis.redisCacheFactory
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(factories_exports);
|
|
25
|
+
var import_memory = require("./memory.js");
|
|
26
|
+
var import_redis = require("./redis.js");
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
inMemoryCacheFactory,
|
|
30
|
+
redisCacheFactory
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/factories/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|