@ultrst-armada/kloks 1.6.0 → 1.7.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/.krusbl-release-attestation.json +3 -3
- package/package.json +1 -1
- package/packages/backend/dist/{BaseStorageAdapter-tosOoSUg.d.ts → BaseStorageAdapter-6x_BQiB3.d.ts} +6 -1
- package/packages/backend/dist/{chunk-OZDYAEH4.js → chunk-3IUA66RS.js} +219 -3
- package/packages/backend/dist/{chunk-E72GXBXF.js → chunk-6K75XXFD.js} +9 -200
- package/packages/backend/dist/{chunk-GPXV4GBD.js → chunk-6W7OAGNV.js} +59 -75
- package/packages/backend/dist/{chunk-GQUNN7SA.js → chunk-7ZT2ZPPH.js} +7 -5
- package/packages/backend/dist/{chunk-DBZVGMJ7.js → chunk-F6IDQLC2.js} +2 -2
- package/packages/backend/dist/chunk-JUPWFW7V.js +134 -0
- package/packages/backend/dist/{chunk-J2J24JVC.js → chunk-R45CEV46.js} +210 -153
- package/packages/backend/dist/{chunk-3HZYAZF4.js → chunk-SQGBAWZN.js} +97 -7
- package/packages/backend/dist/chunk-VAFCR2MS.js +203 -0
- package/packages/backend/dist/{chunk-VDROUXFT.js → chunk-XHADDA75.js} +19 -13
- package/packages/backend/dist/development/index.d.ts +54 -1
- package/packages/backend/dist/development/index.js +7 -1
- package/packages/backend/dist/index.d.ts +5 -5
- package/packages/backend/dist/index.js +38 -211
- package/packages/backend/dist/krnl-services.js +6 -5
- package/packages/backend/dist/services/index.js +4 -3
- package/packages/backend/dist/srkl/index.d.ts +55 -2
- package/packages/backend/dist/srkl/index.js +3 -2
- package/packages/backend/dist/storage/index.d.ts +35 -3
- package/packages/backend/dist/storage/index.js +12 -3
- package/packages/backend/dist/workspace/index.d.ts +27 -33
- package/packages/backend/dist/workspace/index.js +3 -2
- package/packages/backend/kloks.manifest.json +25 -0
- package/packages/client/dist/index.d.ts +34 -1
- package/packages/client/dist/index.js +116 -0
- package/packages/backend/dist/chunk-LS3HWJBX.js +0 -0
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
-
b2DownloadFile,
|
|
3
|
-
b2ListFileNames,
|
|
4
|
-
b2UploadFile,
|
|
5
2
|
createWorkspace,
|
|
6
3
|
deleteWorkspace,
|
|
7
|
-
deleteWorkspaceFile,
|
|
8
4
|
findUserWorkspace,
|
|
9
5
|
getWorkspaces,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
updateWorkspace
|
|
7
|
+
} from "./chunk-6K75XXFD.js";
|
|
8
|
+
import {
|
|
9
|
+
b2DownloadFile,
|
|
10
|
+
b2ListFileNames,
|
|
11
|
+
b2UploadFile,
|
|
12
|
+
queryUnifiedDb
|
|
13
|
+
} from "./chunk-VAFCR2MS.js";
|
|
16
14
|
|
|
17
15
|
// src/workspace/WorkspaceFS.ts
|
|
18
16
|
import { SkipoBase } from "@ultrst-armada/kloks/functions";
|
|
@@ -133,58 +131,6 @@ var WorkspaceCloneSyncEngine = class extends SkipoBase3 {
|
|
|
133
131
|
}
|
|
134
132
|
};
|
|
135
133
|
|
|
136
|
-
// src/workspace/RemoteWorkspaceService.ts
|
|
137
|
-
var RemoteWorkspaceService = class {
|
|
138
|
-
type = "remote";
|
|
139
|
-
async findWorkspace(workspaceId, env) {
|
|
140
|
-
return await findUserWorkspace(workspaceId, env);
|
|
141
|
-
}
|
|
142
|
-
async listWorkspaces(userId, env) {
|
|
143
|
-
return await getWorkspaces(userId, env);
|
|
144
|
-
}
|
|
145
|
-
async createWorkspace(userId, data, env) {
|
|
146
|
-
return await createWorkspace(userId, data, env);
|
|
147
|
-
}
|
|
148
|
-
async updateWorkspace(userId, params, env) {
|
|
149
|
-
return await updateWorkspace(userId, params, env);
|
|
150
|
-
}
|
|
151
|
-
async deleteWorkspace(userId, workspaceId, env) {
|
|
152
|
-
return await deleteWorkspace(userId, workspaceId, env);
|
|
153
|
-
}
|
|
154
|
-
async readFile(workspaceId, filePath, env) {
|
|
155
|
-
const { workspace, connection } = await this.findWorkspace(workspaceId, env);
|
|
156
|
-
if (!workspace) throw new Error(`Workspace "${workspaceId}" not found.`);
|
|
157
|
-
const data = await readWorkspaceFile(workspace, connection, filePath);
|
|
158
|
-
if (!data) throw new Error(`File "${filePath}" not found in workspace "${workspaceId}".`);
|
|
159
|
-
return data;
|
|
160
|
-
}
|
|
161
|
-
async writeFile(workspaceId, filePath, content, env) {
|
|
162
|
-
const { workspace, connection } = await this.findWorkspace(workspaceId, env);
|
|
163
|
-
if (!workspace) throw new Error(`Workspace "${workspaceId}" not found.`);
|
|
164
|
-
await writeWorkspaceFile(workspace, connection, filePath, content);
|
|
165
|
-
const size = typeof content === "string" ? new TextEncoder().encode(content).length : content.byteLength;
|
|
166
|
-
return { success: true, path: filePath, sizeBytes: size };
|
|
167
|
-
}
|
|
168
|
-
async deleteFile(workspaceId, filePath, env) {
|
|
169
|
-
const { workspace, connection } = await this.findWorkspace(workspaceId, env);
|
|
170
|
-
if (!workspace) throw new Error(`Workspace "${workspaceId}" not found.`);
|
|
171
|
-
const deleted = await deleteWorkspaceFile(workspace, connection, filePath);
|
|
172
|
-
return { success: deleted };
|
|
173
|
-
}
|
|
174
|
-
async listFiles(workspaceId, subfolder = "", env) {
|
|
175
|
-
const { workspace, connection } = await this.findWorkspace(workspaceId, env);
|
|
176
|
-
if (!workspace) throw new Error(`Workspace "${workspaceId}" not found.`);
|
|
177
|
-
const files = await listWorkspaceFiles(workspace, connection, subfolder);
|
|
178
|
-
return files.map((f) => ({
|
|
179
|
-
path: f.fileName,
|
|
180
|
-
name: f.fileName.split("/").pop() || f.fileName,
|
|
181
|
-
sizeBytes: f.sizeBytes,
|
|
182
|
-
updatedAt: f.uploadTimestamp
|
|
183
|
-
}));
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
var remoteWorkspaceService = new RemoteWorkspaceService();
|
|
187
|
-
|
|
188
134
|
// src/workspace/WorkingWorkspaceService.ts
|
|
189
135
|
import fs2 from "fs";
|
|
190
136
|
import path2 from "path";
|
|
@@ -243,8 +189,10 @@ function setWorkingWorkspaceConfig(cfg) {
|
|
|
243
189
|
}
|
|
244
190
|
return updated;
|
|
245
191
|
}
|
|
246
|
-
function getWorkingWorkspaceDir() {
|
|
247
|
-
const
|
|
192
|
+
function getWorkingWorkspaceDir(workspaceId = "default") {
|
|
193
|
+
const root = getWorkingWorkspaceConfig().workingDirectory;
|
|
194
|
+
const safeId = workspaceId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
195
|
+
const dir = path.join(root, safeId);
|
|
248
196
|
if (!fs.existsSync(dir)) {
|
|
249
197
|
fs.mkdirSync(dir, { recursive: true });
|
|
250
198
|
}
|
|
@@ -329,7 +277,7 @@ async function syncWorkspace(workspaceId) {
|
|
|
329
277
|
}
|
|
330
278
|
const { workspace, user, connection } = match;
|
|
331
279
|
const folderKey = getWorkspaceFolderKey(workspace, user);
|
|
332
|
-
const workingDir = getWorkingWorkspaceDir();
|
|
280
|
+
const workingDir = getWorkingWorkspaceDir(workspaceId);
|
|
333
281
|
const isB2 = workspace.storageProvider === "backblaze_b2" || workspace.storageConfig?.type === "b2";
|
|
334
282
|
const syncedFiles = [];
|
|
335
283
|
let uploadedCount = 0;
|
|
@@ -503,8 +451,8 @@ var WorkingWorkspaceService = class {
|
|
|
503
451
|
}
|
|
504
452
|
workingDirResolver;
|
|
505
453
|
type = "working";
|
|
506
|
-
getWorkingDir() {
|
|
507
|
-
return this.workingDirResolver ? this.workingDirResolver() : getWorkingWorkspaceDir();
|
|
454
|
+
getWorkingDir(workspaceId) {
|
|
455
|
+
return this.workingDirResolver ? this.workingDirResolver(workspaceId) : getWorkingWorkspaceDir(workspaceId);
|
|
508
456
|
}
|
|
509
457
|
async findWorkspace(workspaceId, env) {
|
|
510
458
|
return await findUserWorkspace(workspaceId, env);
|
|
@@ -514,7 +462,7 @@ var WorkingWorkspaceService = class {
|
|
|
514
462
|
}
|
|
515
463
|
async createWorkspace(userId, data, env) {
|
|
516
464
|
const res = await createWorkspace(userId, data, env);
|
|
517
|
-
const dir = this.getWorkingDir();
|
|
465
|
+
const dir = this.getWorkingDir(res.workspace?.id || data?.id || "default");
|
|
518
466
|
try {
|
|
519
467
|
await fs2.promises.mkdir(dir, { recursive: true });
|
|
520
468
|
} catch {
|
|
@@ -529,12 +477,12 @@ var WorkingWorkspaceService = class {
|
|
|
529
477
|
}
|
|
530
478
|
async readFile(_workspaceId, filePath) {
|
|
531
479
|
const cleanRel = filePath.replace(/^\/+/, "");
|
|
532
|
-
const fullPath = path2.resolve(this.getWorkingDir(), cleanRel);
|
|
480
|
+
const fullPath = path2.resolve(this.getWorkingDir(_workspaceId), cleanRel);
|
|
533
481
|
return await fs2.promises.readFile(fullPath);
|
|
534
482
|
}
|
|
535
483
|
async writeFile(_workspaceId, filePath, content) {
|
|
536
484
|
const cleanRel = filePath.replace(/^\/+/, "");
|
|
537
|
-
const fullPath = path2.resolve(this.getWorkingDir(), cleanRel);
|
|
485
|
+
const fullPath = path2.resolve(this.getWorkingDir(_workspaceId), cleanRel);
|
|
538
486
|
await fs2.promises.mkdir(path2.dirname(fullPath), { recursive: true });
|
|
539
487
|
const buffer = typeof content === "string" ? Buffer.from(content) : Buffer.from(content.buffer, content.byteOffset, content.byteLength);
|
|
540
488
|
await fs2.promises.writeFile(fullPath, buffer);
|
|
@@ -551,7 +499,7 @@ var WorkingWorkspaceService = class {
|
|
|
551
499
|
}
|
|
552
500
|
}
|
|
553
501
|
async listFiles(_workspaceId, subfolder = "") {
|
|
554
|
-
const baseDir = path2.resolve(this.getWorkingDir(), subfolder.replace(/^\/+/, ""));
|
|
502
|
+
const baseDir = path2.resolve(this.getWorkingDir(_workspaceId), subfolder.replace(/^\/+/, ""));
|
|
555
503
|
if (!fs2.existsSync(baseDir)) return [];
|
|
556
504
|
const entries = await fs2.promises.readdir(baseDir, { withFileTypes: true });
|
|
557
505
|
return entries.map((e) => {
|
|
@@ -565,7 +513,7 @@ var WorkingWorkspaceService = class {
|
|
|
565
513
|
} catch {
|
|
566
514
|
}
|
|
567
515
|
return {
|
|
568
|
-
path: path2.relative(this.getWorkingDir(), full),
|
|
516
|
+
path: path2.relative(this.getWorkingDir(_workspaceId), full),
|
|
569
517
|
name: e.name,
|
|
570
518
|
isFolder: e.isDirectory(),
|
|
571
519
|
sizeBytes,
|
|
@@ -579,12 +527,46 @@ var WorkingWorkspaceService = class {
|
|
|
579
527
|
};
|
|
580
528
|
var workingWorkspaceService = new WorkingWorkspaceService();
|
|
581
529
|
|
|
530
|
+
// src/workspace/RemoteWorkspaceService.ts
|
|
531
|
+
var RemoteWorkspaceService = class {
|
|
532
|
+
type = "working";
|
|
533
|
+
findWorkspace(id, env) {
|
|
534
|
+
return workingWorkspaceService.findWorkspace(id, env);
|
|
535
|
+
}
|
|
536
|
+
listWorkspaces(userId, env) {
|
|
537
|
+
return workingWorkspaceService.listWorkspaces(userId, env);
|
|
538
|
+
}
|
|
539
|
+
createWorkspace(userId, data, env) {
|
|
540
|
+
return workingWorkspaceService.createWorkspace(userId, data, env);
|
|
541
|
+
}
|
|
542
|
+
updateWorkspace(userId, params, env) {
|
|
543
|
+
return workingWorkspaceService.updateWorkspace(userId, params, env);
|
|
544
|
+
}
|
|
545
|
+
deleteWorkspace(userId, id, env) {
|
|
546
|
+
return workingWorkspaceService.deleteWorkspace(userId, id, env);
|
|
547
|
+
}
|
|
548
|
+
readFile(id, path3, env) {
|
|
549
|
+
return workingWorkspaceService.readFile(id, path3);
|
|
550
|
+
}
|
|
551
|
+
writeFile(id, path3, content, env) {
|
|
552
|
+
return workingWorkspaceService.writeFile(id, path3, content);
|
|
553
|
+
}
|
|
554
|
+
deleteFile(id, path3, env) {
|
|
555
|
+
return workingWorkspaceService.deleteFile(id, path3);
|
|
556
|
+
}
|
|
557
|
+
listFiles(id, subfolder, env) {
|
|
558
|
+
return workingWorkspaceService.listFiles(id, subfolder);
|
|
559
|
+
}
|
|
560
|
+
sync(id, options, env) {
|
|
561
|
+
return workingWorkspaceService.sync(id, options);
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
var remoteWorkspaceService = workingWorkspaceService;
|
|
565
|
+
|
|
582
566
|
export {
|
|
583
567
|
WorkspaceFS,
|
|
584
568
|
SyncEngine,
|
|
585
569
|
WorkspaceCloneSyncEngine,
|
|
586
|
-
RemoteWorkspaceService,
|
|
587
|
-
remoteWorkspaceService,
|
|
588
570
|
getDefaultWorkingWorkspaceDir,
|
|
589
571
|
getWorkingWorkspaceConfig,
|
|
590
572
|
setWorkingWorkspaceConfig,
|
|
@@ -593,5 +575,7 @@ export {
|
|
|
593
575
|
getWorkspaceFolderKey,
|
|
594
576
|
syncWorkspace,
|
|
595
577
|
WorkingWorkspaceService,
|
|
596
|
-
workingWorkspaceService
|
|
578
|
+
workingWorkspaceService,
|
|
579
|
+
RemoteWorkspaceService,
|
|
580
|
+
remoteWorkspaceService
|
|
597
581
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
workspaceGraphService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-F6IDQLC2.js";
|
|
4
4
|
import {
|
|
5
5
|
getSrklAccounts,
|
|
6
6
|
srklListBackblazeBuckets
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-XHADDA75.js";
|
|
8
8
|
import {
|
|
9
9
|
StorageAdapterFactory
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-R45CEV46.js";
|
|
11
11
|
import {
|
|
12
12
|
b2ListBuckets
|
|
13
13
|
} from "./chunk-4QEMALXF.js";
|
|
@@ -20,9 +20,11 @@ import {
|
|
|
20
20
|
deleteWorkspace,
|
|
21
21
|
findUserWorkspace,
|
|
22
22
|
getWorkspaces,
|
|
23
|
-
queryUnifiedDb,
|
|
24
23
|
updateWorkspace
|
|
25
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-6K75XXFD.js";
|
|
25
|
+
import {
|
|
26
|
+
queryUnifiedDb
|
|
27
|
+
} from "./chunk-VAFCR2MS.js";
|
|
26
28
|
import {
|
|
27
29
|
RateLimiter,
|
|
28
30
|
SessionManager,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StorageAdapterFactory
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-R45CEV46.js";
|
|
4
4
|
import {
|
|
5
5
|
findUserWorkspace
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6K75XXFD.js";
|
|
7
7
|
|
|
8
8
|
// src/services/workspaceGraphService.ts
|
|
9
9
|
function slugify(name) {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseStorageAdapter,
|
|
3
|
+
ensureS3DirectoryMarker,
|
|
4
|
+
permanentDeleteS3Folder,
|
|
5
|
+
permanentDeleteS3Object,
|
|
6
|
+
renameS3Folder
|
|
7
|
+
} from "./chunk-R45CEV46.js";
|
|
8
|
+
|
|
9
|
+
// src/storage/S3Adapter.ts
|
|
10
|
+
var S3Client;
|
|
11
|
+
var PutObjectCommand;
|
|
12
|
+
var GetObjectCommand;
|
|
13
|
+
var ListObjectsV2Command;
|
|
14
|
+
var HeadObjectCommand;
|
|
15
|
+
var S3Adapter = class extends BaseStorageAdapter {
|
|
16
|
+
client;
|
|
17
|
+
bucket;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
super(config);
|
|
20
|
+
this.bucket = config.bucket || "";
|
|
21
|
+
}
|
|
22
|
+
async ensureClient() {
|
|
23
|
+
if (this.client) return;
|
|
24
|
+
try {
|
|
25
|
+
const aws = await import("@aws-sdk/client-s3");
|
|
26
|
+
S3Client = aws.S3Client;
|
|
27
|
+
PutObjectCommand = aws.PutObjectCommand;
|
|
28
|
+
GetObjectCommand = aws.GetObjectCommand;
|
|
29
|
+
ListObjectsV2Command = aws.ListObjectsV2Command;
|
|
30
|
+
HeadObjectCommand = aws.HeadObjectCommand;
|
|
31
|
+
this.client = new S3Client({
|
|
32
|
+
region: this.config.region || "us-east-1",
|
|
33
|
+
endpoint: this.config.endpoint,
|
|
34
|
+
credentials: {
|
|
35
|
+
accessKeyId: this.config.accessKey,
|
|
36
|
+
secretAccessKey: this.config.secretKey
|
|
37
|
+
},
|
|
38
|
+
forcePathStyle: Boolean(this.config.endpoint)
|
|
39
|
+
});
|
|
40
|
+
} catch (e) {
|
|
41
|
+
throw new Error(`@aws-sdk/client-s3 failed to initialize: ${e.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async read(pathStr) {
|
|
45
|
+
await this.ensureClient();
|
|
46
|
+
const command = new GetObjectCommand({ Bucket: this.bucket, Key: this.normalizePath(pathStr) });
|
|
47
|
+
const response = await this.client.send(command);
|
|
48
|
+
return response.Body ? await response.Body.transformToByteArray() : new Uint8Array();
|
|
49
|
+
}
|
|
50
|
+
async write(pathStr, data, contentType = "application/octet-stream") {
|
|
51
|
+
await this.ensureClient();
|
|
52
|
+
const body = typeof data === "string" ? Buffer.from(data, "utf-8") : Buffer.from(data);
|
|
53
|
+
const command = new PutObjectCommand({
|
|
54
|
+
Bucket: this.bucket,
|
|
55
|
+
Key: this.normalizePath(pathStr),
|
|
56
|
+
Body: body,
|
|
57
|
+
ContentType: contentType
|
|
58
|
+
});
|
|
59
|
+
await this.client.send(command);
|
|
60
|
+
}
|
|
61
|
+
async delete(pathStr) {
|
|
62
|
+
await this.ensureClient();
|
|
63
|
+
await permanentDeleteS3Object(this.client, this.bucket, this.normalizePath(pathStr));
|
|
64
|
+
}
|
|
65
|
+
async deleteFolder(pathStr) {
|
|
66
|
+
await this.ensureClient();
|
|
67
|
+
return await permanentDeleteS3Folder(this.client, this.bucket, this.normalizePath(pathStr));
|
|
68
|
+
}
|
|
69
|
+
async renameFolder(oldPath, newPath) {
|
|
70
|
+
await this.ensureClient();
|
|
71
|
+
return await renameS3Folder(this.client, this.bucket, this.normalizePath(oldPath), this.normalizePath(newPath));
|
|
72
|
+
}
|
|
73
|
+
async ensureDirectory(pathStr) {
|
|
74
|
+
await this.ensureClient();
|
|
75
|
+
await ensureS3DirectoryMarker(this.client, this.bucket, this.normalizePath(pathStr));
|
|
76
|
+
}
|
|
77
|
+
async exists(pathStr) {
|
|
78
|
+
await this.ensureClient();
|
|
79
|
+
try {
|
|
80
|
+
const command = new HeadObjectCommand({ Bucket: this.bucket, Key: this.normalizePath(pathStr) });
|
|
81
|
+
await this.client.send(command);
|
|
82
|
+
return true;
|
|
83
|
+
} catch (e) {
|
|
84
|
+
if (e.name === "NotFound" || e.$metadata?.httpStatusCode === 404) return false;
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async list(pathStr = "") {
|
|
89
|
+
await this.ensureClient();
|
|
90
|
+
const prefix = pathStr ? this.normalizePath(pathStr).replace(/\/+$/, "") + "/" : "";
|
|
91
|
+
const command = new ListObjectsV2Command({ Bucket: this.bucket, Prefix: prefix });
|
|
92
|
+
const response = await this.client.send(command);
|
|
93
|
+
return (response.Contents || []).map((item) => ({
|
|
94
|
+
path: item.Key,
|
|
95
|
+
size: item.Size || 0,
|
|
96
|
+
modifiedAt: item.LastModified ? item.LastModified.getTime() : 0
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
async stat(pathStr) {
|
|
100
|
+
await this.ensureClient();
|
|
101
|
+
const command = new HeadObjectCommand({ Bucket: this.bucket, Key: this.normalizePath(pathStr) });
|
|
102
|
+
const response = await this.client.send(command);
|
|
103
|
+
return {
|
|
104
|
+
path: pathStr,
|
|
105
|
+
size: response.ContentLength || 0,
|
|
106
|
+
modifiedAt: response.LastModified ? response.LastModified.getTime() : 0
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async mkdir(pathStr) {
|
|
110
|
+
await this.ensureDirectory(pathStr);
|
|
111
|
+
}
|
|
112
|
+
async testConnection() {
|
|
113
|
+
const start = performance.now();
|
|
114
|
+
try {
|
|
115
|
+
await this.ensureClient();
|
|
116
|
+
const res = await this.client.send(new ListObjectsV2Command({ Bucket: this.bucket, MaxKeys: 1 }));
|
|
117
|
+
return {
|
|
118
|
+
ok: true,
|
|
119
|
+
latencyMs: Math.round(performance.now() - start),
|
|
120
|
+
details: { bucket: this.bucket, keyCount: res.KeyCount ?? 0 }
|
|
121
|
+
};
|
|
122
|
+
} catch (e) {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
latencyMs: Math.round(performance.now() - start),
|
|
126
|
+
error: e.message
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
S3Adapter
|
|
134
|
+
};
|