UNPKG

@travetto/model-mongo

Version:

Mongo backing for the travetto model module.

125 lines (117 loc) 3.34 kB
import type mongo from 'mongodb'; import { type TimeSpan, TimeUtil, RuntimeResources, Runtime } from '@travetto/runtime'; import { Config } from '@travetto/config'; /** * Mongo model config */ @Config('model.mongo') export class MongoModelConfig { /** * Hosts */ hosts?: string[]; /** * Collection prefix */ namespace?: string; /** * Username */ username?: string; /** * Password */ password?: string; /** * Server port */ port?: number; /** * Direct mongo connection options, these do not go on the connection string */ connectionOptions: mongo.MongoClientOptions = {}; /** * Is using the SRV DNS record configuration */ srvRecord?: boolean; /** * Mongo client options */ options: mongo.MongoClientOptions = {}; /** * Allow storage modification at runtime */ modifyStorage?: boolean; /** * Frequency of culling for cullable content */ cullRate?: number | TimeSpan; /** * Connection string */ connectionString?: string; /** * Should we store the _id as a string in the id field */ storeId?: boolean; /** * Load all the ssl certs as needed */ async postConstruct(): Promise<void> { const resolve = (file: string): Promise<string> => RuntimeResources.resolve(file).catch(() => file); if (this.connectionString) { const details = new URL(this.connectionString); this.hosts ??= details.hostname.split(',').filter(host => !!host); this.srvRecord ??= details.protocol === 'mongodb+srv:'; this.namespace ??= details.pathname.replace('/', ''); Object.assign(this.options, Object.fromEntries(details.searchParams.entries())); this.port ??= +details.port; this.username ??= details.username; this.password ??= details.password; } // Defaults if (!this.namespace) { this.namespace = 'app'; } if (!this.port || Number.isNaN(this.port)) { this.port = 27017; } if (!this.hosts || !this.hosts.length) { this.hosts = ['localhost']; } const options = this.options; if (options.ssl) { if (options.cert) { options.cert = await Promise.all([options.cert].flat(2).map(data => Buffer.isBuffer(data) ? data : resolve(data))); } if (options.tlsCertificateKeyFile) { options.tlsCertificateKeyFile = await resolve(options.tlsCertificateKeyFile); } if (options.tlsCAFile) { options.tlsCAFile = await resolve(options.tlsCAFile); } if (options.tlsCRLFile) { options.tlsCRLFile = await resolve(options.tlsCRLFile); } } if (!Runtime.production) { options.waitQueueTimeoutMS = 0; options.serverSelectionTimeoutMS = TimeUtil.asMillis(1, 's'); } } /** * Build connection URLs */ get url(): string { const hosts = this.hosts! .map(host => (this.srvRecord || host.includes(':')) ? host : `${host}:${this.port ?? 27017}`) .join(','); const optionString = new URLSearchParams(Object.entries(this.options)).toString(); let creds = ''; if (this.username) { creds = `${[this.username, this.password].filter(part => !!part).join(':')}@`; } const url = `mongodb${this.srvRecord ? '+srv' : ''}://${creds}${hosts}/${this.namespace}?${optionString}`; return url; } }