From cfbeac9c569d6924c479c033ad44d05a1c0397ae Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Sat, 9 Sep 2023 17:59:56 -0700 Subject: [PATCH] Enable port to be overridden (#1527) Enable port to be overriden --- server/.env.example | 1 + .../cast-to-positive-number.decorator.spec.ts | 51 +++++++++++++++++++ .../cast-to-positive-number.decorator.ts | 15 ++++++ .../environment/environment.service.ts | 4 ++ .../environment/environment.validation.ts | 7 +++ 5 files changed, 78 insertions(+) create mode 100644 server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts create mode 100644 server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts diff --git a/server/.env.example b/server/.env.example index ade0950e7..9a129d62e 100644 --- a/server/.env.example +++ b/server/.env.example @@ -10,6 +10,7 @@ REFRESH_TOKEN_SECRET=replace_me_with_a_random_string SIGN_IN_PREFILLED=true # ———————— Optional ———————— +# PORT=3000 # DEBUG_MODE=true # ACCESS_TOKEN_EXPIRES_IN=30m # LOGIN_TOKEN_EXPIRES_IN=15m diff --git a/server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts b/server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts new file mode 100644 index 000000000..0a65d3a90 --- /dev/null +++ b/server/src/integrations/environment/decorators/__tests__/cast-to-positive-number.decorator.spec.ts @@ -0,0 +1,51 @@ +import { plainToClass } from 'class-transformer'; + +import { CastToPositiveNumber } from 'src/integrations/environment/decorators/cast-to-positive-number.decorator'; + +class TestClass { + @CastToPositiveNumber() + numberProperty?: any; +} + +describe('CastToPositiveNumber Decorator', () => { + it('should cast number to number', () => { + const transformedClass = plainToClass(TestClass, { numberProperty: 123 }); + expect(transformedClass.numberProperty).toBe(123); + }); + + it('should cast string to number', () => { + const transformedClass = plainToClass(TestClass, { numberProperty: '123' }); + expect(transformedClass.numberProperty).toBe(123); + }); + + it('should cast null to undefined', () => { + const transformedClass = plainToClass(TestClass, { numberProperty: null }); + expect(transformedClass.numberProperty).toBe(undefined); + }); + + it('should cast negative number to undefined', () => { + const transformedClass = plainToClass(TestClass, { numberProperty: -12 }); + expect(transformedClass.numberProperty).toBe(undefined); + }); + + it('should cast undefined to undefined', () => { + const transformedClass = plainToClass(TestClass, { + numberProperty: undefined, + }); + expect(transformedClass.numberProperty).toBe(undefined); + }); + + it('should cast NaN string to undefined', () => { + const transformedClass = plainToClass(TestClass, { + numberProperty: 'toto', + }); + expect(transformedClass.numberProperty).toBe(undefined); + }); + + it('should cast a negative string to undefined', () => { + const transformedClass = plainToClass(TestClass, { + numberProperty: '-123', + }); + expect(transformedClass.numberProperty).toBe(undefined); + }); +}); diff --git a/server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts b/server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts new file mode 100644 index 000000000..4167957c7 --- /dev/null +++ b/server/src/integrations/environment/decorators/cast-to-positive-number.decorator.ts @@ -0,0 +1,15 @@ +import { Transform } from 'class-transformer'; + +export function CastToPositiveNumber() { + return Transform(({ value }: { value: string }) => toNumber(value)); +} + +const toNumber = (value: any) => { + if (typeof value === 'number') { + return value >= 0 ? value : undefined; + } + if (typeof value === 'string') { + return isNaN(+value) ? undefined : toNumber(+value); + } + return undefined; +}; diff --git a/server/src/integrations/environment/environment.service.ts b/server/src/integrations/environment/environment.service.ts index b5eadc497..fe658d3bd 100644 --- a/server/src/integrations/environment/environment.service.ts +++ b/server/src/integrations/environment/environment.service.ts @@ -28,6 +28,10 @@ export class EnvironmentService { ); } + getPort(): number { + return this.configService.get('PORT') ?? 3000; + } + getPGDatabaseUrl(): string { return this.configService.get('PG_DATABASE_URL')!; } diff --git a/server/src/integrations/environment/environment.validation.ts b/server/src/integrations/environment/environment.validation.ts index 785aa281d..de70025bd 100644 --- a/server/src/integrations/environment/environment.validation.ts +++ b/server/src/integrations/environment/environment.validation.ts @@ -7,6 +7,7 @@ import { ValidateIf, validateSync, IsBoolean, + IsNumber, } from 'class-validator'; import { assert } from 'src/utils/assert'; @@ -17,6 +18,7 @@ import { AwsRegion } from './interfaces/aws-region.interface'; import { IsAWSRegion } from './decorators/is-aws-region.decorator'; import { CastToBoolean } from './decorators/cast-to-boolean.decorator'; import { SupportDriver } from './interfaces/support.interface'; +import { CastToPositiveNumber } from './decorators/cast-to-positive-number.decorator'; export class EnvironmentVariables { // Misc @@ -40,6 +42,11 @@ export class EnvironmentVariables { @IsBoolean() TELEMETRY_ANONYMIZATION_ENABLED?: boolean; + @CastToPositiveNumber() + @IsNumber() + @IsOptional() + PORT: number; + // Database @IsUrl({ protocols: ['postgres'], require_tld: false }) PG_DATABASE_URL: string;