Skip to content

Commit

Permalink
BC-6676 - Use v3 config (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
bischofmax committed Mar 26, 2024
1 parent cb8cc3c commit 9237896
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/configuration/api/api.configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export const API = {
FILE_UPLOAD: "/api/v3/file/upload/SCHOOLID/boardnodes/CONTEXTID",
LOGIN_REDIRECT: "/login?redirect=/tldraw?roomName=ROOMID",
USER_DATA: `/api/v3/user/me`,
ENV_CONFIG: `/api/v1/config/app/public`,
ENV_CONFIG: `/api/v3/config/public`,
};
1 change: 1 addition & 0 deletions src/configuration/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './api/api.configuration';
7 changes: 7 additions & 0 deletions src/guards/http.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export class HttpGuard {
static checkStatusOk(response: Response) {
if (!response.ok) {
throw new Error(`${response.status} - ${response.statusText}`);
}
}
}
2 changes: 2 additions & 0 deletions src/guards/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './type.guard';
export * from './http.guard';
25 changes: 25 additions & 0 deletions src/guards/type.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export class TypeGuard {
static checkKeyAndValueExists(json: Record<string, unknown>, key: string): void {
if (!(key in json) && json[key]) {
throw new Error(`The ${key} is missing`);
}
}

static checkNumber(value: unknown): void {
if (typeof value !== 'number') {
throw new Error('Type is not a number');
}
}

static checkArray(value: unknown): void {
if (!Array.isArray(value)) {
throw new Error('Type is not an array');
}
}

static checkBoolean(value: unknown): void {
if (typeof value !== 'boolean') {
throw new Error('Type is not a boolean');
}
}
}
35 changes: 35 additions & 0 deletions src/mapper/configuration.mapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Envs } from "../types";
import { TypeGuard } from "../guards";

const checkEnvType = (obj: Record<string, unknown>): void => {
TypeGuard.checkKeyAndValueExists(obj, 'FEATURE_TLDRAW_ENABLED');
TypeGuard.checkKeyAndValueExists(obj, 'TLDRAW__ASSETS_ENABLED');
TypeGuard.checkKeyAndValueExists(obj, 'TLDRAW__ASSETS_MAX_SIZE');
TypeGuard.checkKeyAndValueExists(obj, 'TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST');
TypeGuard.checkBoolean(obj.FEATURE_TLDRAW_ENABLED);
TypeGuard.checkBoolean(obj.FEATURE_TLDRAW_ENABLED);
TypeGuard.checkNumber(obj.TLDRAW__ASSETS_MAX_SIZE);
TypeGuard.checkArray(obj.TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST);
}

const castToEnv = (obj: Record<string, unknown>): Envs => {
checkEnvType(obj);
const configuration = obj as Envs;

return configuration;
}

export class ConfigurationMapper {
static mapToConfigurationFromResponse(obj: Record<string, unknown>): Envs {
const configuration = castToEnv(obj);

const mappedConfiguration: Envs = {
FEATURE_TLDRAW_ENABLED: configuration.FEATURE_TLDRAW_ENABLED,
TLDRAW__ASSETS_ENABLED: configuration.TLDRAW__ASSETS_ENABLED,
TLDRAW__ASSETS_MAX_SIZE: configuration.TLDRAW__ASSETS_MAX_SIZE,
TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST: configuration.TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST,
}

return mappedConfiguration;
}
}
1 change: 1 addition & 0 deletions src/mapper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './configuration.mapper';
2 changes: 1 addition & 1 deletion src/types/Envs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export type Envs = {
FEATURE_TLDRAW_ENABLED: boolean;
TLDRAW__ASSETS_ENABLED: boolean;
TLDRAW__ASSETS_MAX_SIZE: number;
TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST: string;
TLDRAW__ASSETS_ALLOWED_MIME_TYPES_LIST: string[];
};
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Envs';
24 changes: 16 additions & 8 deletions src/utils/envConfig.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { Envs } from "../types/Envs";
import { API } from "../configuration/api/api.configuration";
import { Envs } from "../types";
import { API } from "../configuration";
import { ConfigurationMapper } from "../mapper";
import { HttpGuard } from "../guards";

export const getEnvs = async (): Promise<Envs | undefined> => {
// the try catch should not part of getEnvs, the place that use it must handle the errors
// should be part of a store
// Without loading the config the Promise.all should not be finished and proceed.
export const getEnvs = async (): Promise<Envs|undefined> => {
try {
// TODO: check order..
const response = await fetch(API.ENV_CONFIG);
HttpGuard.checkStatusOk(response);
const responseData = await response.json();

const configuration = ConfigurationMapper.mapToConfigurationFromResponse(responseData);

if (!response.ok) {
throw new Error(`${response.status} - ${response.statusText}`);
}

return await response.json();
return configuration;
} catch (error) {
// It should exists one place that execute the console.error in the application. A errorHandler.
// If we want to collect this informations to send it back to us, then we have currently no possibility to implement it.
console.error("Error fetching env config:", error);
}
};

0 comments on commit 9237896

Please sign in to comment.