@ultrst-armada/kloks 1.5.2 → 1.7.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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "packageName": "@ultrst-armada/kloks",
4
- "version": "1.5.2",
5
- "sourceCommit": "07f2e1a49da642bbfd42cd79422306c93195493f",
4
+ "version": "1.7.0",
5
+ "sourceCommit": "b794ff2065167edac2d5c817897b5244e9136952",
6
6
  "releaseWorkflow": "npm Release",
7
- "workflowRunId": "39969373482"
7
+ "workflowRunId": "40036485979"
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultrst-armada/kloks",
3
- "version": "1.5.2",
3
+ "version": "1.7.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -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,
@@ -1,18 +1,20 @@
1
1
  import {
2
- b2DownloadFile,
3
- b2ListFileNames,
4
- b2UploadFile,
5
2
  createWorkspace,
6
3
  deleteWorkspace,
7
4
  deleteWorkspaceFile,
8
5
  findUserWorkspace,
9
6
  getWorkspaces,
10
7
  listWorkspaceFiles,
11
- queryUnifiedDb,
12
8
  readWorkspaceFile,
13
9
  updateWorkspace,
14
10
  writeWorkspaceFile
15
- } from "./chunk-E72GXBXF.js";
11
+ } from "./chunk-6K75XXFD.js";
12
+ import {
13
+ b2DownloadFile,
14
+ b2ListFileNames,
15
+ b2UploadFile,
16
+ queryUnifiedDb
17
+ } from "./chunk-VAFCR2MS.js";
16
18
 
17
19
  // src/workspace/WorkspaceFS.ts
18
20
  import { SkipoBase } from "@ultrst-armada/kloks/functions";
