Skip to content
This repository has been archived by the owner on Aug 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #348 from beabee-communityrm/refactor/validation-d…
Browse files Browse the repository at this point in the history
…ecorations

feat: use new beabee-common functionality
  • Loading branch information
wpf500 authored Mar 22, 2024
2 parents a4f8c63 + e8f4435 commit d695fee
Show file tree
Hide file tree
Showing 19 changed files with 297 additions and 221 deletions.
19 changes: 14 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"test": "jest --setupFiles dotenv/config"
},
"dependencies": {
"@beabee/beabee-common": "^1.19.14",
"@beabee/beabee-common": "^0.20.2",
"@captchafox/node": "^1.2.0",
"@inquirer/prompts": "^3.3.0",
"@sendgrid/mail": "^8.1.0",
Expand Down
211 changes: 115 additions & 96 deletions src/api/dto/CalloutFormDto.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import {
BaseCalloutComponentSchema,
CalloutComponentBaseSchema,
CalloutComponentBaseInputSchema,
CalloutComponentBaseNestableSchema,
CalloutComponentContentSchema,
CalloutComponentInputSelectSchema,
CalloutComponentType,
calloutComponentNestableTypes,
calloutComponentInputTypes,
CalloutComponentBaseInputSelectableSchema,
calloutComponentInputSelectableTypes,
CalloutComponentSchema,
GetCalloutFormSchema,
GetCalloutNavigationSchema,
GetCalloutSlideSchema,
InputCalloutComponentSchema,
NestableCalloutComponentSchema,
RadioCalloutComponentSchema,
SelectCalloutComponentSchema,
SetCalloutFormSchema,
SetCalloutNavigationSchema,
SetCalloutSlideSchema
SetCalloutSlideSchema,
CalloutComponentBaseRules,
CalloutResponseAnswer,
isCalloutComponentOfBaseType,
CalloutComponentBaseType
} from "@beabee/beabee-common";
import { Transform, Type, plainToInstance } from "class-transformer";
import {
Expand All @@ -30,35 +40,10 @@ import { log as mainLogger } from "@core/logging";

const log = mainLogger.child({ app: "callout-form-validation" });

// content

const inputTypes = [
"address",
"button",
"checkbox",
"currency",
"datetime",
"email",
"file",
"number",
"password",
"phoneNumber",
"signature",
"textfield",
"textarea",
"time",
"url"
] as const;
const nestedTypes = ["panel", "well", "tabs"] as const;
const selectTypes = ["select"] as const;
const radioTypes = ["radio", "selectboxes"] as const;

abstract class BaseCalloutComponentDto implements BaseCalloutComponentSchema {
abstract type: string;
abstract class CalloutComponentBaseDto implements CalloutComponentBaseSchema {
abstract type: CalloutComponentType;
abstract input?: boolean;

[key: string]: unknown;

@IsString()
id!: string;

Expand All @@ -72,57 +57,84 @@ abstract class BaseCalloutComponentDto implements BaseCalloutComponentSchema {
@IsOptional()
@IsBoolean()
adminOnly?: boolean;

// Unused properties
[key: string]: unknown;
}

class ContentCalloutComponentDto extends BaseCalloutComponentDto {
class CalloutComponentContentDto
extends CalloutComponentBaseDto
implements CalloutComponentContentSchema
{
@Equals(false)
input!: false;

@IsIn(["content"])
type!: "content";
@Equals(CalloutComponentType.CONTENT)
type!: CalloutComponentType.CONTENT;

@IsString()
html!: string;

@IsString()
label!: string;

@IsOptional()
@IsObject()
validate?: CalloutComponentBaseRules;

@IsOptional()
@IsBoolean()
multiple?: boolean;

@IsOptional()
defaultValue?: CalloutResponseAnswer | CalloutResponseAnswer[] | null;

@IsOptional()
@IsBoolean()
hidden?: boolean;
}

class InputCalloutComponentDto
extends BaseCalloutComponentDto
implements InputCalloutComponentSchema
class CalloutComponentInputDto
extends CalloutComponentBaseDto
implements CalloutComponentBaseInputSchema
{
@IsIn(inputTypes)
type!: (typeof inputTypes)[number];
@IsIn(calloutComponentInputTypes)
type!: CalloutComponentBaseInputSchema["type"];

@Equals(true)
input!: true;
}

class SelectCalloutComponentValueDto {
class CalloutComponentInputSelectDataValueDto {
@IsString()
label!: string;

@IsString()
value!: string;
}

class SelectCalloutComponentDataDto {
class CalloutComponentInputSelectDataDto {
@ValidateNested({ each: true })
@Type(() => SelectCalloutComponentValueDto)
values!: SelectCalloutComponentValueDto[];
@Type(() => CalloutComponentInputSelectDataValueDto)
values!: CalloutComponentInputSelectDataValueDto[];

// Unused properties
[key: string]: unknown;
}

class SelectCalloutComponentDto
extends BaseCalloutComponentDto
implements SelectCalloutComponentSchema
class CalloutComponentInputSelectDto
extends CalloutComponentInputDto
implements CalloutComponentInputSelectSchema
{
@IsIn(selectTypes)
type!: (typeof selectTypes)[number];

@Equals(true)
input!: true;
@Equals(CalloutComponentType.INPUT_SELECT)
type!: CalloutComponentType.INPUT_SELECT;

@ValidateNested()
@Type(() => SelectCalloutComponentDataDto)
data!: SelectCalloutComponentDataDto;
@Type(() => CalloutComponentInputSelectDataDto)
data!: CalloutComponentInputSelectDataDto;
}

class RadioCalloutComponentValueDto {
class CalloutComponentInputSelectableValueDto {
@IsString()
label!: string;

Expand All @@ -134,19 +146,16 @@ class RadioCalloutComponentValueDto {
nextSlideId?: string;
}

class RadioCalloutComponentDto
extends BaseCalloutComponentDto
implements RadioCalloutComponentSchema
class CalloutComponentInputSelectableDto
extends CalloutComponentInputDto
implements CalloutComponentBaseInputSelectableSchema
{
@IsIn(radioTypes)
type!: (typeof radioTypes)[number];

@Equals(true)
input!: true;
@IsIn(calloutComponentInputSelectableTypes)
type!: CalloutComponentBaseInputSelectableSchema["type"];

@ValidateNested({ each: true })
@Type(() => RadioCalloutComponentValueDto)
values!: RadioCalloutComponentValueDto[];
@Type(() => CalloutComponentInputSelectableValueDto)
values!: CalloutComponentInputSelectableValueDto[];
}

function ComponentType() {
Expand All @@ -157,20 +166,36 @@ function ComponentType() {
if (typeof component !== "object" || component === null)
throw new Error("Component must be an object");

switch (true) {
case inputTypes.includes(component.type):
return plainToInstance(InputCalloutComponentDto, component);
case selectTypes.includes(component.type):
return plainToInstance(SelectCalloutComponentDto, component);
case radioTypes.includes(component.type):
return plainToInstance(RadioCalloutComponentDto, component);
case nestedTypes.includes(component.type):
return plainToInstance(NestableCalloutComponentDto, component);
case "content" === component.type:
return plainToInstance(ContentCalloutComponentDto, component);
default:
throw new Error("Unknown component type " + component.type);
switch (component.type) {
case CalloutComponentType.CONTENT:
return plainToInstance(CalloutComponentContentDto, component);
case CalloutComponentType.INPUT_SELECT:
return plainToInstance(CalloutComponentInputSelectDto, component);
}

if (
isCalloutComponentOfBaseType(
component,
CalloutComponentBaseType.INPUT_SELECTABLE
)
) {
return plainToInstance(CalloutComponentInputSelectableDto, component);
}
if (
isCalloutComponentOfBaseType(component, CalloutComponentBaseType.INPUT)
) {
return plainToInstance(CalloutComponentInputDto, component);
}
if (
isCalloutComponentOfBaseType(
component,
CalloutComponentBaseType.NESTABLE
)
) {
return plainToInstance(CalloutComponentNestableDto, component);
}

throw new Error("Unknown component type " + component.type);
});
});
}
Expand Down Expand Up @@ -205,26 +230,19 @@ function IsComponent(validationOptions?: ValidationOptions) {
);
}

type CalloutComponentDto =
| ContentCalloutComponentDto
| NestableCalloutComponentDto
| InputCalloutComponentDto
| SelectCalloutComponentDto
| RadioCalloutComponentDto;

class NestableCalloutComponentDto
extends BaseCalloutComponentDto
implements NestableCalloutComponentSchema
class CalloutComponentNestableDto
extends CalloutComponentBaseDto
implements CalloutComponentBaseNestableSchema
{
@IsIn(nestedTypes)
type!: (typeof nestedTypes)[number];
@IsIn(calloutComponentNestableTypes)
type!: CalloutComponentBaseNestableSchema["type"];

@Equals(false)
input!: false;

@IsComponent({ each: true })
@ComponentType()
components!: CalloutComponentDto[];
components!: CalloutComponentSchema[];
}

class SetCalloutNavigationDto implements SetCalloutNavigationSchema {
Expand All @@ -239,9 +257,10 @@ class SetCalloutSlideDto implements SetCalloutSlideSchema {
@IsString()
title!: string;

@IsComponent({ each: true })
@ComponentType()
components!: CalloutComponentDto[];
// @IsComponent({ each: true })
// @ComponentType()
@IsObject({ each: true }) // TODO: implement a Dto
components!: CalloutComponentSchema[];

@ValidateNested()
@Type(() => SetCalloutNavigationDto)
Expand Down Expand Up @@ -277,7 +296,7 @@ class GetCalloutSlideDto implements GetCalloutSlideSchema {

@IsComponent({ each: true })
@ComponentType()
components!: CalloutComponentDto[];
components!: CalloutComponentSchema[];

@ValidateNested()
@Type(() => GetCalloutNavigationDto)
Expand Down
8 changes: 4 additions & 4 deletions src/api/dto/CalloutResponseDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
CalloutComponentSchema,
CalloutResponseAnswerAddress,
CalloutResponseAnswerFileUpload,
CalloutResponseAnswers,
CalloutResponseAnswersSlide,
PaginatedQuery
} from "@beabee/beabee-common";
import { Type } from "class-transformer";
Expand Down Expand Up @@ -95,7 +95,7 @@ export class GetCalloutResponseDto {

@IsOptional()
@IsObject()
answers?: CalloutResponseAnswers;
answers?: CalloutResponseAnswersSlide;

@IsOptional()
@ValidateNested()
Expand All @@ -121,7 +121,7 @@ export class GetCalloutResponseDto {
export class CreateCalloutResponseDto {
// TODO: validate
@IsObject()
answers!: CalloutResponseAnswers;
answers!: CalloutResponseAnswersSlide;

@IsOptional()
@IsString()
Expand Down Expand Up @@ -191,7 +191,7 @@ export class GetCalloutResponseMapDto {
number!: number;

@IsObject()
answers!: CalloutResponseAnswers;
answers!: CalloutResponseAnswersSlide;

@IsString()
title!: string;
Expand Down
Loading

0 comments on commit d695fee

Please sign in to comment.