feat: интеграция с VPS Tracker
Build, Test, and Push CFDM Docker Image / test (push) Failing after 3m36s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
Build, Test, and Push CFDM Docker Image / test (push) Failing after 3m36s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Has been skipped
Build, Test, and Push CFDM Docker Image / update-wiki (push) Has been skipped
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
Исходящий sync bindings после updateConfig, настройки в app_settings, страница Интеграции, приём событий vps_down для DNS failover. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Vendored
+180
-73
@@ -184,6 +184,18 @@ var ipHealthStatus = sqliteTable(
|
||||
},
|
||||
(t) => [primaryKey({ columns: [t.scope, t.ref_id, t.ip] })]
|
||||
);
|
||||
var appSettings = sqliteTable("app_settings", {
|
||||
id: text("id").primaryKey(),
|
||||
app_switcher_json: text("app_switcher_json"),
|
||||
vps_tracker_url: text("vps_tracker_url"),
|
||||
vps_tracker_integration_token: text("vps_tracker_integration_token"),
|
||||
vps_tracker_sync_enabled: integer("vps_tracker_sync_enabled", {
|
||||
mode: "boolean"
|
||||
}).notNull().default(false),
|
||||
vps_tracker_last_sync_at: text("vps_tracker_last_sync_at"),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
var schema = {
|
||||
groups,
|
||||
services,
|
||||
@@ -198,7 +210,8 @@ var schema = {
|
||||
serviceGroupDnsRecords,
|
||||
certificates,
|
||||
syncJobs,
|
||||
ipHealthStatus
|
||||
ipHealthStatus,
|
||||
appSettings
|
||||
};
|
||||
|
||||
// src/client.ts
|
||||
@@ -263,6 +276,94 @@ var ConflictError = class extends Error {
|
||||
}
|
||||
};
|
||||
|
||||
// src/settings-repo.ts
|
||||
import { eq } from "drizzle-orm";
|
||||
import { appSwitcherConfigSchema } from "@cfdm/shared";
|
||||
var SETTINGS_ID = "settings-main";
|
||||
var DEFAULT_APP_SWITCHER = {
|
||||
menuLabel: "\u041F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F",
|
||||
apps: [
|
||||
{
|
||||
id: "vps-tracker",
|
||||
name: "VPS Tracker",
|
||||
subtitle: "\u0423\u0447\u0451\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043B\u044C\u043D\u044B\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432",
|
||||
url: "http://192.168.100.67:3001",
|
||||
icon: "server",
|
||||
shortcut: "\u23181"
|
||||
},
|
||||
{
|
||||
id: "cfdm",
|
||||
name: "CF Domain Manager",
|
||||
subtitle: "\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0434\u043E\u043C\u0435\u043D\u0430\u043C\u0438",
|
||||
url: "http://192.168.100.67:6363",
|
||||
icon: "cloud",
|
||||
shortcut: "\u23182"
|
||||
}
|
||||
]
|
||||
};
|
||||
function parseAppSwitcher(raw) {
|
||||
if (!raw?.trim()) return DEFAULT_APP_SWITCHER;
|
||||
try {
|
||||
return appSwitcherConfigSchema.parse(JSON.parse(raw));
|
||||
} catch {
|
||||
return DEFAULT_APP_SWITCHER;
|
||||
}
|
||||
}
|
||||
function toDto(row) {
|
||||
return {
|
||||
id: row.id,
|
||||
appSwitcher: parseAppSwitcher(row.app_switcher_json),
|
||||
vpsTrackerUrl: row.vps_tracker_url?.trim() ?? "",
|
||||
vpsTrackerIntegrationTokenSet: Boolean(
|
||||
row.vps_tracker_integration_token?.trim()
|
||||
),
|
||||
vpsTrackerSyncEnabled: Boolean(row.vps_tracker_sync_enabled),
|
||||
vpsTrackerLastSyncAt: row.vps_tracker_last_sync_at
|
||||
};
|
||||
}
|
||||
function getAppSettings(db) {
|
||||
const row = db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
if (!row) {
|
||||
db.insert(appSettings).values({ id: SETTINGS_ID }).run();
|
||||
return toDto(
|
||||
db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get()
|
||||
);
|
||||
}
|
||||
return toDto(row);
|
||||
}
|
||||
function getAppSettingsSecrets(db) {
|
||||
const row = db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
return {
|
||||
vpsTrackerUrl: row?.vps_tracker_url?.trim() ?? "",
|
||||
vpsTrackerIntegrationToken: row?.vps_tracker_integration_token?.trim() ?? "",
|
||||
vpsTrackerSyncEnabled: Boolean(row?.vps_tracker_sync_enabled)
|
||||
};
|
||||
}
|
||||
function updateAppSettings(db, patch) {
|
||||
const existing = db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
if (!existing) {
|
||||
db.insert(appSettings).values({ id: SETTINGS_ID }).run();
|
||||
}
|
||||
const current = db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
db.update(appSettings).set({
|
||||
app_switcher_json: patch.appSwitcher !== void 0 ? JSON.stringify(patch.appSwitcher) : current.app_switcher_json,
|
||||
vps_tracker_url: patch.vpsTrackerUrl !== void 0 ? patch.vpsTrackerUrl : current.vps_tracker_url,
|
||||
vps_tracker_integration_token: patch.vpsTrackerIntegrationToken !== void 0 && patch.vpsTrackerIntegrationToken.trim() !== "" ? patch.vpsTrackerIntegrationToken : current.vps_tracker_integration_token,
|
||||
vps_tracker_sync_enabled: patch.vpsTrackerSyncEnabled !== void 0 ? patch.vpsTrackerSyncEnabled : current.vps_tracker_sync_enabled,
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
||||
}).where(eq(appSettings.id, SETTINGS_ID)).run();
|
||||
return getAppSettings(db);
|
||||
}
|
||||
function touchVpsTrackerSync(db) {
|
||||
db.update(appSettings).set({
|
||||
vps_tracker_last_sync_at: (/* @__PURE__ */ new Date()).toISOString(),
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
||||
}).where(eq(appSettings.id, SETTINGS_ID)).run();
|
||||
}
|
||||
function getAppSwitcher(db) {
|
||||
return getAppSettings(db).appSwitcher;
|
||||
}
|
||||
|
||||
// src/repos.ts
|
||||
var repos_exports = {};
|
||||
__export(repos_exports, {
|
||||
@@ -357,12 +458,12 @@ __export(repos_exports, {
|
||||
upsertSubdomain: () => upsertSubdomain
|
||||
});
|
||||
import { dnsRecordNamesMatch } from "@cfdm/shared";
|
||||
import { and, asc, count, eq, isNull, like, notInArray, or, sql as sql2 } from "drizzle-orm";
|
||||
import { and, asc, count, eq as eq2, isNull, like, notInArray, or, sql as sql2 } from "drizzle-orm";
|
||||
function listGroups(db) {
|
||||
return db.select().from(groups).orderBy(asc(groups.name)).all();
|
||||
}
|
||||
function getGroup(db, id) {
|
||||
const row = db.select().from(groups).where(eq(groups.id, id)).get();
|
||||
const row = db.select().from(groups).where(eq2(groups.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`group ${id}`);
|
||||
return row;
|
||||
}
|
||||
@@ -380,17 +481,17 @@ function createGroup(db, name, slug) {
|
||||
return getGroup(db, id);
|
||||
}
|
||||
function updateGroup(db, id, name, slug) {
|
||||
const result = db.update(groups).set({ name, slug, updated_at: sql2`datetime('now')` }).where(eq(groups.id, id)).run();
|
||||
const result = db.update(groups).set({ name, slug, updated_at: sql2`datetime('now')` }).where(eq2(groups.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`group ${id}`);
|
||||
return getGroup(db, id);
|
||||
}
|
||||
function deleteGroup(db, id) {
|
||||
const result = db.delete(groups).where(eq(groups.id, id)).run();
|
||||
const result = db.delete(groups).where(eq2(groups.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`group ${id}`);
|
||||
}
|
||||
function listDomains(db, groupId) {
|
||||
if (groupId != null) {
|
||||
return db.select().from(domains).where(eq(domains.group_id, groupId)).orderBy(asc(domains.zone_name)).all();
|
||||
return db.select().from(domains).where(eq2(domains.group_id, groupId)).orderBy(asc(domains.zone_name)).all();
|
||||
}
|
||||
return db.select().from(domains).orderBy(asc(domains.zone_name)).all();
|
||||
}
|
||||
@@ -412,7 +513,7 @@ function findDomainByZoneName(db, zoneName) {
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
function getDomain(db, id) {
|
||||
const row = db.select().from(domains).where(eq(domains.id, id)).get();
|
||||
const row = db.select().from(domains).where(eq2(domains.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`domain ${id}`);
|
||||
return row;
|
||||
}
|
||||
@@ -433,33 +534,33 @@ function updateDomain(db, id, groupId, status, certMonitoring) {
|
||||
if (certMonitoring !== void 0) {
|
||||
updates.cert_monitoring = certMonitoring;
|
||||
}
|
||||
const result = db.update(domains).set(updates).where(eq(domains.id, id)).run();
|
||||
const result = db.update(domains).set(updates).where(eq2(domains.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`domain ${id}`);
|
||||
return getDomain(db, id);
|
||||
}
|
||||
function deleteDomain(db, id) {
|
||||
const result = db.delete(domains).where(eq(domains.id, id)).run();
|
||||
const result = db.delete(domains).where(eq2(domains.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`domain ${id}`);
|
||||
}
|
||||
function setDomainLastSynced(db, id) {
|
||||
db.update(domains).set({
|
||||
last_synced_at: sql2`datetime('now')`,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(domains.id, id)).run();
|
||||
}).where(eq2(domains.id, id)).run();
|
||||
}
|
||||
function listAllDomains(db) {
|
||||
return listDomains(db);
|
||||
}
|
||||
function listSubdomainsByDomain(db, domainId) {
|
||||
return db.select().from(subdomains).where(eq(subdomains.domain_id, domainId)).orderBy(asc(subdomains.name)).all();
|
||||
return db.select().from(subdomains).where(eq2(subdomains.domain_id, domainId)).orderBy(asc(subdomains.name)).all();
|
||||
}
|
||||
function getSubdomain(db, id) {
|
||||
const row = db.select().from(subdomains).where(eq(subdomains.id, id)).get();
|
||||
const row = db.select().from(subdomains).where(eq2(subdomains.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`subdomain ${id}`);
|
||||
return row;
|
||||
}
|
||||
function findSubdomainByDomainAndName(db, domainId, name) {
|
||||
const row = db.select().from(subdomains).where(and(eq(subdomains.domain_id, domainId), eq(subdomains.name, name))).get();
|
||||
const row = db.select().from(subdomains).where(and(eq2(subdomains.domain_id, domainId), eq2(subdomains.name, name))).get();
|
||||
return row ?? null;
|
||||
}
|
||||
function upsertSubdomain(db, domainId, name, fqdn) {
|
||||
@@ -483,12 +584,12 @@ function updateSubdomain(db, id, patch) {
|
||||
if (patch.cert_monitoring !== void 0) {
|
||||
updates.cert_monitoring = patch.cert_monitoring;
|
||||
}
|
||||
const result = db.update(subdomains).set(updates).where(eq(subdomains.id, id)).run();
|
||||
const result = db.update(subdomains).set(updates).where(eq2(subdomains.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`subdomain ${id}`);
|
||||
return getSubdomain(db, id);
|
||||
}
|
||||
function deleteSubdomain(db, id) {
|
||||
const result = db.delete(subdomains).where(eq(subdomains.id, id)).run();
|
||||
const result = db.delete(subdomains).where(eq2(subdomains.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`subdomain ${id}`);
|
||||
}
|
||||
function listAllSubdomains(db) {
|
||||
@@ -498,9 +599,9 @@ function mapDnsRecord(row) {
|
||||
return row;
|
||||
}
|
||||
function listDnsRecords(db, domainId, filter = {}) {
|
||||
const conditions = [eq(dnsRecords.domain_id, domainId)];
|
||||
const conditions = [eq2(dnsRecords.domain_id, domainId)];
|
||||
if (filter.record_type) {
|
||||
conditions.push(eq(dnsRecords.record_type, filter.record_type.toUpperCase()));
|
||||
conditions.push(eq2(dnsRecords.record_type, filter.record_type.toUpperCase()));
|
||||
}
|
||||
if (filter.name) {
|
||||
conditions.push(like(dnsRecords.name, `%${filter.name}%`));
|
||||
@@ -509,10 +610,10 @@ function listDnsRecords(db, domainId, filter = {}) {
|
||||
conditions.push(like(dnsRecords.content, `%${filter.content}%`));
|
||||
}
|
||||
if (filter.proxied != null) {
|
||||
conditions.push(eq(dnsRecords.proxied, filter.proxied));
|
||||
conditions.push(eq2(dnsRecords.proxied, filter.proxied));
|
||||
}
|
||||
if (filter.sync_status) {
|
||||
conditions.push(eq(dnsRecords.sync_status, filter.sync_status));
|
||||
conditions.push(eq2(dnsRecords.sync_status, filter.sync_status));
|
||||
}
|
||||
if (filter.q) {
|
||||
const pat = `%${filter.q}%`;
|
||||
@@ -531,7 +632,7 @@ function listDnsRecords(db, domainId, filter = {}) {
|
||||
return db.select().from(dnsRecords).where(and(...conditions)).orderBy(asc(sortCol)).limit(limit).offset(offset).all().map(mapDnsRecord);
|
||||
}
|
||||
function getDnsRecord(db, domainId, id) {
|
||||
const row = db.select().from(dnsRecords).where(and(eq(dnsRecords.id, id), eq(dnsRecords.domain_id, domainId))).get();
|
||||
const row = db.select().from(dnsRecords).where(and(eq2(dnsRecords.id, id), eq2(dnsRecords.domain_id, domainId))).get();
|
||||
if (!row) throw new NotFoundError(`dns record ${id}`);
|
||||
return mapDnsRecord(row);
|
||||
}
|
||||
@@ -562,7 +663,7 @@ function updateDnsFields(db, id, recordType, name, content, ttl, proxied, priori
|
||||
sync_status: syncStatus,
|
||||
last_error: lastError,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(dnsRecords.id, id)).run();
|
||||
}).where(eq2(dnsRecords.id, id)).run();
|
||||
}
|
||||
function setDnsSyncStatus(db, id, syncStatus, cfRecordId, lastError) {
|
||||
db.update(dnsRecords).set({
|
||||
@@ -570,19 +671,19 @@ function setDnsSyncStatus(db, id, syncStatus, cfRecordId, lastError) {
|
||||
cf_record_id: cfRecordId,
|
||||
last_error: lastError,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(dnsRecords.id, id)).run();
|
||||
}).where(eq2(dnsRecords.id, id)).run();
|
||||
}
|
||||
function deleteDnsRecord(db, id) {
|
||||
db.delete(dnsRecords).where(eq(dnsRecords.id, id)).run();
|
||||
db.delete(dnsRecords).where(eq2(dnsRecords.id, id)).run();
|
||||
}
|
||||
function listDnsByDomain(db, domainId) {
|
||||
return db.select().from(dnsRecords).where(eq(dnsRecords.domain_id, domainId)).all().map(mapDnsRecord);
|
||||
return db.select().from(dnsRecords).where(eq2(dnsRecords.domain_id, domainId)).all().map(mapDnsRecord);
|
||||
}
|
||||
function findDnsByCfId(db, domainId, cfRecordId) {
|
||||
const row = db.select().from(dnsRecords).where(
|
||||
and(
|
||||
eq(dnsRecords.domain_id, domainId),
|
||||
eq(dnsRecords.cf_record_id, cfRecordId)
|
||||
eq2(dnsRecords.domain_id, domainId),
|
||||
eq2(dnsRecords.cf_record_id, cfRecordId)
|
||||
)
|
||||
).get();
|
||||
return row ? mapDnsRecord(row) : null;
|
||||
@@ -591,7 +692,7 @@ function markDnsPendingDelete(db, id) {
|
||||
setDnsSyncStatus(db, id, "pending_delete", null, null);
|
||||
}
|
||||
function maxSortOrderInGroup(db, groupId) {
|
||||
const condition = groupId === null ? isNull(services.service_group_id) : eq(services.service_group_id, groupId);
|
||||
const condition = groupId === null ? isNull(services.service_group_id) : eq2(services.service_group_id, groupId);
|
||||
const row = db.select({ maxOrder: sql2`coalesce(max(${services.sort_order}), -1)` }).from(services).where(condition).get();
|
||||
return row?.maxOrder ?? -1;
|
||||
}
|
||||
@@ -599,13 +700,13 @@ function listServices(db) {
|
||||
return db.select().from(services).orderBy(asc(services.sort_order), asc(services.name)).all();
|
||||
}
|
||||
function listServicesByGroup(db, groupId) {
|
||||
return db.select().from(services).where(eq(services.service_group_id, groupId)).orderBy(asc(services.sort_order), asc(services.name)).all();
|
||||
return db.select().from(services).where(eq2(services.service_group_id, groupId)).orderBy(asc(services.sort_order), asc(services.name)).all();
|
||||
}
|
||||
function listUngroupedServices(db) {
|
||||
return db.select().from(services).where(isNull(services.service_group_id)).orderBy(asc(services.sort_order), asc(services.name)).all();
|
||||
}
|
||||
function getService(db, id) {
|
||||
const row = db.select().from(services).where(eq(services.id, id)).get();
|
||||
const row = db.select().from(services).where(eq2(services.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`service ${id}`);
|
||||
return row;
|
||||
}
|
||||
@@ -620,11 +721,11 @@ function updateService(db, id, name, slug) {
|
||||
slug,
|
||||
subdomain: slug,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(services.id, id)).run();
|
||||
}).where(eq2(services.id, id)).run();
|
||||
return getService(db, id);
|
||||
}
|
||||
function setServiceEnabled(db, id, enabled) {
|
||||
db.update(services).set({ enabled, updated_at: sql2`datetime('now')` }).where(eq(services.id, id)).run();
|
||||
db.update(services).set({ enabled, updated_at: sql2`datetime('now')` }).where(eq2(services.id, id)).run();
|
||||
return getService(db, id);
|
||||
}
|
||||
function setServiceLb(db, id, weight, priority) {
|
||||
@@ -632,7 +733,7 @@ function setServiceLb(db, id, weight, priority) {
|
||||
lb_weight: weight,
|
||||
lb_priority: priority,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(services.id, id)).run();
|
||||
}).where(eq2(services.id, id)).run();
|
||||
}
|
||||
function setServiceGroup(db, id, groupId) {
|
||||
const sortOrder = maxSortOrderInGroup(db, groupId) + 1;
|
||||
@@ -640,14 +741,14 @@ function setServiceGroup(db, id, groupId) {
|
||||
service_group_id: groupId,
|
||||
sort_order: sortOrder,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(services.id, id)).run();
|
||||
}).where(eq2(services.id, id)).run();
|
||||
}
|
||||
function reorderServices(db, groupId, orderedIds) {
|
||||
const uniqueIds = new Set(orderedIds);
|
||||
if (uniqueIds.size !== orderedIds.length) {
|
||||
throw new Error("duplicate service ids in reorder request");
|
||||
}
|
||||
const condition = groupId === null ? isNull(services.service_group_id) : eq(services.service_group_id, groupId);
|
||||
const condition = groupId === null ? isNull(services.service_group_id) : eq2(services.service_group_id, groupId);
|
||||
const existing = db.select({ id: services.id }).from(services).where(condition).all().map((row) => row.id);
|
||||
const existingSet = new Set(existing);
|
||||
for (const serviceId of orderedIds) {
|
||||
@@ -657,12 +758,12 @@ function reorderServices(db, groupId, orderedIds) {
|
||||
}
|
||||
db.transaction((tx) => {
|
||||
for (let index = 0; index < orderedIds.length; index++) {
|
||||
tx.update(services).set({ sort_order: index, updated_at: sql2`datetime('now')` }).where(eq(services.id, orderedIds[index])).run();
|
||||
tx.update(services).set({ sort_order: index, updated_at: sql2`datetime('now')` }).where(eq2(services.id, orderedIds[index])).run();
|
||||
}
|
||||
});
|
||||
}
|
||||
function deleteService(db, id) {
|
||||
const result = db.delete(services).where(eq(services.id, id)).run();
|
||||
const result = db.delete(services).where(eq2(services.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`service ${id}`);
|
||||
}
|
||||
function mapServiceGroup(row) {
|
||||
@@ -689,7 +790,7 @@ function listServiceGroups(db) {
|
||||
return db.select().from(serviceGroups).orderBy(asc(serviceGroups.name)).all().map(mapServiceGroup);
|
||||
}
|
||||
function getServiceGroup(db, id) {
|
||||
const row = db.select().from(serviceGroups).where(eq(serviceGroups.id, id)).get();
|
||||
const row = db.select().from(serviceGroups).where(eq2(serviceGroups.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`service group ${id}`);
|
||||
return mapServiceGroup(row);
|
||||
}
|
||||
@@ -735,37 +836,37 @@ function updateServiceGroup(db, id, name, groupType, icon, domain, lbPatch) {
|
||||
if (lbPatch.health_check_timeout_ms !== void 0)
|
||||
update.health_check_timeout_ms = lbPatch.health_check_timeout_ms;
|
||||
}
|
||||
const result = db.update(serviceGroups).set(update).where(eq(serviceGroups.id, id)).run();
|
||||
const result = db.update(serviceGroups).set(update).where(eq2(serviceGroups.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`service group ${id}`);
|
||||
return getServiceGroup(db, id);
|
||||
}
|
||||
function setServiceGroupEnabled(db, id, enabled) {
|
||||
const result = db.update(serviceGroups).set({ enabled, updated_at: sql2`datetime('now')` }).where(eq(serviceGroups.id, id)).run();
|
||||
const result = db.update(serviceGroups).set({ enabled, updated_at: sql2`datetime('now')` }).where(eq2(serviceGroups.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`service group ${id}`);
|
||||
return getServiceGroup(db, id);
|
||||
}
|
||||
function deleteServiceGroup(db, id) {
|
||||
const result = db.delete(serviceGroups).where(eq(serviceGroups.id, id)).run();
|
||||
const result = db.delete(serviceGroups).where(eq2(serviceGroups.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`service group ${id}`);
|
||||
}
|
||||
function listServiceIps(db, serviceId) {
|
||||
return db.select({ ip: serviceIps.ip }).from(serviceIps).where(eq(serviceIps.service_id, serviceId)).all().map((r) => r.ip);
|
||||
return db.select({ ip: serviceIps.ip }).from(serviceIps).where(eq2(serviceIps.service_id, serviceId)).all().map((r) => r.ip);
|
||||
}
|
||||
function replaceServiceIps(db, serviceId, ips) {
|
||||
db.delete(serviceIps).where(eq(serviceIps.service_id, serviceId)).run();
|
||||
db.delete(serviceIps).where(eq2(serviceIps.service_id, serviceId)).run();
|
||||
for (const ip of ips) {
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip }).run();
|
||||
}
|
||||
}
|
||||
function listBindingIps(db, bindingId) {
|
||||
return db.select({ ip: serviceBindingIps.ip }).from(serviceBindingIps).where(eq(serviceBindingIps.binding_id, bindingId)).all().map((r) => r.ip);
|
||||
return db.select({ ip: serviceBindingIps.ip }).from(serviceBindingIps).where(eq2(serviceBindingIps.binding_id, bindingId)).all().map((r) => r.ip);
|
||||
}
|
||||
function listBindingIpsWithMeta(db, bindingId) {
|
||||
return db.select({
|
||||
ip: serviceBindingIps.ip,
|
||||
weight: serviceBindingIps.weight,
|
||||
priority: serviceBindingIps.priority
|
||||
}).from(serviceBindingIps).where(eq(serviceBindingIps.binding_id, bindingId)).all();
|
||||
}).from(serviceBindingIps).where(eq2(serviceBindingIps.binding_id, bindingId)).all();
|
||||
}
|
||||
function replaceBindingIps(db, bindingId, ips) {
|
||||
replaceBindingIpsWithMeta(
|
||||
@@ -775,7 +876,7 @@ function replaceBindingIps(db, bindingId, ips) {
|
||||
);
|
||||
}
|
||||
function replaceBindingIpsWithMeta(db, bindingId, entries) {
|
||||
db.delete(serviceBindingIps).where(eq(serviceBindingIps.binding_id, bindingId)).run();
|
||||
db.delete(serviceBindingIps).where(eq2(serviceBindingIps.binding_id, bindingId)).run();
|
||||
for (const entry of entries) {
|
||||
db.insert(serviceBindingIps).values({
|
||||
binding_id: bindingId,
|
||||
@@ -804,13 +905,13 @@ function updateBindingLbConfig(db, bindingId, patch) {
|
||||
update.health_check_interval_sec = patch.health_check_interval_sec;
|
||||
if (patch.health_check_timeout_ms !== void 0)
|
||||
update.health_check_timeout_ms = patch.health_check_timeout_ms;
|
||||
db.update(serviceBindings).set(update).where(eq(serviceBindings.id, bindingId)).run();
|
||||
db.update(serviceBindings).set(update).where(eq2(serviceBindings.id, bindingId)).run();
|
||||
}
|
||||
function setBindingCnameTarget(db, bindingId, target) {
|
||||
db.update(serviceBindings).set({
|
||||
cname_target: target,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(serviceBindings.id, bindingId)).run();
|
||||
}).where(eq2(serviceBindings.id, bindingId)).run();
|
||||
}
|
||||
function listRecordsForBinding(db, bindingId) {
|
||||
return db.all(sql2`
|
||||
@@ -829,8 +930,8 @@ function linkBindingRecord(db, bindingId, dnsRecordId) {
|
||||
function unlinkBindingRecord(db, bindingId, dnsRecordId) {
|
||||
db.delete(serviceBindingRecords).where(
|
||||
and(
|
||||
eq(serviceBindingRecords.binding_id, bindingId),
|
||||
eq(serviceBindingRecords.dns_record_id, dnsRecordId)
|
||||
eq2(serviceBindingRecords.binding_id, bindingId),
|
||||
eq2(serviceBindingRecords.dns_record_id, dnsRecordId)
|
||||
)
|
||||
).run();
|
||||
}
|
||||
@@ -851,8 +952,8 @@ function linkGroupDnsRecord(db, groupId, dnsRecordId) {
|
||||
function unlinkGroupDnsRecord(db, groupId, dnsRecordId) {
|
||||
db.delete(serviceGroupDnsRecords).where(
|
||||
and(
|
||||
eq(serviceGroupDnsRecords.group_id, groupId),
|
||||
eq(serviceGroupDnsRecords.dns_record_id, dnsRecordId)
|
||||
eq2(serviceGroupDnsRecords.group_id, groupId),
|
||||
eq2(serviceGroupDnsRecords.dns_record_id, dnsRecordId)
|
||||
)
|
||||
).run();
|
||||
}
|
||||
@@ -942,7 +1043,7 @@ function listBindingsByService(db, serviceId) {
|
||||
`);
|
||||
}
|
||||
function getBinding(db, id) {
|
||||
const row = db.select().from(serviceBindings).where(eq(serviceBindings.id, id)).get();
|
||||
const row = db.select().from(serviceBindings).where(eq2(serviceBindings.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`service binding ${id}`);
|
||||
return row;
|
||||
}
|
||||
@@ -962,9 +1063,9 @@ function getBindingView(db, id) {
|
||||
function findBinding(db, serviceId, domainId, hostname) {
|
||||
const row = db.select().from(serviceBindings).where(
|
||||
and(
|
||||
eq(serviceBindings.service_id, serviceId),
|
||||
eq(serviceBindings.domain_id, domainId),
|
||||
eq(serviceBindings.hostname, hostname)
|
||||
eq2(serviceBindings.service_id, serviceId),
|
||||
eq2(serviceBindings.domain_id, domainId),
|
||||
eq2(serviceBindings.hostname, hostname)
|
||||
)
|
||||
).get();
|
||||
return row ?? null;
|
||||
@@ -984,43 +1085,43 @@ function updateBindingFields(db, id, serviceId, hostname, dnsRecordId) {
|
||||
hostname,
|
||||
dns_record_id: dnsRecordId,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(serviceBindings.id, id)).run();
|
||||
}).where(eq2(serviceBindings.id, id)).run();
|
||||
}
|
||||
function setBindingDnsRecordId(db, bindingId, dnsRecordId) {
|
||||
db.update(serviceBindings).set({
|
||||
dns_record_id: dnsRecordId,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(serviceBindings.id, bindingId)).run();
|
||||
}).where(eq2(serviceBindings.id, bindingId)).run();
|
||||
}
|
||||
function bindingsToRemove(db, serviceId, keepIds) {
|
||||
const all = db.select().from(serviceBindings).where(eq(serviceBindings.service_id, serviceId)).all();
|
||||
const all = db.select().from(serviceBindings).where(eq2(serviceBindings.service_id, serviceId)).all();
|
||||
return all.filter((b) => !keepIds.includes(b.id));
|
||||
}
|
||||
function deleteBindingsExcept(db, serviceId, keepIds) {
|
||||
const all = db.select().from(serviceBindings).where(eq(serviceBindings.service_id, serviceId)).all();
|
||||
const all = db.select().from(serviceBindings).where(eq2(serviceBindings.service_id, serviceId)).all();
|
||||
for (const binding of all) {
|
||||
if (!keepIds.includes(binding.id)) {
|
||||
db.delete(serviceBindings).where(eq(serviceBindings.id, binding.id)).run();
|
||||
db.delete(serviceBindings).where(eq2(serviceBindings.id, binding.id)).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
function deleteBinding(db, id) {
|
||||
const result = db.delete(serviceBindings).where(eq(serviceBindings.id, id)).run();
|
||||
const result = db.delete(serviceBindings).where(eq2(serviceBindings.id, id)).run();
|
||||
if (result.changes === 0) throw new NotFoundError(`service binding ${id}`);
|
||||
}
|
||||
function listCertificates(db, status) {
|
||||
if (status) {
|
||||
return db.select().from(certificates).where(eq(certificates.status, status)).orderBy(asc(certificates.expires_at)).all();
|
||||
return db.select().from(certificates).where(eq2(certificates.status, status)).orderBy(asc(certificates.expires_at)).all();
|
||||
}
|
||||
return db.select().from(certificates).orderBy(asc(certificates.expires_at)).all();
|
||||
}
|
||||
function getCertificate(db, id) {
|
||||
const row = db.select().from(certificates).where(eq(certificates.id, id)).get();
|
||||
const row = db.select().from(certificates).where(eq2(certificates.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`certificate ${id}`);
|
||||
return row;
|
||||
}
|
||||
function upsertCertificateCheck(db, domainId, subdomainId, hostname, expiresAt, status, lastError) {
|
||||
const existing = db.select().from(certificates).where(eq(certificates.hostname, hostname)).get();
|
||||
const existing = db.select().from(certificates).where(eq2(certificates.hostname, hostname)).get();
|
||||
if (existing) {
|
||||
db.update(certificates).set({
|
||||
domain_id: domainId,
|
||||
@@ -1030,7 +1131,7 @@ function upsertCertificateCheck(db, domainId, subdomainId, hostname, expiresAt,
|
||||
last_error: lastError,
|
||||
status,
|
||||
updated_at: sql2`datetime('now')`
|
||||
}).where(eq(certificates.id, existing.id)).run();
|
||||
}).where(eq2(certificates.id, existing.id)).run();
|
||||
return getCertificate(db, existing.id);
|
||||
}
|
||||
const id = db.insert(certificates).values({
|
||||
@@ -1063,7 +1164,7 @@ function createSyncJob(db, id, domainId) {
|
||||
db.insert(syncJobs).values({ id, domain_id: domainId, status: "pending" }).run();
|
||||
}
|
||||
function getSyncJob(db, id) {
|
||||
const row = db.select().from(syncJobs).where(eq(syncJobs.id, id)).get();
|
||||
const row = db.select().from(syncJobs).where(eq2(syncJobs.id, id)).get();
|
||||
if (!row) throw new NotFoundError(`sync job ${id}`);
|
||||
return row;
|
||||
}
|
||||
@@ -1072,7 +1173,7 @@ function finishSyncJob(db, id, status, message) {
|
||||
status,
|
||||
message,
|
||||
finished_at: sql2`datetime('now')`
|
||||
}).where(eq(syncJobs.id, id)).run();
|
||||
}).where(eq2(syncJobs.id, id)).run();
|
||||
}
|
||||
function listIpHealthStatus(db, scope, refId) {
|
||||
return db.all(sql2`
|
||||
@@ -1111,17 +1212,17 @@ function upsertIpHealthStatus(db, scope, refId, ip, status, latencyMs, consecuti
|
||||
function deleteIpHealthStatusForRef(db, scope, refId) {
|
||||
db.delete(ipHealthStatus).where(
|
||||
and(
|
||||
eq(ipHealthStatus.scope, scope),
|
||||
eq(ipHealthStatus.ref_id, refId)
|
||||
eq2(ipHealthStatus.scope, scope),
|
||||
eq2(ipHealthStatus.ref_id, refId)
|
||||
)
|
||||
).run();
|
||||
}
|
||||
function deleteIpHealthStatusForIp(db, scope, refId, ip) {
|
||||
db.delete(ipHealthStatus).where(
|
||||
and(
|
||||
eq(ipHealthStatus.scope, scope),
|
||||
eq(ipHealthStatus.ref_id, refId),
|
||||
eq(ipHealthStatus.ip, ip)
|
||||
eq2(ipHealthStatus.scope, scope),
|
||||
eq2(ipHealthStatus.ref_id, refId),
|
||||
eq2(ipHealthStatus.ip, ip)
|
||||
)
|
||||
).run();
|
||||
}
|
||||
@@ -1222,11 +1323,15 @@ function listHealthCheckTargets(db) {
|
||||
export {
|
||||
ConflictError,
|
||||
NotFoundError,
|
||||
appSettings,
|
||||
certificates,
|
||||
createDb,
|
||||
createMemoryDb,
|
||||
dnsRecords,
|
||||
domains,
|
||||
getAppSettings,
|
||||
getAppSettingsSecrets,
|
||||
getAppSwitcher,
|
||||
groups,
|
||||
healthCheck,
|
||||
ipHealthStatus,
|
||||
@@ -1242,5 +1347,7 @@ export {
|
||||
serviceIps,
|
||||
services,
|
||||
subdomains,
|
||||
syncJobs
|
||||
syncJobs,
|
||||
touchVpsTrackerSync,
|
||||
updateAppSettings
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user