diff --git a/backend/src/templateFormatter.ts b/backend/src/templateFormatter.ts index 0dcb7bde..7463d483 100644 --- a/backend/src/templateFormatter.ts +++ b/backend/src/templateFormatter.ts @@ -59,29 +59,36 @@ function isTemplateSafeValue(value: unknown): value is TemplateSafeValue { export class TemplateSafeValueContainer { // Fake property used for stricter type checks since TypeScript uses structural typing _isTemplateSafeValueContainer: true; - [key: string]: TemplateSafeValue; - constructor(data: Record = {}) { - for (const [key, value] of Object.entries(data)) { - if (!isTemplateSafeValue(value)) { - // tslint:disable:no-console - console.error("=== CONTEXT FOR UNSAFE VALUE ==="); - console.error("stringified:", JSON.stringify(value)); - console.error("typeof:", typeof value); - console.error("constructor name:", (value as any)?.constructor?.name); - console.error("=== /CONTEXT FOR UNSAFE VALUE ==="); - // tslint:enable:no-console - throw new Error(`Unsafe value for key "${key}" in SafeTemplateValueContainer`); - } - - this[key] = value; + constructor(data?: Record) { + if (data) { + ingestDataIntoTemplateSafeValueContainer(this, data); } } } export type TypedTemplateSafeValueContainer = TemplateSafeValueContainer & T; +export function ingestDataIntoTemplateSafeValueContainer( + target: TemplateSafeValueContainer, + data: Record = {}, +) { + for (const [key, value] of Object.entries(data)) { + if (!isTemplateSafeValue(value)) { + // tslint:disable:no-console + console.error("=== CONTEXT FOR UNSAFE VALUE ==="); + console.error("stringified:", JSON.stringify(value)); + console.error("typeof:", typeof value); + console.error("constructor name:", (value as any)?.constructor?.name); + console.error("=== /CONTEXT FOR UNSAFE VALUE ==="); + // tslint:enable:no-console + throw new Error(`Unsafe value for key "${key}" in SafeTemplateValueContainer`); + } + target[key] = value; + } +} + export function createTypedTemplateSafeValueContainer>( data: T, ): TypedTemplateSafeValueContainer { diff --git a/backend/src/utils/templateSafeObjects.ts b/backend/src/utils/templateSafeObjects.ts index 05e3f08f..55149850 100644 --- a/backend/src/utils/templateSafeObjects.ts +++ b/backend/src/utils/templateSafeObjects.ts @@ -22,7 +22,11 @@ import { ISavedMessageStickerData, SavedMessage, } from "../data/entities/SavedMessage"; -import { TemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../templateFormatter"; +import { + ingestDataIntoTemplateSafeValueContainer, + TemplateSafeValueContainer, + TypedTemplateSafeValueContainer, +} from "../templateFormatter"; type InputProps = Omit< { @@ -36,7 +40,8 @@ export class TemplateSafeGuild extends TemplateSafeValueContainer { name: string; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -51,7 +56,8 @@ export class TemplateSafeUser extends TemplateSafeValueContainer { createdAt?: number; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -61,7 +67,8 @@ export class TemplateSafeUnknownUser extends TemplateSafeValueContainer { discriminator: string; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -73,7 +80,8 @@ export class TemplateSafeRole extends TemplateSafeValueContainer { hoist: boolean; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -86,7 +94,8 @@ export class TemplateSafeMember extends TemplateSafeUser { guildName: string; constructor(data: InputProps) { - super(data); + super({}); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -94,7 +103,8 @@ export class TemplateSafeUnknownMember extends TemplateSafeUnknownUser { user: TemplateSafeUnknownUser; constructor(data: InputProps) { - super(data); + super({}); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -105,7 +115,8 @@ export class TemplateSafeChannel extends TemplateSafeValueContainer { parentId?: Snowflake; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -117,7 +128,8 @@ export class TemplateSafeStage extends TemplateSafeValueContainer { topic: string; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -130,7 +142,8 @@ export class TemplateSafeEmoji extends TemplateSafeValueContainer { mention: string; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -146,7 +159,8 @@ export class TemplateSafeSticker extends TemplateSafeValueContainer { url: string; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -159,7 +173,8 @@ export class TemplateSafeSavedMessage extends TemplateSafeValueContainer { data: TemplateSafeSavedMessageData; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -175,7 +190,8 @@ export class TemplateSafeSavedMessageData extends TemplateSafeValueContainer { timestamp: number; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -196,7 +212,8 @@ export class TemplateSafeCase extends TemplateSafeValueContainer { log_message_id: string | null; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } } @@ -207,7 +224,8 @@ export class TemplateSafeMessage extends TemplateSafeValueContainer { channel: TemplateSafeChannel; constructor(data: InputProps) { - super(data); + super(); + ingestDataIntoTemplateSafeValueContainer(this, data); } }