@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.
Files changed (29) hide show
  1. package/.krusbl-release-attestation.json +3 -3
  2. package/package.json +1 -1
  3. package/packages/backend/dist/{BaseStorageAdapter-tosOoSUg.d.ts → BaseStorageAdapter-6x_BQiB3.d.ts} +6 -1
  4. package/packages/backend/dist/{chunk-OZDYAEH4.js → chunk-3IUA66RS.js} +219 -3
  5. package/packages/backend/dist/{chunk-E72GXBXF.js → chunk-6K75XXFD.js} +9 -200
  6. package/packages/backend/dist/{chunk-GPXV4GBD.js → chunk-6W7OAGNV.js} +59 -75
  7. package/packages/backend/dist/{chunk-GQUNN7SA.js → chunk-7ZT2ZPPH.js} +7 -5
  8. package/packages/backend/dist/{chunk-DBZVGMJ7.js → chunk-F6IDQLC2.js} +2 -2
  9. package/packages/backend/dist/chunk-JUPWFW7V.js +134 -0
  10. package/packages/backend/dist/{chunk-J2J24JVC.js → chunk-R45CEV46.js} +210 -153
  11. package/packages/backend/dist/{chunk-3HZYAZF4.js → chunk-SQGBAWZN.js} +97 -7
  12. package/packages/backend/dist/chunk-VAFCR2MS.js +203 -0
  13. package/packages/backend/dist/{chunk-VDROUXFT.js → chunk-XHADDA75.js} +19 -13
  14. package/packages/backend/dist/development/index.d.ts +54 -1
  15. package/packages/backend/dist/development/index.js +7 -1
  16. package/packages/backend/dist/index.d.ts +5 -5
  17. package/packages/backend/dist/index.js +38 -211
  18. package/packages/backend/dist/krnl-services.js +6 -5
  19. package/packages/backend/dist/services/index.js +4 -3
  20. package/packages/backend/dist/srkl/index.d.ts +55 -2
  21. package/packages/backend/dist/srkl/index.js +3 -2
  22. package/packages/backend/dist/storage/index.d.ts +35 -3
  23. package/packages/backend/dist/storage/index.js +12 -3
  24. package/packages/backend/dist/workspace/index.d.ts +27 -33
  25. package/packages/backend/dist/workspace/index.js +3 -2
  26. package/packages/backend/kloks.manifest.json +25 -0
  27. package/packages/client/dist/index.d.ts +34 -1
  28. package/packages/client/dist/index.js +116 -0
  29. package/packages/backend/dist/chunk-LS3HWJBX.js +0 -0
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "packageName": "@ultrst-armada/kloks",
4
- "version": "1.6.0",
5
- "sourceCommit": "a44775f58baed156dbc5590d9d920e6b582f2eee",
4
+ "version": "1.7.1",
5
+ "sourceCommit": "67d641336636d076f15240809b73c0a4f9f438b5",
6
6
  "releaseWorkflow": "npm Release",
7
- "workflowRunId": "39983348775"
7
+ "workflowRunId": "40193283076"
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultrst-armada/kloks",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -1,7 +1,7 @@
1
1
  import { SkipoBase } from '@ultrst-armada/kloks/functions';
2
2
 
3
3
  type StorageMode = 'local' | 'local_hosted' | 'remote';
