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
+340
-2
@@ -1,7 +1,7 @@
|
||||
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
||||
import Database from 'better-sqlite3';
|
||||
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
||||
import { LbMode, HealthCheckType, ServiceBinding, Domain, Group, Service, ServiceGroup, Subdomain, HealthCheckScope, DnsRecord, ServiceBindingView, Certificate, GroupWithStats, IpHealthStatus, SyncJob, DomainListItem, HealthCheckTarget } from '@cfdm/shared';
|
||||
import { AppSwitcherConfig, LbMode, HealthCheckType, ServiceBinding, Domain, Group, Service, ServiceGroup, Subdomain, HealthCheckScope, DnsRecord, ServiceBindingView, Certificate, GroupWithStats, IpHealthStatus, SyncJob, DomainListItem, HealthCheckTarget } from '@cfdm/shared';
|
||||
|
||||
declare const groups: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "groups";
|
||||
@@ -2226,6 +2226,163 @@ declare const ipHealthStatus: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
declare const appSettings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "app_settings";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "id";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: true;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
app_switcher_json: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "app_switcher_json";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_url: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_url";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_integration_token: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_integration_token";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_sync_enabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_sync_enabled";
|
||||
tableName: "app_settings";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
vps_tracker_last_sync_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_last_sync_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
updated_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "updated_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
declare const schema: {
|
||||
groups: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "groups";
|
||||
@@ -4450,6 +4607,163 @@ declare const schema: {
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
appSettings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "app_settings";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "id";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: true;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
app_switcher_json: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "app_switcher_json";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_url: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_url";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_integration_token: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_integration_token";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
vps_tracker_sync_enabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_sync_enabled";
|
||||
tableName: "app_settings";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
vps_tracker_last_sync_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "vps_tracker_last_sync_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
updated_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "updated_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
};
|
||||
|
||||
type Sqlite = Database.Database;
|
||||
@@ -4473,6 +4787,30 @@ declare class ConflictError extends Error {
|
||||
constructor(message: string);
|
||||
}
|
||||
|
||||
type AppSettingsDto = {
|
||||
id: string;
|
||||
appSwitcher: AppSwitcherConfig;
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationTokenSet: boolean;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
vpsTrackerLastSyncAt: string | null;
|
||||
};
|
||||
type AppSettingsPatch = {
|
||||
appSwitcher?: AppSwitcherConfig;
|
||||
vpsTrackerUrl?: string;
|
||||
vpsTrackerIntegrationToken?: string;
|
||||
vpsTrackerSyncEnabled?: boolean;
|
||||
};
|
||||
declare function getAppSettings(db: Db): AppSettingsDto;
|
||||
declare function getAppSettingsSecrets(db: Db): {
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationToken: string;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
};
|
||||
declare function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto;
|
||||
declare function touchVpsTrackerSync(db: Db): void;
|
||||
declare function getAppSwitcher(db: Db): AppSwitcherConfig;
|
||||
|
||||
interface DnsListFilter {
|
||||
record_type?: string;
|
||||
name?: string;
|
||||
@@ -4705,4 +5043,4 @@ declare namespace repos {
|
||||
export { type repos_BindingIpMeta as BindingIpMeta, type repos_BindingLbPatch as BindingLbPatch, type repos_DnsListFilter as DnsListFilter, type repos_ServiceGroupLbPatch as ServiceGroupLbPatch, type repos_UpdateSubdomainPatch as UpdateSubdomainPatch, repos_bindingsToRemove as bindingsToRemove, repos_countCertificatesByStatus as countCertificatesByStatus, repos_createDomain as createDomain, repos_createGroup as createGroup, repos_createService as createService, repos_createServiceGroup as createServiceGroup, repos_createSubdomain as createSubdomain, repos_createSyncJob as createSyncJob, repos_deleteBinding as deleteBinding, repos_deleteBindingsExcept as deleteBindingsExcept, repos_deleteCertificatesNotIn as deleteCertificatesNotIn, repos_deleteDnsRecord as deleteDnsRecord, repos_deleteDomain as deleteDomain, repos_deleteGroup as deleteGroup, repos_deleteIpHealthStatusForIp as deleteIpHealthStatusForIp, repos_deleteIpHealthStatusForRef as deleteIpHealthStatusForRef, repos_deleteService as deleteService, repos_deleteServiceGroup as deleteServiceGroup, repos_deleteSubdomain as deleteSubdomain, repos_findBinding as findBinding, repos_findDnsByCfId as findDnsByCfId, repos_findDomainByZoneName as findDomainByZoneName, repos_findSubdomainByDomainAndName as findSubdomainByDomainAndName, repos_finishSyncJob as finishSyncJob, repos_getBinding as getBinding, repos_getBindingView as getBindingView, repos_getCertificate as getCertificate, repos_getDnsRecord as getDnsRecord, repos_getDomain as getDomain, repos_getGroup as getGroup, repos_getGroupWithStats as getGroupWithStats, repos_getIpHealthStatusRow as getIpHealthStatusRow, repos_getService as getService, repos_getServiceGroup as getServiceGroup, repos_getSubdomain as getSubdomain, repos_getSyncJob as getSyncJob, repos_insertBinding as insertBinding, repos_insertDnsRecord as insertDnsRecord, repos_linkBindingRecord as linkBindingRecord, repos_linkGroupDnsRecord as linkGroupDnsRecord, repos_listAllBindings as listAllBindings, repos_listAllDomains as listAllDomains, repos_listAllSubdomains as listAllSubdomains, repos_listBindingIps as listBindingIps, repos_listBindingIpsWithMeta as listBindingIpsWithMeta, repos_listBindingsByDomain as listBindingsByDomain, repos_listBindingsByService as listBindingsByService, repos_listCertificates as listCertificates, repos_listDnsByDomain as listDnsByDomain, repos_listDnsRecords as listDnsRecords, repos_listDomains as listDomains, repos_listDomainsEnriched as listDomainsEnriched, repos_listGroupDnsRecords as listGroupDnsRecords, repos_listGroups as listGroups, repos_listHealthCheckTargets as listHealthCheckTargets, repos_listIpHealthStatus as listIpHealthStatus, repos_listRecordsForBinding as listRecordsForBinding, repos_listServiceGroups as listServiceGroups, repos_listServiceIps as listServiceIps, repos_listServices as listServices, repos_listServicesByGroup as listServicesByGroup, repos_listSubdomainsByDomain as listSubdomainsByDomain, repos_listUngroupedServices as listUngroupedServices, repos_markDnsPendingDelete as markDnsPendingDelete, repos_reorderServices as reorderServices, repos_replaceBindingIps as replaceBindingIps, repos_replaceBindingIpsWithMeta as replaceBindingIpsWithMeta, repos_replaceServiceIps as replaceServiceIps, repos_setBindingCnameTarget as setBindingCnameTarget, repos_setBindingDnsRecordId as setBindingDnsRecordId, repos_setDnsSyncStatus as setDnsSyncStatus, repos_setDomainLastSynced as setDomainLastSynced, repos_setServiceEnabled as setServiceEnabled, repos_setServiceGroup as setServiceGroup, repos_setServiceGroupEnabled as setServiceGroupEnabled, repos_setServiceLb as setServiceLb, repos_unlinkBindingRecord as unlinkBindingRecord, repos_unlinkGroupDnsRecord as unlinkGroupDnsRecord, repos_updateBindingFields as updateBindingFields, repos_updateBindingLbConfig as updateBindingLbConfig, repos_updateDnsFields as updateDnsFields, repos_updateDomain as updateDomain, repos_updateGroup as updateGroup, repos_updateService as updateService, repos_updateServiceGroup as updateServiceGroup, repos_updateSubdomain as updateSubdomain, repos_upsertCertificateCheck as upsertCertificateCheck, repos_upsertIpHealthStatus as upsertIpHealthStatus, repos_upsertSubdomain as upsertSubdomain };
|
||||
}
|
||||
|
||||
export { ConflictError, type Db, type DnsListFilter, NotFoundError, type Sqlite, type UpdateSubdomainPatch, certificates, createDb, createMemoryDb, dnsRecords, domains, groups, healthCheck, ipHealthStatus, repos, resolveDatabasePath, runMigrations, schema, serviceBindingIps, serviceBindingRecords, serviceBindings, serviceGroupDnsRecords, serviceGroups, serviceIps, services, subdomains, syncJobs };
|
||||
export { type AppSettingsDto, type AppSettingsPatch, ConflictError, type Db, type DnsListFilter, NotFoundError, type Sqlite, type UpdateSubdomainPatch, appSettings, certificates, createDb, createMemoryDb, dnsRecords, domains, getAppSettings, getAppSettingsSecrets, getAppSwitcher, groups, healthCheck, ipHealthStatus, repos, resolveDatabasePath, runMigrations, schema, serviceBindingIps, serviceBindingRecords, serviceBindings, serviceGroupDnsRecords, serviceGroups, serviceIps, services, subdomains, syncJobs, touchVpsTrackerSync, updateAppSettings };
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
-- Application settings (single row)
|
||||
CREATE TABLE IF NOT EXISTS app_settings (
|
||||
id TEXT PRIMARY KEY,
|
||||
app_switcher_json TEXT,
|
||||
vps_tracker_url TEXT,
|
||||
vps_tracker_integration_token TEXT,
|
||||
vps_tracker_sync_enabled INTEGER NOT NULL DEFAULT 0,
|
||||
vps_tracker_last_sync_at TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
INSERT OR IGNORE INTO app_settings (id) VALUES ('settings-main');
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from "./schema.js";
|
||||
export * from "./client.js";
|
||||
export * from "./errors.js";
|
||||
export * from "./settings-repo.js";
|
||||
export * as repos from "./repos.js";
|
||||
export type { DnsListFilter, UpdateSubdomainPatch } from "./repos.js";
|
||||
|
||||
@@ -268,6 +268,25 @@ export const ipHealthStatus = sqliteTable(
|
||||
(t) => [primaryKey({ columns: [t.scope, t.ref_id, t.ip] })],
|
||||
);
|
||||
|
||||
export const 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')`),
|
||||
});
|
||||
|
||||
export const schema = {
|
||||
groups,
|
||||
services,
|
||||
@@ -283,4 +302,5 @@ export const schema = {
|
||||
certificates,
|
||||
syncJobs,
|
||||
ipHealthStatus,
|
||||
appSettings,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { appSwitcherConfigSchema, type AppSwitcherConfig } from "@cfdm/shared";
|
||||
import type { Db } from "./client.js";
|
||||
import { appSettings } from "./schema.js";
|
||||
|
||||
const SETTINGS_ID = "settings-main";
|
||||
|
||||
const DEFAULT_APP_SWITCHER: AppSwitcherConfig = {
|
||||
menuLabel: "Приложения",
|
||||
apps: [
|
||||
{
|
||||
id: "vps-tracker",
|
||||
name: "VPS Tracker",
|
||||
subtitle: "Учёт виртуальных серверов",
|
||||
url: "http://192.168.100.67:3001",
|
||||
icon: "server",
|
||||
shortcut: "⌘1",
|
||||
},
|
||||
{
|
||||
id: "cfdm",
|
||||
name: "CF Domain Manager",
|
||||
subtitle: "Управление доменами",
|
||||
url: "http://192.168.100.67:6363",
|
||||
icon: "cloud",
|
||||
shortcut: "⌘2",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export type AppSettingsDto = {
|
||||
id: string;
|
||||
appSwitcher: AppSwitcherConfig;
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationTokenSet: boolean;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
vpsTrackerLastSyncAt: string | null;
|
||||
};
|
||||
|
||||
export type AppSettingsPatch = {
|
||||
appSwitcher?: AppSwitcherConfig;
|
||||
vpsTrackerUrl?: string;
|
||||
vpsTrackerIntegrationToken?: string;
|
||||
vpsTrackerSyncEnabled?: boolean;
|
||||
};
|
||||
|
||||
function parseAppSwitcher(raw: string | null | undefined): AppSwitcherConfig {
|
||||
if (!raw?.trim()) return DEFAULT_APP_SWITCHER;
|
||||
try {
|
||||
return appSwitcherConfigSchema.parse(JSON.parse(raw));
|
||||
} catch {
|
||||
return DEFAULT_APP_SWITCHER;
|
||||
}
|
||||
}
|
||||
|
||||
function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
export function getAppSettings(db: Db): AppSettingsDto {
|
||||
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);
|
||||
}
|
||||
|
||||
export function getAppSettingsSecrets(db: Db): {
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationToken: string;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
} {
|
||||
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),
|
||||
};
|
||||
}
|
||||
|
||||
export function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto {
|
||||
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 !== undefined
|
||||
? JSON.stringify(patch.appSwitcher)
|
||||
: current.app_switcher_json,
|
||||
vps_tracker_url:
|
||||
patch.vpsTrackerUrl !== undefined
|
||||
? patch.vpsTrackerUrl
|
||||
: current.vps_tracker_url,
|
||||
vps_tracker_integration_token:
|
||||
patch.vpsTrackerIntegrationToken !== undefined &&
|
||||
patch.vpsTrackerIntegrationToken.trim() !== ""
|
||||
? patch.vpsTrackerIntegrationToken
|
||||
: current.vps_tracker_integration_token,
|
||||
vps_tracker_sync_enabled:
|
||||
patch.vpsTrackerSyncEnabled !== undefined
|
||||
? patch.vpsTrackerSyncEnabled
|
||||
: current.vps_tracker_sync_enabled,
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.run();
|
||||
|
||||
return getAppSettings(db);
|
||||
}
|
||||
|
||||
export function touchVpsTrackerSync(db: Db): void {
|
||||
db.update(appSettings)
|
||||
.set({
|
||||
vps_tracker_last_sync_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.run();
|
||||
}
|
||||
|
||||
export function getAppSwitcher(db: Db): AppSwitcherConfig {
|
||||
return getAppSettings(db).appSwitcher;
|
||||
}
|
||||
Vendored
+104
-1
@@ -1197,4 +1197,107 @@ type CreateDomainInput = z.infer<typeof createDomainSchema>;
|
||||
type LoginInput = z.infer<typeof loginSchema>;
|
||||
type CreateDnsRecordInput = z.infer<typeof createDnsRecordSchema>;
|
||||
|
||||
export { CERT_ERROR, CERT_EXPIRED, CERT_MONITORING_VALUES, CERT_MONITOR_AUTO, CERT_MONITOR_REQUIRED, CERT_MONITOR_SKIPPED, CERT_OK, CERT_UNKNOWN, CERT_WARNING, type CertMonitoring, type Certificate, type CfDnsRecord, type CfZone, type CreateDnsRecordInput, type CreateDnsRecordPayload, type CreateDomainInput, type CreateGroupInput, type CreateServiceBindingInput, type CreateServiceGroupInput, type CreateServiceInput, type CreateServiceWithConfigInput, type CreateSubdomainInput, type DnsRecord, type Domain, type DomainListItem, type Group, type GroupWithStats, type HealthCheckConfig, type HealthCheckScope, type HealthCheckTarget, type HealthCheckType, type HealthStatusQuery, type IpHealthState, type IpHealthStatus, type JwtClaims, type LbMode, type LoginInput, type LoginRequest, type LoginResponse, type ParsedFqdn, type ReorderServicesInput, SYNC_CONFLICT, SYNC_ERROR, SYNC_PENDING_DELETE, SYNC_PENDING_PUSH, SYNC_SYNCED, type Service, type ServiceBinding, type ServiceBindingView, type ServiceDomainBinding, type ServiceDomainBindingView, type ServiceGroup, type ServiceGroupView, type ServiceGroupsResponse, type ServiceView, type Subdomain, type SubdomainRecord, type SyncJob, type ToggleEnabledInput, type UpdateDomainInput, type UpdateServiceConfigInput, type UpdateServiceGroupInput, type UpdateSubdomainInput, ValidationError, bindingToFqdn, certMonitoringSchema, certStatusFromExpiry, certificateSchema, createDnsRecordSchema, createDomainSchema, createGroupSchema, createServiceBindingSchema, createServiceGroupSchema, createServiceSchema, createServiceWithConfigSchema, createSubdomainSchema, dnsNameToSubdomainLabel, dnsRecordNamesMatch, dnsRecordSchema, domainListItemSchema, domainSchema, fqdnToDisplay, groupSchema, groupWithStatsSchema, healthCheckConfigSchema, healthCheckScopeSchema, healthCheckTypeSchema, healthStatusQuerySchema, ipHealthStateSchema, ipHealthStatusSchema, isValidIpv4, lbModeSchema, loginSchema, normalizeDnsRecordName, parseFqdn, reorderServicesSchema, serviceBindingSchema, serviceDomainBindingSchema, serviceGroupSchema, serviceGroupTypeSchema, serviceGroupViewSchema, serviceGroupsResponseSchema, serviceSchema, serviceViewSchema, shouldMonitorService, subdomainLabelToFqdn, subdomainSchema, toggleEnabledSchema, updateDomainGroupSchema, updateDomainSchema, updateServiceConfigSchema, updateServiceGroupSchema, updateSubdomainSchema, validateDnsRecord };
|
||||
declare const appSwitcherIconSchema: z.ZodEnum<{
|
||||
server: "server";
|
||||
cloud: "cloud";
|
||||
globe: "globe";
|
||||
dashboard: "dashboard";
|
||||
chart: "chart";
|
||||
}>;
|
||||
declare const appSwitcherEntrySchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
subtitle: z.ZodOptional<z.ZodString>;
|
||||
url: z.ZodString;
|
||||
icon: z.ZodDefault<z.ZodEnum<{
|
||||
server: "server";
|
||||
cloud: "cloud";
|
||||
globe: "globe";
|
||||
dashboard: "dashboard";
|
||||
chart: "chart";
|
||||
}>>;
|
||||
shortcut: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
declare const appSwitcherConfigSchema: z.ZodObject<{
|
||||
menuLabel: z.ZodDefault<z.ZodString>;
|
||||
apps: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
subtitle: z.ZodOptional<z.ZodString>;
|
||||
url: z.ZodString;
|
||||
icon: z.ZodDefault<z.ZodEnum<{
|
||||
server: "server";
|
||||
cloud: "cloud";
|
||||
globe: "globe";
|
||||
dashboard: "dashboard";
|
||||
chart: "chart";
|
||||
}>>;
|
||||
shortcut: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
type AppSwitcherEntry = z.infer<typeof appSwitcherEntrySchema>;
|
||||
type AppSwitcherConfig = z.infer<typeof appSwitcherConfigSchema>;
|
||||
|
||||
declare const cfdmBindingSyncItemSchema: z.ZodObject<{
|
||||
bindingId: z.ZodNumber;
|
||||
serviceId: z.ZodNumber;
|
||||
serviceName: z.ZodString;
|
||||
serviceSlug: z.ZodString;
|
||||
fqdn: z.ZodString;
|
||||
zoneName: z.ZodString;
|
||||
hostname: z.ZodString;
|
||||
ips: z.ZodArray<z.ZodString>;
|
||||
deleted: z.ZodOptional<z.ZodBoolean>;
|
||||
}, z.core.$strip>;
|
||||
declare const cfdmSyncBindingsBodySchema: z.ZodObject<{
|
||||
bindings: z.ZodArray<z.ZodObject<{
|
||||
bindingId: z.ZodNumber;
|
||||
serviceId: z.ZodNumber;
|
||||
serviceName: z.ZodString;
|
||||
serviceSlug: z.ZodString;
|
||||
fqdn: z.ZodString;
|
||||
zoneName: z.ZodString;
|
||||
hostname: z.ZodString;
|
||||
ips: z.ZodArray<z.ZodString>;
|
||||
deleted: z.ZodOptional<z.ZodBoolean>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
type CfdmBindingSyncItem = z.infer<typeof cfdmBindingSyncItemSchema>;
|
||||
declare const appSettingsPatchSchema: z.ZodObject<{
|
||||
appSwitcher: z.ZodOptional<z.ZodObject<{
|
||||
menuLabel: z.ZodDefault<z.ZodString>;
|
||||
apps: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
name: z.ZodString;
|
||||
subtitle: z.ZodOptional<z.ZodString>;
|
||||
url: z.ZodString;
|
||||
icon: z.ZodDefault<z.ZodEnum<{
|
||||
server: "server";
|
||||
cloud: "cloud";
|
||||
globe: "globe";
|
||||
dashboard: "dashboard";
|
||||
chart: "chart";
|
||||
}>>;
|
||||
shortcut: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>>;
|
||||
vpsTrackerUrl: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
|
||||
vpsTrackerIntegrationToken: z.ZodOptional<z.ZodString>;
|
||||
vpsTrackerSyncEnabled: z.ZodOptional<z.ZodBoolean>;
|
||||
}, z.core.$strip>;
|
||||
type AppSettingsPatch = z.infer<typeof appSettingsPatchSchema>;
|
||||
declare const vpsTrackerEventSchema: z.ZodObject<{
|
||||
event: z.ZodEnum<{
|
||||
vps_down: "vps_down";
|
||||
vps_up: "vps_up";
|
||||
}>;
|
||||
vps: z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
ip: z.ZodOptional<z.ZodString>;
|
||||
label: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
timestamp: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
type VpsTrackerEvent = z.infer<typeof vpsTrackerEventSchema>;
|
||||
|
||||
export { type AppSettingsPatch, type AppSwitcherConfig, type AppSwitcherEntry, CERT_ERROR, CERT_EXPIRED, CERT_MONITORING_VALUES, CERT_MONITOR_AUTO, CERT_MONITOR_REQUIRED, CERT_MONITOR_SKIPPED, CERT_OK, CERT_UNKNOWN, CERT_WARNING, type CertMonitoring, type Certificate, type CfDnsRecord, type CfZone, type CfdmBindingSyncItem, type CreateDnsRecordInput, type CreateDnsRecordPayload, type CreateDomainInput, type CreateGroupInput, type CreateServiceBindingInput, type CreateServiceGroupInput, type CreateServiceInput, type CreateServiceWithConfigInput, type CreateSubdomainInput, type DnsRecord, type Domain, type DomainListItem, type Group, type GroupWithStats, type HealthCheckConfig, type HealthCheckScope, type HealthCheckTarget, type HealthCheckType, type HealthStatusQuery, type IpHealthState, type IpHealthStatus, type JwtClaims, type LbMode, type LoginInput, type LoginRequest, type LoginResponse, type ParsedFqdn, type ReorderServicesInput, SYNC_CONFLICT, SYNC_ERROR, SYNC_PENDING_DELETE, SYNC_PENDING_PUSH, SYNC_SYNCED, type Service, type ServiceBinding, type ServiceBindingView, type ServiceDomainBinding, type ServiceDomainBindingView, type ServiceGroup, type ServiceGroupView, type ServiceGroupsResponse, type ServiceView, type Subdomain, type SubdomainRecord, type SyncJob, type ToggleEnabledInput, type UpdateDomainInput, type UpdateServiceConfigInput, type UpdateServiceGroupInput, type UpdateSubdomainInput, ValidationError, type VpsTrackerEvent, appSettingsPatchSchema, appSwitcherConfigSchema, appSwitcherEntrySchema, appSwitcherIconSchema, bindingToFqdn, certMonitoringSchema, certStatusFromExpiry, certificateSchema, cfdmBindingSyncItemSchema, cfdmSyncBindingsBodySchema, createDnsRecordSchema, createDomainSchema, createGroupSchema, createServiceBindingSchema, createServiceGroupSchema, createServiceSchema, createServiceWithConfigSchema, createSubdomainSchema, dnsNameToSubdomainLabel, dnsRecordNamesMatch, dnsRecordSchema, domainListItemSchema, domainSchema, fqdnToDisplay, groupSchema, groupWithStatsSchema, healthCheckConfigSchema, healthCheckScopeSchema, healthCheckTypeSchema, healthStatusQuerySchema, ipHealthStateSchema, ipHealthStatusSchema, isValidIpv4, lbModeSchema, loginSchema, normalizeDnsRecordName, parseFqdn, reorderServicesSchema, serviceBindingSchema, serviceDomainBindingSchema, serviceGroupSchema, serviceGroupTypeSchema, serviceGroupViewSchema, serviceGroupsResponseSchema, serviceSchema, serviceViewSchema, shouldMonitorService, subdomainLabelToFqdn, subdomainSchema, toggleEnabledSchema, updateDomainGroupSchema, updateDomainSchema, updateServiceConfigSchema, updateServiceGroupSchema, updateSubdomainSchema, validateDnsRecord, vpsTrackerEventSchema };
|
||||
|
||||
Vendored
+64
-1
@@ -478,6 +478,62 @@ var healthStatusQuerySchema = z.object({
|
||||
scope: healthCheckScopeSchema,
|
||||
ref_id: z.coerce.number().int().positive()
|
||||
});
|
||||
|
||||
// src/app-switcher.ts
|
||||
import { z as z2 } from "zod";
|
||||
var appSwitcherIconSchema = z2.enum([
|
||||
"server",
|
||||
"cloud",
|
||||
"globe",
|
||||
"dashboard",
|
||||
"chart"
|
||||
]);
|
||||
var appSwitcherEntrySchema = z2.object({
|
||||
id: z2.string(),
|
||||
name: z2.string(),
|
||||
subtitle: z2.string().optional(),
|
||||
url: z2.string().url(),
|
||||
icon: appSwitcherIconSchema.default("server"),
|
||||
shortcut: z2.string().optional()
|
||||
});
|
||||
var appSwitcherConfigSchema = z2.object({
|
||||
menuLabel: z2.string().default("\u041F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F"),
|
||||
apps: z2.array(appSwitcherEntrySchema).min(1)
|
||||
});
|
||||
|
||||
// src/integration-vps-tracker.ts
|
||||
import { z as z3 } from "zod";
|
||||
var cfdmBindingSyncItemSchema = z3.object({
|
||||
bindingId: z3.number().int().positive(),
|
||||
serviceId: z3.number().int().positive(),
|
||||
serviceName: z3.string().min(1),
|
||||
serviceSlug: z3.string().min(1),
|
||||
fqdn: z3.string().min(1),
|
||||
zoneName: z3.string().min(1),
|
||||
hostname: z3.string(),
|
||||
ips: z3.array(z3.string()),
|
||||
deleted: z3.boolean().optional()
|
||||
});
|
||||
var cfdmSyncBindingsBodySchema = z3.object({
|
||||
bindings: z3.array(cfdmBindingSyncItemSchema).min(1)
|
||||
});
|
||||
var appSettingsPatchSchema = z3.object({
|
||||
appSwitcher: appSwitcherConfigSchema.optional(),
|
||||
vpsTrackerUrl: z3.string().url().or(z3.literal("")).optional(),
|
||||
vpsTrackerIntegrationToken: z3.string().optional(),
|
||||
vpsTrackerSyncEnabled: z3.boolean().optional()
|
||||
});
|
||||
var vpsTrackerEventSchema = z3.object({
|
||||
event: z3.enum(["vps_down", "vps_up"]),
|
||||
vps: z3.array(
|
||||
z3.object({
|
||||
id: z3.string().min(1),
|
||||
ip: z3.string().optional(),
|
||||
label: z3.string().optional()
|
||||
})
|
||||
),
|
||||
timestamp: z3.string().datetime().optional()
|
||||
});
|
||||
export {
|
||||
CERT_ERROR,
|
||||
CERT_EXPIRED,
|
||||
@@ -494,10 +550,16 @@ export {
|
||||
SYNC_PENDING_PUSH,
|
||||
SYNC_SYNCED,
|
||||
ValidationError,
|
||||
appSettingsPatchSchema,
|
||||
appSwitcherConfigSchema,
|
||||
appSwitcherEntrySchema,
|
||||
appSwitcherIconSchema,
|
||||
bindingToFqdn,
|
||||
certMonitoringSchema,
|
||||
certStatusFromExpiry,
|
||||
certificateSchema,
|
||||
cfdmBindingSyncItemSchema,
|
||||
cfdmSyncBindingsBodySchema,
|
||||
createDnsRecordSchema,
|
||||
createDomainSchema,
|
||||
createGroupSchema,
|
||||
@@ -543,5 +605,6 @@ export {
|
||||
updateServiceConfigSchema,
|
||||
updateServiceGroupSchema,
|
||||
updateSubdomainSchema,
|
||||
validateDnsRecord
|
||||
validateDnsRecord,
|
||||
vpsTrackerEventSchema
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const appSwitcherIconSchema = z.enum([
|
||||
"server",
|
||||
"cloud",
|
||||
"globe",
|
||||
"dashboard",
|
||||
"chart",
|
||||
]);
|
||||
|
||||
export const appSwitcherEntrySchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
subtitle: z.string().optional(),
|
||||
url: z.string().url(),
|
||||
icon: appSwitcherIconSchema.default("server"),
|
||||
shortcut: z.string().optional(),
|
||||
});
|
||||
|
||||
export const appSwitcherConfigSchema = z.object({
|
||||
menuLabel: z.string().default("Приложения"),
|
||||
apps: z.array(appSwitcherEntrySchema).min(1),
|
||||
});
|
||||
|
||||
export type AppSwitcherEntry = z.infer<typeof appSwitcherEntrySchema>;
|
||||
export type AppSwitcherConfig = z.infer<typeof appSwitcherConfigSchema>;
|
||||
@@ -3,6 +3,8 @@ export * from "./validators.js";
|
||||
export * from "./subdomain.js";
|
||||
export * from "./parse-fqdn.js";
|
||||
export * from "./schemas.js";
|
||||
export * from "./app-switcher.js";
|
||||
export * from "./integration-vps-tracker.js";
|
||||
export type {
|
||||
CfZone,
|
||||
CfDnsRecord,
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { z } from "zod";
|
||||
import { appSwitcherConfigSchema } from "./app-switcher.js";
|
||||
|
||||
export const cfdmBindingSyncItemSchema = z.object({
|
||||
bindingId: z.number().int().positive(),
|
||||
serviceId: z.number().int().positive(),
|
||||
serviceName: z.string().min(1),
|
||||
serviceSlug: z.string().min(1),
|
||||
fqdn: z.string().min(1),
|
||||
zoneName: z.string().min(1),
|
||||
hostname: z.string(),
|
||||
ips: z.array(z.string()),
|
||||
deleted: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const cfdmSyncBindingsBodySchema = z.object({
|
||||
bindings: z.array(cfdmBindingSyncItemSchema).min(1),
|
||||
});
|
||||
|
||||
export type CfdmBindingSyncItem = z.infer<typeof cfdmBindingSyncItemSchema>;
|
||||
|
||||
export const appSettingsPatchSchema = z.object({
|
||||
appSwitcher: appSwitcherConfigSchema.optional(),
|
||||
vpsTrackerUrl: z.string().url().or(z.literal("")).optional(),
|
||||
vpsTrackerIntegrationToken: z.string().optional(),
|
||||
vpsTrackerSyncEnabled: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export type AppSettingsPatch = z.infer<typeof appSettingsPatchSchema>;
|
||||
|
||||
export const vpsTrackerEventSchema = z.object({
|
||||
event: z.enum(["vps_down", "vps_up"]),
|
||||
vps: z.array(
|
||||
z.object({
|
||||
id: z.string().min(1),
|
||||
ip: z.string().optional(),
|
||||
label: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
timestamp: z.string().datetime().optional(),
|
||||
});
|
||||
|
||||
export type VpsTrackerEvent = z.infer<typeof vpsTrackerEventSchema>;
|
||||
Reference in New Issue
Block a user