Skip to content

Commit

Permalink
feat: move and fix things
Browse files Browse the repository at this point in the history
  • Loading branch information
BoscoDomingo committed Nov 9, 2024
1 parent 0c860ff commit 602319c
Show file tree
Hide file tree
Showing 37 changed files with 405 additions and 407 deletions.
3 changes: 3 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NODE_COMPILE_CACHE = /tmp/node-cache
PORT = 8080
NODE_ENV=test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# API keys and secrets
.env*
!.env.example
!.env.test

# Dependency directory
node_modules
Expand All @@ -16,3 +17,6 @@ coverage
!.vscode/extensions.json
!.vscode/*.code-snippets
.vscode

logs
*.log
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This repository is intended to serve as a starting point if you want to bootstra
- No proper DI framework/container/tool (just simple DI via constructor injection)
- Logging tied to the framework (Fastify)
- Ready for events, but not yet implemented
- Due to Node.js' handling of .env files, testing will fail in CI unless the files exist. [A PR is in the works to fix this](https://github.com/nodejs/node/pull/53060).

If these issues don't matter for your intended use, or you know how to fix them, this will be a fast way to run a quick script or program.
If you're looking for a simpler setup, check out my [TypeScript API Template](https://github.com/BoscoDomingo/typescript-api-skeleton) or my [TypeScript Simple Setup](https://github.com/BoscoDomingo/typescript-skeleton)
Expand Down
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@
"src",
"dist"
],
"workspaces": [
"apps/*",
"packages/*"
],
"private": true,
"scripts": {
"start": "node --env-file-if-exists=.env ./dist/src/app.js",
"start": "node --env-file-if-exists=.env ./dist/app.js",
"dev": "tsx watch --clear-screen=false --env-file-if-exists=.env ./src/app.ts",
"build": "tsc -p tsconfig.build.json",
"build": "tsc -p tsconfig.json",
"lint": "biome check",
"format": "biome check --write",
"test": "glob -c \"FASTIFY_AUTOLOAD_TYPESCRIPT=1 tsx --tsconfig ./test/tsconfig.json --env-file-if-exists .env --env-file-if-exists .env.test --test\" \"./test/**/*.test.ts\""
Expand All @@ -32,7 +36,6 @@
},
"homepage": "https://github.com/AlexHHPS/typescript-ddd-hexagonal-ddd#readme",
"dependencies": {
"@fastify/autoload": "^6.0.2",
"@fastify/cors": "^10.0.1",
"@fastify/helmet": "^12.0.1",
"@fastify/rate-limit": "^10.1.1",
Expand Down
8 changes: 0 additions & 8 deletions pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import closeWithGrace from "close-with-grace";
import { Server } from "./server.js";
import { Server } from "./infrastructure/server.js";

// This is generally not a good practice for libraries,
// but since it is for internal use only, it is acceptable.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { User } from "../../../domain/domain1/entities/user.entity.js";

export class CreateUserUseCaseInput {
constructor(readonly user: User) {}
}
import type { User } from "../../domain/entities/user.entity.js";

export class CreateUserUseCaseInput {
constructor(readonly user: User) {}
}
5 changes: 5 additions & 0 deletions src/application/createUser/createUserUseCase.output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { UUIDv7 } from "../../domain/value_objects/uuidv7.js";

export interface CreateUserUseCaseOutput {
id: UUIDv7;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { UserRepository } from "../../../domain/domain1/repositories/user.repository.js";
import type { CreateUserUseCaseInput } from "./createUserUseCase.input.js";
import type { CreateUserUseCaseOutput } from "./createUserUseCase.output.js";

export class CreateUserUseCase {
constructor(private readonly repository: UserRepository) {}

async execute({
user,
}: CreateUserUseCaseInput): Promise<CreateUserUseCaseOutput> {
await this.repository.save(user);
// TO-DO: Send the createdUser event
return { id: user.id };
}
}
import type { UserRepository } from "../../domain/repositories/user.repository.js";
import type { CreateUserUseCaseInput } from "./createUserUseCase.input.js";
import type { CreateUserUseCaseOutput } from "./createUserUseCase.output.js";

export class CreateUserUseCase {
constructor(private readonly repository: UserRepository) {}

async execute({
user,
}: CreateUserUseCaseInput): Promise<CreateUserUseCaseOutput> {
await this.repository.save(user);
// TO-DO: Send the createdUser event
return { id: user.id };
}
}

This file was deleted.

5 changes: 0 additions & 5 deletions src/application/domain1/getUser/getUserUseCase.input.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/application/getUser/getUserUseCase.input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { UUIDv7 } from "../../domain/value_objects/uuidv7.js";

export interface FindUserUseCaseInput {
id: UUIDv7;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import type { User } from "../../../domain/domain1/entities/user.entity.js";
import type { UserRepository } from "../../../domain/domain1/repositories/user.repository.js";

import type { FindUserUseCaseInput as GetUserUseCaseInput } from "./getUserUseCase.input.js";

export class GetUserUseCase {
constructor(private readonly repository: UserRepository) {}

async execute(input: GetUserUseCaseInput): Promise<User> {
const result = await this.repository.getById(input.id);
return result;
}
}
import type { User } from "../../domain/entities/user.entity.js";
import type { UserRepository } from "../../domain/repositories/user.repository.js";
import type { FindUserUseCaseInput as GetUserUseCaseInput } from "./getUserUseCase.input.js";

export class GetUserUseCase {
constructor(private readonly repository: UserRepository) {}

async execute(input: GetUserUseCaseInput): Promise<User> {
const result = await this.repository.getById(input.id);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { Filter } from "./filter.js";
import type { CursorPagination, Pagination } from "./pagination.js";
import type { Sorting } from "./sorting.js";

export interface ExampleCriteria {
readonly filters: Set<Filter>;
readonly sorting?: Sorting;
readonly pagination?: Pagination | CursorPagination;
}
import type { Filter } from "./filter.js";
import type { CursorPagination, Pagination } from "./pagination.js";
import type { Sorting } from "./sorting.js";

/** Represents a query combining multiple filters.
Filters inside a group are combined with `AND`, different groups are combined with `OR` */
export interface CompositeCriteria {
readonly filterGroups: Set<Set<Filter>>;
readonly sorting?: Sorting;
readonly pagination?: Pagination | CursorPagination;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Operators } from "./operators.js";

export interface Filter {
readonly field: string;
readonly operator: Operators;
readonly value: string | number | boolean | Date;
}
import type { Operators } from "./operators.js";

export interface Filter {
readonly field: string;
readonly operator: Operators;
readonly value: string | number | boolean | Date;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
export enum Operators {
EQUAL = "EQ",
NOT_EQUAL = "NE",
GREATER_THAN = "GT",
GREATER_THAN_OR_EQUAL = "GTE",
LESS_THAN = "LT",
LESS_THAN_OR_EQUAL = "LTE",
EXISTS = "EXISTS",
// IN = "IN",
// NOT_IN = "NOT_IN",
// LIKE = "LIKE",
// NOT_LIKE = "NOT_LIKE",
// IS_NULL = "IS_NULL",
// IS_NOT_NULL = "IS_NOT_NULL",
// BETWEEN = "BETWEEN",
}
export enum Operators {
EQUAL = "EQ",
NOT_EQUAL = "NE",
GREATER_THAN = "GT",
GREATER_THAN_OR_EQUAL = "GTE",
LESS_THAN = "LT",
LESS_THAN_OR_EQUAL = "LTE",
EXISTS = "EXISTS",
// IN = "IN",
// NOT_IN = "NOT_IN",
// LIKE = "LIKE",
// NOT_LIKE = "NOT_LIKE",
// IS_NULL = "IS_NULL",
// IS_NOT_NULL = "IS_NOT_NULL",
// BETWEEN = "BETWEEN",
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export interface Pagination {
readonly page?: number;
readonly size?: number;
}

export interface CursorPagination {
readonly cursor?: string;
readonly direction?: "before" | "after" | "around";
readonly size?: number;
readonly includeCursor?: boolean;
}
export interface Pagination {
readonly page?: number;
readonly size?: number;
}

export interface CursorPagination {
readonly cursor?: string;
readonly direction?: "before" | "after" | "around";
readonly size?: number;
readonly includeCursor?: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface Sorting {
readonly field: string;
readonly direction: "asc" | "desc";
}
export interface Sorting {
readonly field: string;
readonly direction: "asc" | "desc";
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { UUIDv7 } from "../../value_objects/uuidv7.js";

export class User {
readonly id: UUIDv7 = new UUIDv7();
name: string;
readonly createdAt: Date;
updatedAt: Date;

constructor(input: {
readonly id?: UUIDv7;
readonly name: string;
readonly createdAt: Date;
readonly updatedAt: Date;
}) {
const { id, name, createdAt, updatedAt } = input;

// These are just example validations, you should add your own
if (createdAt > new Date()) {
throw new Error("Invalid createdAt date");
}

if (updatedAt > new Date()) {
throw new Error("Invalid updatedAt date");
}

this.id = id ?? new UUIDv7();
this.name = name;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
}
import { UUIDv7 } from "../value_objects/uuidv7.js";

export class User {
readonly id: UUIDv7 = new UUIDv7();
name: string;
readonly createdAt: Date;
updatedAt: Date;

constructor(input: {
readonly id?: UUIDv7;
readonly name: string;
readonly createdAt: Date;
readonly updatedAt: Date;
}) {
const { id, name, createdAt, updatedAt } = input;

// These are just example validations, you should add your own
if (createdAt > new Date()) {
throw new Error("Invalid createdAt date");
}

if (updatedAt > new Date()) {
throw new Error("Invalid updatedAt date");
}

this.id = id ?? new UUIDv7();
this.name = name;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export class InsertError extends Error {
constructor(message: string, data: Record<string, unknown>) {
super(`${message}: ${JSON.stringify(data)}`);
}
}
export class InsertError extends Error {
constructor(message: string, data: Record<string, unknown>) {
super(`${message}: ${JSON.stringify(data)}`);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export class NotFoundError extends Error {
constructor(message: string, data: Record<string, unknown>) {
super(`${message}: ${JSON.stringify(data)}`);
}
}
export class NotFoundError extends Error {
constructor(message: string, data: Record<string, unknown>) {
super(`${message}: ${JSON.stringify(data)}`);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export class ExampleEvent {
constructor(
public readonly message: string,
public readonly data: Map<string, unknown>,
public readonly createdAt: Date,
public readonly receivedAt: Date,
) {}
}
export class ExampleEvent {
constructor(
public readonly message: string,
public readonly data: Map<string, unknown>,
public readonly createdAt: Date,
public readonly receivedAt: Date,
) {}
}
Loading

0 comments on commit 602319c

Please sign in to comment.