openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
170 lines (169 loc) • 6.94 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs";
import { y as parseDateStringTimestampMs } from "./number-coercion-CkhMiRw8.mjs";
import { c as isRecord } from "./record-coerce-TIsquoVR.mjs";
import { i as executeSqliteQuerySync, o as getNodeSqliteKysely } from "./kysely-sync-DUWzQvCU.mjs";
import { l as runOpenClawStateWriteTransaction } from "./openclaw-state-db-DJZ7EKoI.mjs";
import { a as safeChannelKey, n as resolveAllowFromAccountId, r as resolvePairingRequestAccountId, t as dedupePreserveOrder } from "./pairing-store-keys-cRW5JPmq.mjs";
//#region src/pairing/pairing-store-sqlite.ts
function normalizePersistedPairingMeta(value) {
if (!isRecord(value)) return;
const out = {};
for (const [key, entry] of Object.entries(value)) {
const normalized = normalizeOptionalString(entry);
if (normalized) out[key] = normalized;
}
return Object.keys(out).length > 0 ? out : void 0;
}
function normalizePersistedPairingRequest(value) {
if (!isRecord(value)) return;
const id = normalizeOptionalString(value.id);
const code = normalizeOptionalString(value.code);
const createdAt = normalizeOptionalString(value.createdAt);
const lastSeenAt = normalizeOptionalString(value.lastSeenAt) ?? createdAt;
if (!id || !code || !createdAt || !lastSeenAt || parseDateStringTimestampMs(createdAt) === void 0 || parseDateStringTimestampMs(lastSeenAt) === void 0) return;
const meta = normalizePersistedPairingMeta(value.meta);
return {
id,
code,
createdAt,
lastSeenAt,
...meta ? { meta } : {}
};
}
function readChannelAllowRows(database, channel) {
const db = getNodeSqliteKysely(database);
return executeSqliteQuerySync(database, db.selectFrom("channel_pairing_allow_entries").selectAll().where("channel_key", "=", safeChannelKey(channel)).orderBy("account_id", "asc").orderBy("sort_order", "asc").orderBy("entry", "asc")).rows;
}
function readChannelAllowEntries(database, channel) {
const rows = readChannelAllowRows(database, channel);
const allowFrom = {};
for (const row of rows) {
const accountId = resolveAllowFromAccountId(row.account_id);
(allowFrom[accountId] ??= []).push(row.entry);
}
return allowFrom;
}
function normalizePairingRequestRows(rows) {
return rows.flatMap((row) => {
let meta;
if (row.meta_json) try {
meta = normalizePersistedPairingMeta(JSON.parse(row.meta_json));
} catch {
meta = void 0;
}
meta = {
...meta,
accountId: resolveAllowFromAccountId(row.account_id)
};
const request = normalizePersistedPairingRequest({
id: row.request_id,
code: row.code,
createdAt: row.created_at,
lastSeenAt: row.last_seen_at,
meta
});
return request ? [request] : [];
});
}
function readChannelPairingRequests(database, channel) {
const db = getNodeSqliteKysely(database);
const rows = executeSqliteQuerySync(database, db.selectFrom("channel_pairing_requests").selectAll().where("channel_key", "=", safeChannelKey(channel)).orderBy("created_at", "asc").orderBy("account_id", "asc").orderBy("request_id", "asc")).rows;
return normalizePairingRequestRows(rows);
}
function readChannelPairingSnapshotFromDatabase(database, channel) {
const db = getNodeSqliteKysely(database.db);
const channelKey = safeChannelKey(channel);
const rows = executeSqliteQuerySync(database.db, db.selectFrom("channel_pairing_requests").select((eb) => [
"channel_key",
"account_id",
"request_id as record_id",
"code",
"created_at",
"last_seen_at",
"meta_json",
eb.val(0).as("sort_order"),
eb.val(0).as("updated_at"),
eb.val("request").as("kind")
]).where("channel_key", "=", channelKey).unionAll(db.selectFrom("channel_pairing_allow_entries").select((eb) => [
"channel_key",
"account_id",
"entry as record_id",
eb.val("").as("code"),
eb.val("").as("created_at"),
eb.val("").as("last_seen_at"),
eb.val(null).as("meta_json"),
"sort_order",
"updated_at",
eb.val("allow").as("kind")
]).where("channel_key", "=", channelKey)).orderBy("kind", "asc").orderBy("created_at", "asc").orderBy("account_id", "asc").orderBy("sort_order", "asc").orderBy("record_id", "asc")).rows;
const requestRows = [];
const allowRows = [];
for (const row of rows) if (row.kind === "request") requestRows.push({
channel_key: row.channel_key,
account_id: row.account_id,
request_id: row.record_id,
code: row.code,
created_at: row.created_at,
last_seen_at: row.last_seen_at,
meta_json: row.meta_json
});
else allowRows.push({
channel_key: row.channel_key,
account_id: row.account_id,
entry: row.record_id,
sort_order: row.sort_order,
updated_at: row.updated_at
});
const requests = normalizePairingRequestRows(requestRows);
const allowFrom = {};
for (const row of allowRows) (allowFrom[resolveAllowFromAccountId(row.account_id)] ??= []).push(row.entry);
return {
state: {
version: 1,
requests,
allowFrom
},
requestRows,
allowRows
};
}
function writeChannelPairingStateToDatabase(database, channel, state) {
const db = getNodeSqliteKysely(database.db);
const channelKey = safeChannelKey(channel);
executeSqliteQuerySync(database.db, db.deleteFrom("channel_pairing_requests").where("channel_key", "=", channelKey));
executeSqliteQuerySync(database.db, db.deleteFrom("channel_pairing_allow_entries").where("channel_key", "=", channelKey));
for (const request of state.requests) {
const normalized = normalizePersistedPairingRequest(request);
if (!normalized) continue;
executeSqliteQuerySync(database.db, db.insertInto("channel_pairing_requests").values({
channel_key: channelKey,
account_id: resolvePairingRequestAccountId(normalized),
request_id: normalized.id,
code: normalized.code,
created_at: normalized.createdAt,
last_seen_at: normalized.lastSeenAt,
meta_json: normalized.meta ? JSON.stringify(normalized.meta) : null
}));
}
const updatedAt = Date.now();
for (const [accountId, entries] of Object.entries(state.allowFrom ?? {})) {
const normalizedEntries = dedupePreserveOrder(entries.map((entry) => normalizeOptionalString(entry) ?? "").filter((entry) => entry && entry !== "*"));
for (const [sortOrder, entry] of normalizedEntries.entries()) executeSqliteQuerySync(database.db, db.insertInto("channel_pairing_allow_entries").values({
channel_key: channelKey,
account_id: resolveAllowFromAccountId(accountId),
entry,
sort_order: sortOrder,
updated_at: updatedAt
}));
}
}
function updateChannelPairingStateSnapshot(channel, env, update) {
return runOpenClawStateWriteTransaction((database) => {
const state = readChannelPairingSnapshotFromDatabase(database, channel).state;
const result = update(state);
writeChannelPairingStateToDatabase(database, channel, state);
return result;
}, { env });
}
//#endregion
export { updateChannelPairingStateSnapshot as a, readChannelPairingSnapshotFromDatabase as i, readChannelAllowEntries as n, readChannelPairingRequests as r, normalizePersistedPairingRequest as t };