4
- type StorageProviderType = 'local_fs' | 's3' | 'backblaze_b2' | 'b2' | 'cloudflare_r2' | 'r2' | 'supabase' | 'firebase' | 'google_drive';
4
+ type StorageProviderType = 'local_fs' | 'backblaze_b2' | 'b2' | 'supabase' | 'firebase' | 'google_drive';
5
5
  interface StorageConfig {
6
6
  provider: StorageProviderType;
7
7
  mode?: StorageMode;
@@ -19,6 +19,11 @@ interface StorageConfig {
19
19
  keyId?: string;
20
20
  applicationKey?: string;
21
21
  accountId?: string;
22
+ googleClientId?: string;
23
+ googleRedirectUri?: string;
24
+ googleAccessToken?: string;
25
+ googleRefreshToken?: string;
26
+ googleRootFolderId?: string;
22
27
  }
23
28
  interface FileInfo {
24
29
  path: string;
@@ -1,3 +1,8 @@
1
+ import {
2
+ b2ListBuckets,
3
+ queryUnifiedDb
4
+ } from "./chunk-VAFCR2MS.js";
5
+
1
6
  // src/srkl/SrklClient.ts
2
7
  var CANONICAL_SRKL_URL = "https://srkl-engine.vercel.app";
3
8
  var SrklClient = class {
@@ -116,9 +121,10 @@ var SrklClient = class {
116
121
  const creds = account.credentials || {};
117
122
  const sId = (account.serviceId || "").toLowerCase();
118
123
  const isB2 = sId.includes("backblaze") || sId === "b2";
124
+ const isGoogle = sId.includes("google_drive") || sId.includes("googledrive") || sId === "google";
119
125
  return {
120
126
  id: `conn-srkl-${account.id}`,
121
- provider: isB2 ? "backblaze_b2" : "aws_s3",
127
+ provider: isB2 ? "backblaze_b2" : isGoogle ? "google_drive" : "aws_s3",
122
128
  label: `SRKL: ${account.name || (isB2 ? "Backblaze" : "S3")}`,
123
129
  role: "redundant_clone",
124
130
  enabled: true,
@@ -132,7 +138,13 @@ var SrklClient = class {
132
138
  s3SecretAccessKey: creds.secretAccessKey || creds.applicationKey || creds.s3SecretAccessKey,
133
139
  s3BucketName: creds.bucketName || creds.s3BucketName,
134
140
  s3Region: creds.region || creds.s3Region,
135
- s3Endpoint: creds.endpoint || creds.s3Endpoint
141
+ s3Endpoint: creds.endpoint || creds.s3Endpoint,
142
+ googleEmail: creds.email || account.credentials?.email || account.name,
143
+ googleRootFolderId: creds.rootFolderId,
144
+ googleRootFolderName: creds.rootFolderName,
145
+ googleAccessToken: creds.accessToken,
146
+ googleAccessTokenExpiresAt: creds.accessTokenExpiresAt,
147
+ googleRefreshToken: creds.refreshToken
136
148
  };
137
149
  }
138
150
  };
@@ -492,6 +504,200 @@ async function syncSrklAccounts(userId, sessionToken, srklUrl) {
492
504
  return await resp.json();
493
505
  }
494
506
 
507
+ // src/core/srklCore.ts
508
+ var cachedSrklUrl = null;
509
+ async function getPrimarySrklDeploymentUrl(env) {
510
+ if (cachedSrklUrl && Date.now() < cachedSrklUrl.expiresAt) return cachedSrklUrl.url;
511
+ try {
512
+ const res = await queryUnifiedDb(
513
+ `SELECT url FROM "ultrst-srkl-deployments" WHERE is_active = true ORDER BY is_primary DESC, priority DESC, created_at ASC LIMIT 1`,
514
+ [],
515
+ env
516
+ );
517
+ if (res.rows.length > 0 && res.rows[0].url) {
518
+ const url = res.rows[0].url.trim().replace(/\/+$/, "");
519
+ cachedSrklUrl = { url, expiresAt: Date.now() + 10 * 60 * 1e3 };
520
+ return url;
521
+ }
522
+ } catch (err) {
523
+ console.warn("[SrklCore] Deployment DB lookup fallback:", err.message);
524
+ }
525
+ const fallback = "https://srkl-engine.vercel.app";
526
+ cachedSrklUrl = { url: fallback, expiresAt: Date.now() + 10 * 60 * 1e3 };
527
+ return fallback;
528
+ }
529
+ function deduplicateAccounts(items) {
530
+ const seen = /* @__PURE__ */ new Set();
531
+ const out = [];
532
+ for (const a of items) {
533
+ if (!a) continue;
534
+ const creds = a.credentials || a.metadata?.credentials || a;
535
+ const keyId = (creds.keyId || creds.b2KeyId || creds.accessKeyId || "").trim();
536
+ const token = (creds.token || creds.apiToken || creds.applicationKey || creds.b2ApplicationKey || "").trim();
537
+ const sId = (a.serviceId || a.provider || "").toLowerCase().trim();
538
+ const sig = keyId ? `key:${keyId}` : token ? `tok:${sId}:${token.slice(-12)}` : a.id ? `id:${a.id}` : `nam:${sId}:${a.name || a.label}`;
539
+ if (!seen.has(sig)) {
540
+ seen.add(sig);
541
+ if (a.id) seen.add(`id:${a.id}`);
542
+ out.push(a);
543
+ }
544
+ }
545
+ return out;
546
+ }
547
+ async function getSrklAccounts(userId, service2, env) {
548
+ const rawAccounts = [];
549
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
550
+ if (userId) {
551
+ try {
552
+ const uRes = await queryUnifiedDb(
553
+ `SELECT app_profiles FROM "ultrst-users" WHERE id = $1 OR email = $1 LIMIT 1`,
554
+ [userId],
555
+ env
556
+ );
557
+ if (uRes.rows.length > 0) {
558
+ const p = typeof uRes.rows[0].app_profiles === "string" ? JSON.parse(uRes.rows[0].app_profiles) : uRes.rows[0].app_profiles || {};
559
+ const conns = [];
560
+ for (const app of Object.values(p)) {
561
+ if (app && typeof app === "object" && Array.isArray(app.storage_connections)) {
562
+ conns.push(...app.storage_connections);
563
+ }
564
+ }
565
+ for (const c of conns) {
566
+ if (!service2 || (c.provider || "").toLowerCase().includes(service2.toLowerCase())) {
567
+ rawAccounts.push({
568
+ id: c.id,
569
+ name: c.label || c.name || "Backblaze B2 Account",
570
+ provider: c.provider === "backblaze_b2" ? "backblaze" : c.provider,
571
+ serviceId: "backblaze",
572
+ category: "storage",
573
+ groupIds: c.groupIds || (c.groupId ? [c.groupId] : []),
574
+ credentials: {
575
+ keyId: c.b2KeyId || c.keyId || c.accessKeyId || "",
576
+ applicationKey: c.b2ApplicationKey || c.applicationKey || c.secretAccessKey || "",
577
+ bucketName: c.b2BucketName || c.bucketName || "",
578
+ bucketId: c.b2BucketId || c.bucketId || "",
579
+ endpoint: c.b2Endpoint || c.endpoint || "s3.eu-central-003.backblazeb2.com",
580
+ region: c.b2Region || c.region || "eu-central-003"
581
+ }
582
+ });
583
+ }
584
+ }
585
+ }
586
+ } catch (err) {
587
+ console.warn("[SrklCore] Storage connection DB lookup fallback:", err.message);
588
+ }
589
+ }
590
+ try {
591
+ const fs = await import("fs/promises");
592
+ const path = await import("path");
593
+ const accPath = path.resolve(".skipo/accounts.json");
594
+ const raw = await fs.readFile(accPath, "utf-8");
595
+ const localUsers = JSON.parse(raw);
596
+ for (const u of Object.values(localUsers)) {
597
+ const conns = Array.isArray(u.storage_connections) ? u.storage_connections : [];
598
+ for (const c of conns) {
599
+ if (!service2 || (c.provider || "").toLowerCase().includes(service2.toLowerCase())) {
600
+ rawAccounts.push({
601
+ id: c.id,
602
+ name: c.label || c.name || "Local B2 Account",
603
+ provider: "backblaze",
604
+ serviceId: "backblaze",
605
+ credentials: {
606
+ keyId: c.b2KeyId || c.keyId || "",
607
+ applicationKey: c.b2ApplicationKey || c.applicationKey || "",
608
+ bucketName: c.b2BucketName || c.bucketName || "",
609
+ bucketId: c.b2BucketId || "",
610
+ endpoint: c.b2Endpoint || "s3.eu-central-003.backblazeb2.com",
611
+ region: c.b2Region || "eu-central-003"
612
+ }
613
+ });
614
+ }
615
+ }
616
+ }
617
+ } catch {
618
+ }
619
+ let fetchError;
620
+ try {
621
+ const srklRes = await fetch(`${srklUrl}/api/srkl/accounts?service=${service2 || "backblaze"}`, {
622
+ signal: AbortSignal.timeout(5e3)
623
+ });
624
+ if (srklRes.ok) {
625
+ const sData = await srklRes.json();
626
+ if (Array.isArray(sData.accounts)) {
627
+ for (const sa of sData.accounts) {
628
+ rawAccounts.push(sa);
629
+ }
630
+ }
631
+ }
632
+ } catch (err) {
633
+ fetchError = err.message;
634
+ }
635
+ const accounts = deduplicateAccounts(rawAccounts);
636
+ return {
637
+ success: true,
638
+ deploymentUrl: srklUrl,
639
+ userId,
640
+ count: accounts.length,
641
+ accounts,
642
+ error: accounts.length > 0 ? void 0 : fetchError
643
+ };
644
+ }
645
+ async function listBackblazeBuckets(payload, rawUserId, env) {
646
+ try {
647
+ const userId = rawUserId || payload?.userId || payload?.credentials?.userId || "";
648
+ const creds = payload?.credentials || {};
649
+ let keyId = (payload?.keyId || payload?.b2KeyId || payload?.accessKeyId || creds.keyId || creds.b2KeyId || creds.accessKeyId || "").trim();
650
+ let appKey = (payload?.applicationKey || payload?.b2ApplicationKey || payload?.appKey || payload?.secretAccessKey || creds.applicationKey || creds.b2ApplicationKey || creds.appKey || creds.secretAccessKey || "").trim();
651
+ const bucketId = (payload?.bucketId || creds.bucketId || "").trim();
652
+ const bucketName = (payload?.bucketName || payload?.b2BucketName || creds.bucketName || creds.b2BucketName || "").trim();
653
+ if ((!keyId || !appKey) && (payload?.accountId || payload?.id)) {
654
+ const srkl = await getSrklAccounts(userId, "backblaze", env);
655
+ const matched = srkl.accounts?.find((a) => a.id === (payload.accountId || payload.id));
656
+ if (matched?.credentials) {
657
+ keyId = (matched.credentials.keyId || matched.credentials.b2KeyId || matched.credentials.accessKeyId || keyId).trim();
658
+ appKey = (matched.credentials.applicationKey || matched.credentials.b2ApplicationKey || matched.credentials.appKey || matched.credentials.secretAccessKey || appKey).trim();
659
+ }
660
+ }
661
+ if (!keyId || !appKey) return { success: false, error: "Backblaze credentials (Key ID and Application Key) required." };
662
+ try {
663
+ const buckets = await b2ListBuckets(keyId, appKey, bucketId || void 0, bucketName || void 0);
664
+ if (Array.isArray(buckets) && buckets.length > 0) return { success: true, buckets };
665
+ } catch (err) {
666
+ console.warn("[SrklCore] Direct B2 bucket query failed, trying SRKL fallback:", err.message);
667
+ }
668
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
669
+ const srklRes = await fetch(`${srklUrl}/api/backblaze/buckets`, {
670
+ method: "POST",
671
+ headers: { "Content-Type": "application/json", "x-user-id": userId || "" },
672
+ body: JSON.stringify({ keyId, applicationKey: appKey, bucketId: bucketId || void 0 }),
673
+ signal: AbortSignal.timeout(6e3)
674
+ });
675
+ if (srklRes.ok) {
676
+ const data = await srklRes.json();
677
+ if (data.success && Array.isArray(data.buckets)) return { success: true, buckets: data.buckets };
678
+ }
679
+ return { success: true, buckets: [] };
680
+ } catch (err) {
681
+ return { success: false, error: err.message || "Failed to list Backblaze buckets" };
682
+ }
683
+ }
684
+ var srklListBackblazeBuckets = (keyId, applicationKey, bucketId, bucketName, userId, accountId) => listBackblazeBuckets({ keyId, applicationKey, bucketId, bucketName, accountId }, userId);
685
+ async function getSrklStatus(env) {
686
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
687
+ const start = Date.now();
688
+ try {
689
+ const resp = await fetch(`${srklUrl}/api/ecosystem/health`, { signal: AbortSignal.timeout(5e3) });
690
+ const latencyMs = Date.now() - start;
691
+ if (resp.ok) {
692
+ const data = await resp.json().catch(() => ({}));
693
+ return { success: true, deploymentUrl: srklUrl, online: true, latencyMs, details: data };
694
+ }
695
+ return { success: false, deploymentUrl: srklUrl, online: false, status: resp.status, latencyMs };
696
+ } catch (err) {
697
+ return { success: false, deploymentUrl: srklUrl, online: false, error: err.message, latencyMs: Date.now() - start };
698
+ }
699
+ }
700
+
495
701
  // src/srkl/srkl.ts
496
702
  var runtime = {
497
703
  VaultAccessClient: SrklVaultAccessClient,
@@ -508,7 +714,12 @@ var service = {
508
714
  name: "srkl",
509
715
  description: "SRKL Ecosystem Volatile Memory Credential Vault Service",
510
716
  runtime,
511
- deployment
717
+ deployment,
718
+ getSrklAccounts: (userId, serviceName, env) => getSrklAccounts(userId, serviceName, env),
719
+ getAccounts: (userId, serviceName, env) => getSrklAccounts(userId, serviceName, env),
720
+ listBackblazeBuckets: (payload, userId, env) => listBackblazeBuckets(payload, userId, env),
721
+ getSrklStatus: (env) => getSrklStatus(env),
722
+ getDeploymentUrl: (env) => getPrimarySrklDeploymentUrl(env)
512
723
  };
513
724
  var srklService = service;
514
725
 
@@ -523,5 +734,10 @@ export {
523
734
  globalCredentialRegistry,
524
735
  SrklVaultAccessClient,
525
736
  syncSrklAccounts,
737
+ getPrimarySrklDeploymentUrl,
738
+ getSrklAccounts,
739
+ listBackblazeBuckets,
740
+ srklListBackblazeBuckets,
741
+ getSrklStatus,
526
742
  srklService
527
743
  };
@@ -1,193 +1,12 @@
1
- // src/core/unifiedDb.ts
2
- var neon;
3
- function cleanDbUrl(url) {
4
- if (!url || typeof url !== "string") return "";
5
- return url.trim().replace(/^["']|["']$/g, "");
6
- }
7
- function getUnifiedDbUrl(env) {
8
- const fromEnv = cleanDbUrl(env?.SYSTEM_DATABASE_URL_1) || cleanDbUrl(env?.DATABASE_URL) || cleanDbUrl(env?.SYSTEM_DATABASE_URL_2);
9
- if (fromEnv) return fromEnv;
10
- if (typeof process !== "undefined" && process.env) {
11
- return cleanDbUrl(process.env.SYSTEM_DATABASE_URL_1) || cleanDbUrl(process.env.DATABASE_URL) || cleanDbUrl(process.env.SYSTEM_DATABASE_URL_2) || cleanDbUrl(process.env.SYSTEM_DATABASE_URL_3) || "";
12
- }
13
- return "";
14
- }
15
- async function queryUnifiedDb(sqlText, params = [], env) {
16
- const dbUrl = getUnifiedDbUrl(env);
17
- if (!dbUrl) {
18
- throw new Error("[UnifiedDB] No database URL configured in environment.");
19
- }
20
- if (!neon) {
21
- const mod = await import("@neondatabase/serverless");
22
- neon = mod.neon;
23
- }
24
- const sql = neon(dbUrl);
25
- try {
26
- const rows = await (sql.query ? sql.query(sqlText, params) : sql(sqlText, params));
27
- return {
28
- rows: Array.isArray(rows) ? rows : [],
29
- rowCount: Array.isArray(rows) ? rows.length : 0
30
- };
31
- } catch (err) {
32
- console.error("[UnifiedDB] Query execution error:", err.message);
33
- throw err;
34
- }
35
- }
36
-
37
- // src/core/b2DirectCore.ts
38
- var authCache = /* @__PURE__ */ new Map();
39
- var bucketIdCache = /* @__PURE__ */ new Map();
40
- async function authorizeB2(keyId, applicationKey) {
41
- const cacheKey = `${keyId.trim()}:${applicationKey.trim()}`;
42
- const cached = authCache.get(cacheKey);
43
- if (cached && Date.now() < cached.expiresAt) return cached.auth;
44
- const authHeader = typeof Buffer !== "undefined" ? Buffer.from(`${keyId.trim()}:${applicationKey.trim()}`).toString("base64") : btoa(`${keyId.trim()}:${applicationKey.trim()}`);
45
- let res = await fetch("https://api.backblazeb2.com/b2api/v2/b2_authorize_account", {
46
- headers: { Authorization: `Basic ${authHeader}` },
47
- signal: AbortSignal.timeout(1e4)
48
- });
49
- if (!res.ok) {
50
- res = await fetch("https://api.backblazeb2.com/b2api/v4/b2_authorize_account", {
51
- headers: { Authorization: `Basic ${authHeader}` },
52
- signal: AbortSignal.timeout(1e4)
53
- });
54
- }
55
- if (!res.ok) {
56
- const errText = await res.text();
57
- throw new Error(`Backblaze B2 authorization failed (${res.status}): ${errText}`);
58
- }
59
- const data = await res.json();
60
- const auth = {
61
- accountId: data.accountId,
62
- authorizationToken: data.authorizationToken,
63
- apiUrl: (data.apiInfo?.storageApi?.apiUrl || data.apiUrl || "https://api.backblazeb2.com").replace(/\/+$/, ""),
64
- downloadUrl: (data.apiInfo?.storageApi?.downloadUrl || data.downloadUrl || data.apiUrl || "https://f003.backblazeb2.com").replace(/\/+$/, ""),
65
- s3ApiUrl: data.apiInfo?.storageApi?.s3ApiUrl || data.s3ApiUrl,
66
- allowed: data.apiInfo?.storageApi?.allowed || data.allowed
67
- };
68
- authCache.set(cacheKey, { auth, expiresAt: Date.now() + 20 * 60 * 1e3 });
69
- return auth;
70
- }
71
- async function b2ListBuckets(keyId, applicationKey, bucketId, bucketName) {
72
- const auth = await authorizeB2(keyId, applicationKey);
73
- const rBucketId = bucketId || auth.allowed?.bucketId || auth.allowed?.buckets?.[0]?.bucketId;
74
- const rBucketName = bucketName || auth.allowed?.bucketName || auth.allowed?.buckets?.[0]?.bucketName;
75
- if (!auth.allowed?.bucketId && !auth.allowed?.bucketName) {
76
- try {
77
- const res = await fetch(`${auth.apiUrl}/b2api/v2/b2_list_buckets`, {
78
- method: "POST",
79
- headers: { Authorization: auth.authorizationToken, "Content-Type": "application/json" },
80
- body: JSON.stringify({ accountId: auth.accountId }),
81
- signal: AbortSignal.timeout(8e3)
82
- });
83
- if (res.ok) {
84
- const data = await res.json();
85
- if (Array.isArray(data.buckets) && data.buckets.length > 0) return data.buckets;
86
- }
87
- } catch (err) {
88
- console.warn("[B2DirectCore] list_buckets query failed:", err.message);
89
- }
90
- }
91
- if (rBucketId || rBucketName) {
92
- const body = { accountId: auth.accountId };
93
- if (rBucketId) body.bucketId = rBucketId;
94
- else if (rBucketName) body.bucketName = rBucketName;
95
- try {
96
- const res = await fetch(`${auth.apiUrl}/b2api/v2/b2_list_buckets`, {
97
- method: "POST",
98
- headers: { Authorization: auth.authorizationToken, "Content-Type": "application/json" },
99
- body: JSON.stringify(body),
100
- signal: AbortSignal.timeout(8e3)
101
- });
102
- if (res.ok) {
103
- const data = await res.json();
104
- if (Array.isArray(data.buckets) && data.buckets.length > 0) return data.buckets;
105
- }
106
- } catch {
107
- }
108
- return [{
109
- accountId: auth.accountId,
110
- bucketId: rBucketId || "restricted",
111
- bucketName: rBucketName || (bucketName || "default-bucket"),
112
- bucketType: "allPrivate"
113
- }];
114
- }
115
- return [];
116
- }
117
- async function getB2BucketId(keyId, applicationKey, bucketName) {
118
- const cacheKey = `${keyId.trim()}:${bucketName.trim()}`;
119
- if (bucketIdCache.has(cacheKey)) return bucketIdCache.get(cacheKey);
120
- const buckets = await b2ListBuckets(keyId, applicationKey, void 0, bucketName);
121
- const match = buckets.find((b) => b.bucketName === bucketName);
122
- if (!match) throw new Error(`B2 bucket "${bucketName}" not found in account`);
123
- bucketIdCache.set(cacheKey, match.bucketId);
124
- return match.bucketId;
125
- }
126
- async function b2UploadFile(keyId, applicationKey, bucketName, fileName, buffer, contentType = "b2/x-auto") {
127
- const auth = await authorizeB2(keyId, applicationKey);
128
- const bucketId = await getB2BucketId(keyId, applicationKey, bucketName);
129
- const urlRes = await fetch(`${auth.apiUrl}/b2api/v2/b2_get_upload_url`, {
130
- method: "POST",
131
- headers: { Authorization: auth.authorizationToken, "Content-Type": "application/json" },
132
- body: JSON.stringify({ bucketId })
133
- });
134
- if (!urlRes.ok) throw new Error(`B2 get upload url failed (${urlRes.status})`);
135
- const { uploadUrl, authorizationToken } = await urlRes.json();
136
- const encodedFileName = encodeURIComponent(fileName).replace(/%2F/g, "/");
137
- const uploadRes = await fetch(uploadUrl, {
138
- method: "POST",
139
- headers: {
140
- Authorization: authorizationToken,
141
- "X-Bz-File-Name": encodedFileName,
142
- "Content-Type": contentType,
143
- "Content-Length": String(buffer.byteLength),
144
- "X-Bz-Content-Sha1": "do_not_verify"
145
- },
146
- body: buffer
147
- });
148
- if (!uploadRes.ok) throw new Error(`B2 upload failed for ${fileName} (${uploadRes.status}): ${await uploadRes.text()}`);
149
- return uploadRes.json();
150
- }
151
- async function b2DownloadFile(keyId, applicationKey, bucketName, fileName) {
152
- const auth = await authorizeB2(keyId, applicationKey);
153
- const encodedName = encodeURIComponent(fileName).replace(/%2F/g, "/");
154
- const res = await fetch(`${auth.downloadUrl}/file/${bucketName}/${encodedName}`, { headers: { Authorization: auth.authorizationToken } });
155
- if (res.status === 404) return null;
156
- if (!res.ok) throw new Error(`B2 download failed for ${fileName} (${res.status})`);
157
- return new Uint8Array(await res.arrayBuffer());
158
- }
159
- async function b2ListFileNames(keyId, applicationKey, bucketName, prefix = "") {
160
- const auth = await authorizeB2(keyId, applicationKey);
161
- const bucketId = await getB2BucketId(keyId, applicationKey, bucketName);
162
- const res = await fetch(`${auth.apiUrl}/b2api/v2/b2_list_file_names`, {
163
- method: "POST",
164
- headers: { Authorization: auth.authorizationToken, "Content-Type": "application/json" },
165
- body: JSON.stringify({ bucketId, prefix, maxFileCount: 1e3 })
166
- });
167
- if (!res.ok) throw new Error(`B2 list files failed (${res.status})`);
168
- const data = await res.json();
169
- return data.files || [];
170
- }
171
- async function b2DeleteFileVersion(keyId, applicationKey, fileName, fileId) {
172
- const auth = await authorizeB2(keyId, applicationKey);
173
- const res = await fetch(`${auth.apiUrl}/b2api/v2/b2_delete_file_version`, {
174
- method: "POST",
175
- headers: { Authorization: auth.authorizationToken, "Content-Type": "application/json" },
176
- body: JSON.stringify({ fileName, fileId })
177
- });
178
- if (!res.ok) throw new Error(`B2 delete file version failed (${res.status})`);
179
- return res.json();
180
- }
181
- async function b2DeleteFolder(keyId, applicationKey, bucketName, folderPrefix) {
182
- const cleanPrefix = folderPrefix.replace(/\/+$/, "") + "/";
183
- const files = await b2ListFileNames(keyId, applicationKey, bucketName, cleanPrefix);
184
- let deletedCount = 0;
185
- for (const file of files) {
186
- await b2DeleteFileVersion(keyId, applicationKey, file.fileName, file.fileId);
187
- deletedCount++;
188
- }
189
- return { success: true, deletedCount };
190
- }
1
+ import {
2
+ b2DeleteFileVersion,
3
+ b2DeleteFolder,
4
+ b2DownloadFile,
5
+ b2ListBuckets,
6
+ b2ListFileNames,
7
+ b2UploadFile,
8
+ queryUnifiedDb
9
+ } from "./chunk-VAFCR2MS.js";
191
10
 
192
11
  // src/core/workspaceFileCore.ts
193
12
  async function getFs() {
@@ -718,16 +537,6 @@ async function getWorkspaceStorageDetails(workspaceId, env) {
718
537
  }
719
538
 
720
539
  export {
721
- cleanDbUrl,
722
- getUnifiedDbUrl,
723
- queryUnifiedDb,
724
- b2ListBuckets,
725
- getB2BucketId,
726
- b2UploadFile,
727
- b2DownloadFile,
728
- b2ListFileNames,
729
- b2DeleteFileVersion,
730
- b2DeleteFolder,
731
540
  getWorkspaceFolderPrefix,
732
541
  isB2Workspace,
733
542
  writeWorkspaceFile,