@@ -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 {
@@ -492,6 +497,200 @@ async function syncSrklAccounts(userId, sessionToken, srklUrl) {
492
497
  return await resp.json();
493
498
  }
494
499
 
500
+ // src/core/srklCore.ts
501
+ var cachedSrklUrl = null;
502
+ async function getPrimarySrklDeploymentUrl(env) {
503
+ if (cachedSrklUrl && Date.now() < cachedSrklUrl.expiresAt) return cachedSrklUrl.url;
504
+ try {
505
+ const res = await queryUnifiedDb(
506
+ `SELECT url FROM "ultrst-srkl-deployments" WHERE is_active = true ORDER BY is_primary DESC, priority DESC, created_at ASC LIMIT 1`,
507
+ [],
508
+ env
509
+ );
510
+ if (res.rows.length > 0 && res.rows[0].url) {
511
+ const url = res.rows[0].url.trim().replace(/\/+$/, "");
512
+ cachedSrklUrl = { url, expiresAt: Date.now() + 10 * 60 * 1e3 };
513
+ return url;
514
+ }
515
+ } catch (err) {
516
+ console.warn("[SrklCore] Deployment DB lookup fallback:", err.message);
517
+ }
518
+ const fallback = "https://srkl-engine.vercel.app";
519
+ cachedSrklUrl = { url: fallback, expiresAt: Date.now() + 10 * 60 * 1e3 };
520
+ return fallback;
521
+ }
522
+ function deduplicateAccounts(items) {
523
+ const seen = /* @__PURE__ */ new Set();
524
+ const out = [];
525
+ for (const a of items) {
526
+ if (!a) continue;
527
+ const creds = a.credentials || a.metadata?.credentials || a;
528
+ const keyId = (creds.keyId || creds.b2KeyId || creds.accessKeyId || "").trim();
529
+ const token = (creds.token || creds.apiToken || creds.applicationKey || creds.b2ApplicationKey || "").trim();
530
+ const sId = (a.serviceId || a.provider || "").toLowerCase().trim();
531
+ const sig = keyId ? `key:${keyId}` : token ? `tok:${sId}:${token.slice(-12)}` : a.id ? `id:${a.id}` : `nam:${sId}:${a.name || a.label}`;
532
+ if (!seen.has(sig)) {
533
+ seen.add(sig);
534
+ if (a.id) seen.add(`id:${a.id}`);
535
+ out.push(a);
536
+ }
537
+ }
538
+ return out;
539
+ }
540
+ async function getSrklAccounts(userId, service2, env) {
541
+ const rawAccounts = [];
542
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
543
+ if (userId) {
544
+ try {
545
+ const uRes = await queryUnifiedDb(
546
+ `SELECT app_profiles FROM "ultrst-users" WHERE id = $1 OR email = $1 LIMIT 1`,
547
+ [userId],
548
+ env
549
+ );
550
+ if (uRes.rows.length > 0) {
551
+ const p = typeof uRes.rows[0].app_profiles === "string" ? JSON.parse(uRes.rows[0].app_profiles) : uRes.rows[0].app_profiles || {};
552
+ const conns = [];
553
+ for (const app of Object.values(p)) {
554
+ if (app && typeof app === "object" && Array.isArray(app.storage_connections)) {
555
+ conns.push(...app.storage_connections);
556
+ }
557
+ }
558
+ for (const c of conns) {
559
+ if (!service2 || (c.provider || "").toLowerCase().includes(service2.toLowerCase())) {
560
+ rawAccounts.push({
561
+ id: c.id,
562
+ name: c.label || c.name || "Backblaze B2 Account",
563
+ provider: c.provider === "backblaze_b2" ? "backblaze" : c.provider,
564
+ serviceId: "backblaze",
565
+ category: "storage",
566
+ groupIds: c.groupIds || (c.groupId ? [c.groupId] : []),
567
+ credentials: {
568
+ keyId: c.b2KeyId || c.keyId || c.accessKeyId || "",
569
+ applicationKey: c.b2ApplicationKey || c.applicationKey || c.secretAccessKey || "",
570
+ bucketName: c.b2BucketName || c.bucketName || "",
571
+ bucketId: c.b2BucketId || c.bucketId || "",
572
+ endpoint: c.b2Endpoint || c.endpoint || "s3.eu-central-003.backblazeb2.com",
573
+ region: c.b2Region || c.region || "eu-central-003"
574
+ }
575
+ });
576
+ }
577
+ }
578
+ }
579
+ } catch (err) {
580
+ console.warn("[SrklCore] Storage connection DB lookup fallback:", err.message);
581
+ }
582
+ }
583
+ try {
584
+ const fs = await import("fs/promises");
585
+ const path = await import("path");
586
+ const accPath = path.resolve(".skipo/accounts.json");
587
+ const raw = await fs.readFile(accPath, "utf-8");
588
+ const localUsers = JSON.parse(raw);
589
+ for (const u of Object.values(localUsers)) {
590
+ const conns = Array.isArray(u.storage_connections) ? u.storage_connections : [];
591
+ for (const c of conns) {
592
+ if (!service2 || (c.provider || "").toLowerCase().includes(service2.toLowerCase())) {
593
+ rawAccounts.push({
594
+ id: c.id,
595
+ name: c.label || c.name || "Local B2 Account",
596
+ provider: "backblaze",
597
+ serviceId: "backblaze",
598
+ credentials: {
599
+ keyId: c.b2KeyId || c.keyId || "",
600
+ applicationKey: c.b2ApplicationKey || c.applicationKey || "",
601
+ bucketName: c.b2BucketName || c.bucketName || "",
602
+ bucketId: c.b2BucketId || "",
603
+ endpoint: c.b2Endpoint || "s3.eu-central-003.backblazeb2.com",
604
+ region: c.b2Region || "eu-central-003"
605
+ }
606
+ });
607
+ }
608
+ }
609
+ }
610
+ } catch {
611
+ }
612
+ let fetchError;
613
+ try {
614
+ const srklRes = await fetch(`${srklUrl}/api/srkl/accounts?service=${service2 || "backblaze"}`, {
615
+ signal: AbortSignal.timeout(5e3)
616
+ });
617
+ if (srklRes.ok) {
618
+ const sData = await srklRes.json();
619
+ if (Array.isArray(sData.accounts)) {
620
+ for (const sa of sData.accounts) {
621
+ rawAccounts.push(sa);
622
+ }
623
+ }
624
+ }
625
+ } catch (err) {
626
+ fetchError = err.message;
627
+ }
628
+ const accounts = deduplicateAccounts(rawAccounts);
629
+ return {
630
+ success: true,
631
+ deploymentUrl: srklUrl,
632
+ userId,
633
+ count: accounts.length,
634
+ accounts,
635
+ error: accounts.length > 0 ? void 0 : fetchError
636
+ };
637
+ }
638
+ async function listBackblazeBuckets(payload, rawUserId, env) {
639
+ try {
640
+ const userId = rawUserId || payload?.userId || payload?.credentials?.userId || "";
641
+ const creds = payload?.credentials || {};
642
+ let keyId = (payload?.keyId || payload?.b2KeyId || payload?.accessKeyId || creds.keyId || creds.b2KeyId || creds.accessKeyId || "").trim();
643
+ let appKey = (payload?.applicationKey || payload?.b2ApplicationKey || payload?.appKey || payload?.secretAccessKey || creds.applicationKey || creds.b2ApplicationKey || creds.appKey || creds.secretAccessKey || "").trim();
644
+ const bucketId = (payload?.bucketId || creds.bucketId || "").trim();
645
+ const bucketName = (payload?.bucketName || payload?.b2BucketName || creds.bucketName || creds.b2BucketName || "").trim();
646
+ if ((!keyId || !appKey) && (payload?.accountId || payload?.id)) {
647
+ const srkl = await getSrklAccounts(userId, "backblaze", env);
648
+ const matched = srkl.accounts?.find((a) => a.id === (payload.accountId || payload.id));
649
+ if (matched?.credentials) {
650
+ keyId = (matched.credentials.keyId || matched.credentials.b2KeyId || matched.credentials.accessKeyId || keyId).trim();
651
+ appKey = (matched.credentials.applicationKey || matched.credentials.b2ApplicationKey || matched.credentials.appKey || matched.credentials.secretAccessKey || appKey).trim();
652
+ }
653
+ }
654
+ if (!keyId || !appKey) return { success: false, error: "Backblaze credentials (Key ID and Application Key) required." };
655
+ try {
656
+ const buckets = await b2ListBuckets(keyId, appKey, bucketId || void 0, bucketName || void 0);
657
+ if (Array.isArray(buckets) && buckets.length > 0) return { success: true, buckets };
658
+ } catch (err) {
659
+ console.warn("[SrklCore] Direct B2 bucket query failed, trying SRKL fallback:", err.message);
660
+ }
661
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
662
+ const srklRes = await fetch(`${srklUrl}/api/backblaze/buckets`, {
663
+ method: "POST",
664
+ headers: { "Content-Type": "application/json", "x-user-id": userId || "" },
665
+ body: JSON.stringify({ keyId, applicationKey: appKey, bucketId: bucketId || void 0 }),
666
+ signal: AbortSignal.timeout(6e3)
667
+ });
668
+ if (srklRes.ok) {
669
+ const data = await srklRes.json();
670
+ if (data.success && Array.isArray(data.buckets)) return { success: true, buckets: data.buckets };
671
+ }
672
+ return { success: true, buckets: [] };
673
+ } catch (err) {
674
+ return { success: false, error: err.message || "Failed to list Backblaze buckets" };
675
+ }
676
+ }
677
+ var srklListBackblazeBuckets = (keyId, applicationKey, bucketId, bucketName, userId, accountId) => listBackblazeBuckets({ keyId, applicationKey, bucketId, bucketName, accountId }, userId);
678
+ async function getSrklStatus(env) {
679
+ const srklUrl = await getPrimarySrklDeploymentUrl(env);
680
+ const start = Date.now();
681
+ try {
682
+ const resp = await fetch(`${srklUrl}/api/ecosystem/health`, { signal: AbortSignal.timeout(5e3) });
683
+ const latencyMs = Date.now() - start;
684
+ if (resp.ok) {
685
+ const data = await resp.json().catch(() => ({}));
686
+ return { success: true, deploymentUrl: srklUrl, online: true, latencyMs, details: data };
687
+ }
688
+ return { success: false, deploymentUrl: srklUrl, online: false, status: resp.status, latencyMs };
689
+ } catch (err) {
690
+ return { success: false, deploymentUrl: srklUrl, online: false, error: err.message, latencyMs: Date.now() - start };
691
+ }
692
+ }
693
+
495
694
  // src/srkl/srkl.ts
496
695
  var runtime = {
497
696
  VaultAccessClient: SrklVaultAccessClient,
@@ -508,7 +707,12 @@ var service = {
508
707
  name: "srkl",
509
708
  description: "SRKL Ecosystem Volatile Memory Credential Vault Service",
510
709
  runtime,
511
- deployment
710
+ deployment,
711
+ getSrklAccounts: (userId, serviceName, env) => getSrklAccounts(userId, serviceName, env),
712
+ getAccounts: (userId, serviceName, env) => getSrklAccounts(userId, serviceName, env),
713
+ listBackblazeBuckets: (payload, userId, env) => listBackblazeBuckets(payload, userId, env),
714
+ getSrklStatus: (env) => getSrklStatus(env),
715
+ getDeploymentUrl: (env) => getPrimarySrklDeploymentUrl(env)
512
716
  };
513
717
  var srklService = service;
514
718
 
@@ -523,5 +727,10 @@ export {
523
727
  globalCredentialRegistry,
524
728
  SrklVaultAccessClient,
525
729
  syncSrklAccounts,
730
+ getPrimarySrklDeploymentUrl,
731
+ getSrklAccounts,
732
+ listBackblazeBuckets,
733
+ srklListBackblazeBuckets,
734
+ getSrklStatus,
526
735
  srklService
527
736
  };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-J2J24JVC.js";
4
4
  import {
5
5
  findUserWorkspace
6
- } from "./chunk-E72GXBXF.js";
6
+ } from "./chunk-6K75XXFD.js";
7
7
 
8
8
  // src/services/workspaceGraphService.ts
9
9
  function slugify(name) {
@@ -33,12 +33,12 @@ async function getSrklAccounts(userId, service, queryDb) {
33
33
  const uRes = await queryDb(`SELECT app_profiles FROM "ultrst-users" WHERE id = $1 LIMIT 1`, [userId]);
34
34
  if (uRes.rows.length > 0) {
35
35
  const p = typeof uRes.rows[0].app_profiles === "string" ? JSON.parse(uRes.rows[0].app_profiles) : uRes.rows[0].app_profiles || {};
36
- const pool = [
37
- ...p.srkl?.storage_connections || [],
38
- ...p.depm?.storage_connections || [],
39
- ...p.qwnsr?.storage_connections || [],
40
- ...p.loky?.storage_connections || []
41
- ];
36
+ const pool = [];
37
+ for (const app of Object.values(p)) {
38
+ if (app && typeof app === "object" && Array.isArray(app.storage_connections)) {
39
+ pool.push(...app.storage_connections);
40
+ }
41
+ }
42
42
  for (const conn of pool) {
43
43
  if (service && !conn.provider?.toLowerCase().includes(service.toLowerCase())) continue;
44
44
  const kId = (conn.b2KeyId || conn.keyId || conn.accessKeyId || "").trim();
@@ -87,12 +87,12 @@ async function getSrklAccounts(userId, service, queryDb) {
87
87
  }
88
88
  return { success: true, deploymentUrl: srklUrl, count: accounts.length, accounts };
89
89
  }
90
- async function srklListBackblazeBuckets(keyId, applicationKey, _bucketId, _bucketName, userId, queryDb) {
90
+ async function srklListBackblazeBuckets(keyId, applicationKey, _bucketId, _bucketName, userId, queryDb, accountId) {
91
91
  let resolvedKeyId = (keyId || "").trim();
92
92
  let resolvedAppKey = (applicationKey || "").trim();
93
- if ((!resolvedKeyId || !resolvedAppKey) && userId && queryDb) {
94
- const accountsRes = await getSrklAccounts(userId, "backblaze", queryDb);
95
- const matched = accountsRes.accounts.find((a) => (a.credentials?.keyId || a.credentials?.b2KeyId) === resolvedKeyId) || accountsRes.accounts[0];
93
+ if ((!resolvedKeyId || !resolvedAppKey) && (userId || accountId)) {
94
+ const accountsRes = await getSrklAccounts(userId || "", "backblaze", queryDb);
95
+ const matched = accountsRes.accounts.find((a) => accountId && a.id === accountId || resolvedKeyId && (a.credentials?.keyId || a.credentials?.b2KeyId) === resolvedKeyId) || accountsRes.accounts[0];
96
96
  if (matched) {
97
97
  resolvedKeyId = matched.credentials?.keyId || matched.credentials?.b2KeyId || resolvedKeyId;
98
98
  resolvedAppKey = matched.credentials?.applicationKey || matched.credentials?.b2ApplicationKey || resolvedAppKey;