Files
tyx_AI_xhs/apps/api/src/main.ts
T

118 lines
4.7 KiB
TypeScript

import { createHmac } from "node:crypto";
import { join, resolve } from "node:path";
import { registrationNotice } from "@dada/shared-contracts";
import { createApp } from "./app.js";
import { readBrowserSupportRelease } from "./browser-support.js";
import { defaultInstanceConfigPath, readConfiguredLocalDataRoot } from "./local-data-root.js";
import { ManagedStorage } from "./managed-storage.js";
import { LatestExportService } from "./latest-exports.js";
import { CreditService } from "./credits.js";
import { ProjectService } from "./projects.js";
import { RegistrationService } from "./registration.js";
import { RecentAssetService } from "./recent-assets.js";
import { MockResendAdapter } from "./resend-adapter.js";
import { readSecureConfigCandidate } from "./secure-config.js";
import { StructuredJsonlLogger } from "./structured-log.js";
import { attachApiSupervisorControl, initializeApiCredentialClients, receiveApiCredentials } from "./supervisor-channel.js";
import { ModelConfigurationService } from "./model-configuration.js";
const credentialChannelEnabled = process.argv.includes("--dada-credential-stdin");
let registration: RegistrationService | undefined;
let projects: ProjectService | undefined;
let credits: CreditService | undefined;
let storage: ManagedStorage | undefined;
let latestExports: LatestExportService | undefined;
let models: ModelConfigurationService | undefined;
let recentAssets: RecentAssetService | undefined;
const instanceConfigPath = process.env.DADA_INSTANCE_CONFIG_PATH ?? defaultInstanceConfigPath();
if (credentialChannelEnabled) {
const clients = initializeApiCredentialClients(await receiveApiCredentials());
try {
const derivePepper = (purpose: string) => createHmac("sha256", clients.adminAllowlistPepper)
.update(`Dada/P0A/${purpose}/v1`, "utf8")
.digest();
const dataRoot = readConfiguredLocalDataRoot(instanceConfigPath);
const databasePath = join(dataRoot, "db", "dada.sqlite3");
registration = new RegistrationService({
adminAllowlistPepper: Buffer.from(clients.adminAllowlistPepper),
challengePepper: derivePepper("challenge-pepper"),
currentPrivacyNoticeVersion: registrationNotice.version,
databasePath,
invitePepper: derivePepper("invite-pepper"),
resend: new MockResendAdapter(),
sessionPepper: derivePepper("session-pepper"),
});
projects = new ProjectService({ databasePath });
credits = new CreditService({ databasePath });
storage = new ManagedStorage({ dataRoot, databasePath });
latestExports = new LatestExportService({ databasePath, storage });
models = new ModelConfigurationService({ database: registration.database });
recentAssets = new RecentAssetService({ database: registration.database });
registration.applySecureConfig(readSecureConfigCandidate(instanceConfigPath));
} catch (error) {
latestExports?.close();
latestExports = undefined;
storage?.close();
storage = undefined;
credits?.close();
credits = undefined;
projects?.close();
projects = undefined;
registration?.close();
registration = undefined;
throw error;
} finally {
clients.adminAllowlistPepper.fill(0);
}
}
const browserSupportRelease = readBrowserSupportRelease(resolve("RELEASE.json"));
const app = await createApp({
...(browserSupportRelease ? { browserSupportRelease } : {}),
...(credits ? { credits } : {}),
...(latestExports ? { latestExports } : {}),
...(models ? { models } : {}),
...(projects ? { projects } : {}),
...(registration ? { registration } : {}),
...(recentAssets ? { recentAssets } : {}),
});
await app.listen({
host: "127.0.0.1",
port: 43121,
});
const controlPipeIndex = process.argv.indexOf("--dada-control-pipe");
if (controlPipeIndex >= 0) {
const controlPipe = process.argv[controlPipeIndex + 1];
if (!controlPipe) throw new Error("Supervisor control pipe name is required.");
const control = attachApiSupervisorControl(controlPipe, async () => {
await app.close();
latestExports?.close();
credits?.close();
projects?.close();
registration?.close();
storage?.close();
});
try {
const dataRoot = readConfiguredLocalDataRoot(instanceConfigPath);
if (!storage) storage = new ManagedStorage({ dataRoot, databasePath: join(dataRoot, "db", "dada.sqlite3") });
const logger = new StructuredJsonlLogger({
component: "api",
directory: join(dataRoot, "logs", "api"),
onWriteFailure: () => {
try {
storage?.setLogAvailability(false);
} finally {
control.reportStatus("storage_unavailable");
}
},
});
logger.write({ error_category: "none", status_category: "ready" });
} catch {
control.reportStatus("storage_unavailable");
}
}