Skip to content

Commit

Permalink
chore: move Entity and other types appropriate to lib-api-client
Browse files Browse the repository at this point in the history
  • Loading branch information
brunotot committed Sep 17, 2024
1 parent e65b20d commit 318c02d
Show file tree
Hide file tree
Showing 20 changed files with 5,755 additions and 4,569 deletions.
3 changes: 1 addition & 2 deletions packages/mern-sample-app/app-node-express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
"mongodb": "^6.5.0",
"morgan": "^1.10.0",
"swagger-ui-express": "^5.0.1",
"winston": "^3.11.0",
"zod": "^3.23.8"
"winston": "^3.11.0"
},
"devDependencies": {
"@types/body-parser": "^1.19.5",
Expand Down
44 changes: 23 additions & 21 deletions packages/mern-sample-app/app-node-express/src/ExpressApp.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import express from "express";

import type * as utils from "@org/lib-commons";
import * as apiClientUtils from "@org/lib-api-client";
import * as tsRest from "@org/app-node-express/lib/@ts-rest";
import * as bottleJs from "@org/app-node-express/lib/bottlejs";
import * as mongodb from "@org/app-node-express/lib/mongodb";

import type { RouteMiddlewareFactory } from "@org/app-node-express/lib/@ts-rest";
import type { Class } from "@org/lib-commons";
import type { MongoClient } from "@org/app-node-express/lib/mongodb";

import { initializeExpressRoutes, initializeSwagger } from "@org/app-node-express/lib/@ts-rest";
import { MongoDatabaseService } from "@org/app-node-express/lib/mongodb";
import { getTypedError } from "@org/lib-api-client";
import { iocRegistry } from "@org/app-node-express/lib/bottlejs";
import { log } from "@org/app-node-express/logger";
import { env } from "@org/app-node-express/env";

export type ExpressAppConfig = Partial<{
middleware: tsRest.RouteMiddlewareFactory[];
modules: Record<string, utils.Class>;
middleware: RouteMiddlewareFactory[];
modules: Record<string, Class>;
}>;

export class ExpressApp {
public readonly expressApp: express.Application;
public readonly port: string;
public readonly url: string;
public readonly keycloakUrl?: string;
public readonly middleware: tsRest.RouteMiddlewareFactory[];
public readonly modules: Record<string, utils.Class>;
public readonly middleware: RouteMiddlewareFactory[];
public readonly modules: Record<string, Class>;

#mongoClient: mongodb.MongoClient;
#mockModules: Record<string, utils.Class>;
#mongoClient: MongoClient;
#mockModules: Record<string, Class>;

constructor(config: ExpressAppConfig = {}) {
this.middleware = config.middleware ?? [];
Expand All @@ -38,15 +40,15 @@ export class ExpressApp {
return this.#mockModules;
}

public get mongoClient(): mongodb.MongoClient {
public get mongoClient(): MongoClient {
return this.#mongoClient;
}

private get memoryUsage() {
return `${Math.round((process.memoryUsage().heapUsed / 1024 / 1024) * 100) / 100} MB`;
}

public async init(mocks: Record<string, utils.Class> = {}): Promise<void> {
public async init(mocks: Record<string, Class> = {}): Promise<void> {
log.info("Initializing Swagger");
this.#initializeSwagger();
log.info("Initializing IoC container");
Expand Down Expand Up @@ -85,17 +87,17 @@ export class ExpressApp {
}

async #initializeDatabase() {
this.#mongoClient = mongodb.MongoDatabaseService.buildMongoClient();
this.#mongoClient = MongoDatabaseService.buildMongoClient();
await this.#mongoClient.connect();
}

#initializeIoc(mocks: Record<string, utils.Class>) {
#initializeIoc(mocks: Record<string, Class>) {
this.#mockModules = mocks;
const modules = this.modules;
const localModules: Record<string, utils.Class> = {};
const localModules: Record<string, Class> = {};
Object.entries(modules).forEach(([key, value]) => (localModules[key.toLowerCase()] = value));
Object.entries(mocks).forEach(([key, value]) => (localModules[key.toLowerCase()] = value));
bottleJs.iocRegistry.iocStartup(localModules);
iocRegistry.iocStartup(localModules);
}

#initializeGlobalMiddlewares() {
Expand All @@ -105,11 +107,11 @@ export class ExpressApp {
}

#initializeExpressRoutes() {
tsRest.initializeExpressRoutes(this.expressApp);
initializeExpressRoutes(this.expressApp);
}

#initializeSwagger() {
tsRest.initializeSwagger({
initializeSwagger({
app: this.expressApp,
oauth2RedirectUrl: `${this.url}${env.SWAGGER_ENDPOINT}${env.SWAGGER_OAUTH2_REDIRECT_ENDPOINT}`,
version: env.PACKAGE_JSON_VERSION,
Expand All @@ -122,7 +124,7 @@ export class ExpressApp {
#initializeErrorHandlerMiddleware() {
const errorHandler: express.ErrorRequestHandler = (error: unknown, req, res, next) => {
if (res.headersSent) return next(error);
const err = apiClientUtils.getTypedError(error);
const err = getTypedError(error);
log.warn(`Headers sent before reaching main error handler`, err);
res.status(err.content.status).json(err.content);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import { getSession } from "@org/app-node-express/config/SessionStorage";
// Do not remove!
import { type TODO } from "@org/lib-commons";

export abstract class Repository<T extends Entity<zod.AnyZodObject>> {
export abstract class Repository<T extends Entity> {
private readonly schema: zod.ZodSchema<T>;
private readonly searchFields: string[];

constructor(schema: zod.ZodSchema<T>, searchFields: string[] = []) {
this.schema = schema;
constructor(object: T, searchFields: string[] = []) {
this.schema = object.schema;
this.searchFields = searchFields;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export class KeycloakRepository extends KeycloakDao implements AuthorizationRepo
}

private mapper(model: ApiKeycloakUser): User {
return { ...model, roles: [] };
return {
_id: model.id,
username: model.username,
roles: [],
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type UserCreateFormButtonProps = {
};

const DEFAULT_FORM_STATE: User = {
id: "",
_id: "",
username: "",
roles: ["user"],
};
Expand Down
3 changes: 1 addition & 2 deletions packages/mern-sample-app/lib-api-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"@anatine/zod-openapi": "^2.2.5",
"@ts-rest/core": "^3.45.0",
"@ts-rest/open-api": "^3.45.0",
"@org/lib-commons": "workspace:*",
"zod": "^3.23.8"
"@org/lib-commons": "workspace:*"
},
"devDependencies": {
"rimraf": "^5.0.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { initContract } from "@ts-rest/core";
import { routeCommonProps } from "./../../lib/@ts-rest";
import { RestErrorSchema } from "../../schemas/RestErrorSchema";
import { RestError500Schema } from "../../schemas/RestError500Schema";
import { RestErrorSchema, RestError500Schema } from "../models";
import { JsonQueryParam, PaginationOptions, User } from "../models";
import { UserPaginationResultDto } from "../dto";
import { z } from "@org/lib-commons";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { z, type zod } from "@org/lib-commons";
import { ApiKeycloakUser } from "../../lib";
import { Entity } from "./utils";

export const User = ApiKeycloakUser.extend({
export const User = Entity("User", {
username: z.string(),
roles: z.array(z.string()),
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { z, type zod } from "@org/lib-commons";

export function Entity<const T extends zod.ZodRawShape>(
name: string,
shape: T,
): zod.ZodObject<T & { _id: zod.ZodOptional<zod.ZodString> }> {
if (!name) {
throw new Error("entity name must not be blank");
}

return z
.object({
_id: z.string().optional(),
...shape,
})
.describe(name);
}

export type Entity<T extends object> = T & { _id?: string };
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { z } from "@org/lib-commons";
import { z, type zod } from "@org/lib-commons";

export const RestError500Schema = z
.object({
Expand All @@ -23,3 +23,5 @@ export const RestError500Schema = z
title: "RestError",
description: "Rest error 500",
});

export type RestError500Schema = zod.infer<typeof RestError500Schema>;
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { RestError500Schema } from "./RestError500Schema";
import { type zod } from "@org/lib-commons";

export const RestErrorSchema = RestError500Schema.extend({}).describe("").openapi({
title: undefined,
description: undefined,
});

export type RestErrorSchema = zod.infer<typeof RestErrorSchema>;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PaginationResult } from "./PaginationResult";
import { z, type zod } from "@org/lib-commons";

/** @hidden */
export function TypedPaginationResult<T extends zod.AnyZodObject>(schema: T) {
export function TypedPaginationResult<const T extends zod.AnyZodObject>(schema: T) {
return PaginationResult.extend({
data: z.array(schema),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ export * from "./PaginationResult";
export * from "./TypedPaginationResult";
export * from "./JsonQueryParam";
export * from "./PaginationOptions";
export * from "./RestError500Schema";
export * from "./RestErrorSchema";
export * from "./Entity";
1 change: 0 additions & 1 deletion packages/mern-sample-app/lib-api-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@
export * from "./app";
export * from "./lib";
export * from "./errors";
export * from "./schemas";
2 changes: 0 additions & 2 deletions packages/mern-sample-app/lib-api-client/src/schemas/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// <reference types="@types/jest" />

import { Entity } from "../src/config/Entity.config";
import { z } from "../src/lib";
import { Entity } from "../src/app/models/utils/Entity";
import { z } from "@org/lib-commons/src/lib";

describe("Entity", () => {
describe("given the entity name is present", () => {
Expand Down
25 changes: 0 additions & 25 deletions packages/mern-sample-app/lib-commons/src/config/Entity.config.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/mern-sample-app/lib-commons/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./Entity.config";
export * from "./Types.config";
3 changes: 2 additions & 1 deletion packages/mern-sample-app/lib-commons/src/lib/zod/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as zod from "zod";
import { type TODO } from "../../config";
import { extendZodWithOpenApi } from "@anatine/zod-openapi";
import type { z as zodInternal } from "zod";

type AnatineZodOpenapi = (data: TODO) => TODO;

Expand All @@ -18,6 +19,6 @@ function initZod(): AugmentedZod {
return zod as AugmentedZod;
}

export const z = initZod();
export const z: typeof zodInternal & { openapi: AnatineZodOpenapi } = initZod();

export type { zod };
Loading

0 comments on commit 318c02d

Please sign in to comment.