botinabox 2.16.17 → 2.16.18
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/dist/core/orchestrator/secret-store.d.ts +11 -0
- package/dist/index.js +45 -15
- package/package.json +1 -1
|
@@ -41,6 +41,17 @@ export declare class SecretStore {
|
|
|
41
41
|
set(input: SecretInput): Promise<SecretMeta>;
|
|
42
42
|
get(name: string, environment?: string): Promise<string | null>;
|
|
43
43
|
getMeta(name: string, environment?: string): Promise<SecretMeta | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch the most recently created live row for (name, environment).
|
|
46
|
+
*
|
|
47
|
+
* `set()` keeps this to a single row in steady state, but we still pick the
|
|
48
|
+
* newest in JS rather than rely on a SQL `LIMIT 1` (nondeterministic without
|
|
49
|
+
* an ORDER BY) or a dialect/version-specific `orderBy` form: legacy data
|
|
50
|
+
* written before the upsert fix can still have duplicate live rows, and JS
|
|
51
|
+
* sorting resolves them deterministically across SQLite and Postgres. (Same
|
|
52
|
+
* cross-dialect-sort rationale as the chat memory resolver.)
|
|
53
|
+
*/
|
|
54
|
+
private _latestRow;
|
|
44
55
|
list(): Promise<SecretMeta[]>;
|
|
45
56
|
rotate(name: string, newValue: string, environment?: string): Promise<void>;
|
|
46
57
|
delete(name: string, environment?: string): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -7524,35 +7524,65 @@ var SecretStore = class {
|
|
|
7524
7524
|
this.encKey = encryptionKey ? deriveEncKey(encryptionKey) : null;
|
|
7525
7525
|
}
|
|
7526
7526
|
async set(input) {
|
|
7527
|
-
const
|
|
7528
|
-
const
|
|
7529
|
-
|
|
7530
|
-
|
|
7527
|
+
const environment = input.environment ?? "production";
|
|
7528
|
+
const value = this.encKey && input.value ? encryptValue(input.value, this.encKey) : input.value;
|
|
7529
|
+
const existing = await this.db.query("secrets", {
|
|
7530
|
+
where: { name: input.name, environment },
|
|
7531
|
+
filters: [{ col: "deleted_at", op: "isNull" }],
|
|
7532
|
+
limit: 1
|
|
7533
|
+
});
|
|
7534
|
+
if (existing.length > 0) {
|
|
7535
|
+
const id2 = existing[0].id;
|
|
7536
|
+
const changes = {
|
|
7537
|
+
value,
|
|
7538
|
+
environment,
|
|
7539
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
7540
|
+
};
|
|
7541
|
+
if (input.type !== void 0) changes.type = input.type;
|
|
7542
|
+
if (input.description !== void 0) changes.description = input.description;
|
|
7543
|
+
await this.db.update("secrets", id2, changes);
|
|
7544
|
+
await this.hooks.emit("secret.updated", { name: input.name });
|
|
7545
|
+
const updated = await this.db.get("secrets", id2);
|
|
7546
|
+
return this._toMeta(updated);
|
|
7531
7547
|
}
|
|
7532
|
-
|
|
7548
|
+
const id = uuidv42();
|
|
7549
|
+
await this.db.insert("secrets", { ...input, id, value, environment });
|
|
7533
7550
|
await this.hooks.emit("secret.created", { name: input.name });
|
|
7534
7551
|
const inserted = await this.db.get("secrets", id);
|
|
7535
7552
|
return this._toMeta(inserted);
|
|
7536
7553
|
}
|
|
7537
7554
|
async get(name, environment = "production") {
|
|
7538
|
-
const
|
|
7539
|
-
|
|
7540
|
-
filters: [{ col: "deleted_at", op: "isNull" }],
|
|
7541
|
-
limit: 1
|
|
7542
|
-
});
|
|
7543
|
-
if (rows.length === 0) return null;
|
|
7555
|
+
const row = await this._latestRow(name, environment);
|
|
7556
|
+
if (!row) return null;
|
|
7544
7557
|
await this.hooks.emit("secret.accessed", { name, environment });
|
|
7545
|
-
const raw =
|
|
7558
|
+
const raw = row.value ?? null;
|
|
7546
7559
|
if (raw && this.encKey) return decryptValue(raw, this.encKey);
|
|
7547
7560
|
return raw;
|
|
7548
7561
|
}
|
|
7549
7562
|
async getMeta(name, environment = "production") {
|
|
7563
|
+
const row = await this._latestRow(name, environment);
|
|
7564
|
+
return row ? this._toMeta(row) : null;
|
|
7565
|
+
}
|
|
7566
|
+
/**
|
|
7567
|
+
* Fetch the most recently created live row for (name, environment).
|
|
7568
|
+
*
|
|
7569
|
+
* `set()` keeps this to a single row in steady state, but we still pick the
|
|
7570
|
+
* newest in JS rather than rely on a SQL `LIMIT 1` (nondeterministic without
|
|
7571
|
+
* an ORDER BY) or a dialect/version-specific `orderBy` form: legacy data
|
|
7572
|
+
* written before the upsert fix can still have duplicate live rows, and JS
|
|
7573
|
+
* sorting resolves them deterministically across SQLite and Postgres. (Same
|
|
7574
|
+
* cross-dialect-sort rationale as the chat memory resolver.)
|
|
7575
|
+
*/
|
|
7576
|
+
async _latestRow(name, environment) {
|
|
7550
7577
|
const rows = await this.db.query("secrets", {
|
|
7551
7578
|
where: { name, environment },
|
|
7552
|
-
filters: [{ col: "deleted_at", op: "isNull" }]
|
|
7553
|
-
limit: 1
|
|
7579
|
+
filters: [{ col: "deleted_at", op: "isNull" }]
|
|
7554
7580
|
});
|
|
7555
|
-
|
|
7581
|
+
if (rows.length === 0) return void 0;
|
|
7582
|
+
rows.sort(
|
|
7583
|
+
(a, b) => String(b.created_at ?? "").localeCompare(String(a.created_at ?? ""))
|
|
7584
|
+
);
|
|
7585
|
+
return rows[0];
|
|
7556
7586
|
}
|
|
7557
7587
|
async list() {
|
|
7558
7588
|
const rows = await this.db.query("secrets", {
|