use null for unsetting instead of empty string

This commit is contained in:
Alex Holliday committed 2026-03-12 09:53:31 -07:00
1 parent 6404a06999
commit 48e71d4345
5 files changed
+20 -16

No files matched your search

@@ -1,11 +1,11 @@
import type { Settings } from "@/types/index.js";
import type { Settings, SettingsUpdate } from "@/types/index.js";
export interface ISettingsRepository {
// create
create(settings: Partial<Settings>): Promise<Settings>;
// fetch
findSingleton(): Promise<Settings | null>;
// update
update(settings: Partial<Settings>): Promise<Settings>;
update(settings: SettingsUpdate): Promise<Settings>;
// delete
deleteLegacy: () => Promise<boolean>;
}
@@ -1,6 +1,6 @@
import mongoose from "mongoose";
import { ISettingsRepository } from "@/repositories/settings/ISettingsRepository.js";
import type { Settings } from "@/types/index.js";
import type { Settings, SettingsUpdate } from "@/types/index.js";
import { AppSettingsModel, type AppSettingsDocument } from "@/db/models/index.js";
class MongoSettingsRepository implements ISettingsRepository {
@@ -59,12 +59,12 @@ class MongoSettingsRepository implements ISettingsRepository {
return this.toEntity(settings);
};
update = async (settings: Partial<Settings>) => {
update = async (settings: SettingsUpdate) => {
const update: Record<string, any> = { $set: {}, $unset: {} };
// Iterate through settings and separate into $set and $unset
Object.entries(settings).forEach(([key, value]) => {
if (value === undefined || value === "") {
if (value === undefined || value === null) {
// Unset undefined or empty string values
update.$unset[key] = "";
} else {
+3 -3
View File
@@ -1,5 +1,5 @@
import { ISettingsRepository } from "@/repositories/index.js";
import { Settings } from "@/types/index.js";
import { Settings, SettingsUpdate } from "@/types/index.js";
import { AppError } from "@/utils/AppError.js";
import { ValidatedEnv } from "@/validation/envValidation.js";
import type { StringValue } from "ms";
@@ -19,7 +19,7 @@ export interface ISettingsService {
loadSettings(): EnvConfig;
getSettings(): EnvConfig;
getDBSettings(): Promise<Settings>;
updateDbSettings(newSettings: Partial<Settings>): Promise<Settings>;
updateDbSettings(newSettings: SettingsUpdate): Promise<Settings>;
}
export class SettingsService implements ISettingsService {
@@ -54,7 +54,7 @@ export class SettingsService implements ISettingsService {
return this.settings;
}
updateDbSettings = async (newSettings: Partial<Settings>) => {
updateDbSettings = async (newSettings: SettingsUpdate) => {
return await this.settingsRepository.update(newSettings);
};
+4
View File
@@ -5,6 +5,10 @@ export interface SettingsThresholds {
temperature?: number;
}
export type SettingsUpdate = {
[K in keyof Settings]?: Settings[K] | null;
};
export interface Settings {
id: string;
checkTTL: number;
+8 -8
View File
@@ -8,16 +8,16 @@ import { z } from "zod";
export const updateAppSettingsBodyValidation = z
.object({
checkTTL: z.number().int().min(1).max(CHECK_TTL_SENTINEL).optional(),
systemEmailPort: z.number().optional(),
pagespeedApiKey: z.string().optional(),
systemEmailPort: z.number().nullable().optional(),
pagespeedApiKey: z.string().nullable().optional(),
language: z.string().optional(),
timezone: z.string().optional(),
systemEmailHost: z.string().optional(),
systemEmailAddress: z.string().optional(),
systemEmailPassword: z.string().optional(),
systemEmailUser: z.string().optional(),
systemEmailConnectionHost: z.string().optional(),
systemEmailTLSServername: z.string().optional(),
systemEmailHost: z.string().nullable().optional(),
systemEmailAddress: z.string().nullable().optional(),
systemEmailPassword: z.string().nullable().optional(),
systemEmailUser: z.string().nullable().optional(),
systemEmailConnectionHost: z.string().nullable().optional(),
systemEmailTLSServername: z.string().nullable().optional(),
showURL: z.boolean().optional(),
systemEmailSecure: z.boolean().optional(),