mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
chore: remove core package
Remove the @puaros/core package as it has been superseded by guardian package.
This commit is contained in:
13
packages/core/.gitignore
vendored
13
packages/core/.gitignore
vendored
@@ -1,13 +0,0 @@
|
|||||||
# Build output
|
|
||||||
dist/
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# Test coverage
|
|
||||||
coverage/
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Source files (only publish dist/)
|
|
||||||
src/
|
|
||||||
*.ts
|
|
||||||
!*.d.ts
|
|
||||||
|
|
||||||
# Build artifacts
|
|
||||||
tsconfig.json
|
|
||||||
tsconfig.*.json
|
|
||||||
tsconfig.tsbuildinfo
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Tests
|
|
||||||
**/*.spec.ts
|
|
||||||
**/*.test.ts
|
|
||||||
__tests__/
|
|
||||||
coverage/
|
|
||||||
|
|
||||||
# Development
|
|
||||||
node_modules/
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
|
|
||||||
# IDE
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
|
|
||||||
# Git
|
|
||||||
.git/
|
|
||||||
.gitignore
|
|
||||||
|
|
||||||
# Other
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
.DS_Store
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@puaros/core",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"private": true,
|
|
||||||
"description": "Core business logic for Puaros",
|
|
||||||
"keywords": [
|
|
||||||
"puaros"
|
|
||||||
],
|
|
||||||
"main": "dist/index.js",
|
|
||||||
"types": "dist/index.d.ts",
|
|
||||||
"author": "Fozilbek Samiyev <fozilbek.samiyev@gmail.com>",
|
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
|
||||||
"build": "tsc",
|
|
||||||
"watch": "tsc --watch",
|
|
||||||
"clean": "rm -rf dist",
|
|
||||||
"test": "vitest",
|
|
||||||
"test:ui": "vitest --ui",
|
|
||||||
"test:watch": "vitest --watch",
|
|
||||||
"test:coverage": "vitest run --coverage",
|
|
||||||
"test:run": "vitest run"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"simple-git": "^3.30.0",
|
|
||||||
"tree-sitter": "^0.21.1",
|
|
||||||
"tree-sitter-javascript": "^0.23.0",
|
|
||||||
"tree-sitter-typescript": "^0.23.0",
|
|
||||||
"uuid": "^13.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^22.10.7",
|
|
||||||
"@types/uuid": "^11.0.0",
|
|
||||||
"@vitest/coverage-v8": "^4.0.10",
|
|
||||||
"@vitest/ui": "^4.0.10",
|
|
||||||
"typescript": "^5.7.3",
|
|
||||||
"vitest": "^4.0.10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Standard response wrapper for use cases
|
|
||||||
*/
|
|
||||||
export interface IResponseDto<T> {
|
|
||||||
success: boolean;
|
|
||||||
data?: T;
|
|
||||||
error?: string;
|
|
||||||
timestamp: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ResponseDto<T> implements IResponseDto<T> {
|
|
||||||
public readonly success: boolean;
|
|
||||||
public readonly data?: T;
|
|
||||||
public readonly error?: string;
|
|
||||||
public readonly timestamp: Date;
|
|
||||||
|
|
||||||
private constructor(success: boolean, data?: T, error?: string) {
|
|
||||||
this.success = success;
|
|
||||||
this.data = data;
|
|
||||||
this.error = error;
|
|
||||||
this.timestamp = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ok<T>(data: T): ResponseDto<T> {
|
|
||||||
return new ResponseDto<T>(true, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static fail<T>(error: string): ResponseDto<T> {
|
|
||||||
return new ResponseDto<T>(false, undefined, error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './use-cases/UseCase';
|
|
||||||
export * from './dtos/ResponseDto';
|
|
||||||
export * from './mappers/Mapper';
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* Generic mapper interface for converting between domain entities and DTOs
|
|
||||||
*/
|
|
||||||
export interface IMapper<TDomain, TDto> {
|
|
||||||
toDto(domain: TDomain): TDto;
|
|
||||||
toDomain(dto: TDto): TDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
export abstract class Mapper<TDomain, TDto> implements IMapper<TDomain, TDto> {
|
|
||||||
public abstract toDto(domain: TDomain): TDto;
|
|
||||||
public abstract toDomain(dto: TDto): TDomain;
|
|
||||||
|
|
||||||
public toDtoList(domains: TDomain[]): TDto[] {
|
|
||||||
return domains.map((domain) => this.toDto(domain));
|
|
||||||
}
|
|
||||||
|
|
||||||
public toDomainList(dtos: TDto[]): TDomain[] {
|
|
||||||
return dtos.map((dto) => this.toDomain(dto));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Base interface for all use cases
|
|
||||||
*/
|
|
||||||
export interface IUseCase<TRequest, TResponse> {
|
|
||||||
execute(request: TRequest): Promise<TResponse>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract base class for use cases
|
|
||||||
*/
|
|
||||||
export abstract class UseCase<TRequest, TResponse> implements IUseCase<TRequest, TResponse> {
|
|
||||||
public abstract execute(request: TRequest): Promise<TResponse>;
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base entity class with ID and timestamps
|
|
||||||
*/
|
|
||||||
export abstract class BaseEntity {
|
|
||||||
protected readonly _id: string;
|
|
||||||
protected readonly _createdAt: Date;
|
|
||||||
protected _updatedAt: Date;
|
|
||||||
|
|
||||||
constructor(id?: string) {
|
|
||||||
this._id = id ?? uuidv4();
|
|
||||||
this._createdAt = new Date();
|
|
||||||
this._updatedAt = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
public get id(): string {
|
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get createdAt(): Date {
|
|
||||||
return this._createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get updatedAt(): Date {
|
|
||||||
return this._updatedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected touch(): void {
|
|
||||||
this._updatedAt = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
public equals(entity: BaseEntity): boolean {
|
|
||||||
if (entity === null || entity === undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this === entity) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._id === entity._id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base interface for all domain events
|
|
||||||
*/
|
|
||||||
export interface IDomainEvent {
|
|
||||||
readonly eventId: string;
|
|
||||||
readonly occurredOn: Date;
|
|
||||||
readonly eventType: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for domain events
|
|
||||||
*/
|
|
||||||
export abstract class DomainEvent implements IDomainEvent {
|
|
||||||
public readonly eventId: string;
|
|
||||||
public readonly occurredOn: Date;
|
|
||||||
public readonly eventType: string;
|
|
||||||
|
|
||||||
constructor(eventType: string) {
|
|
||||||
this.eventId = uuidv4();
|
|
||||||
this.occurredOn = new Date();
|
|
||||||
this.eventType = eventType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './entities/BaseEntity';
|
|
||||||
export * from './value-objects/ValueObject';
|
|
||||||
export * from './repositories/IRepository';
|
|
||||||
export * from './events/DomainEvent';
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { BaseEntity } from '../entities/BaseEntity';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic repository interface
|
|
||||||
* Defines standard CRUD operations for entities
|
|
||||||
*/
|
|
||||||
export interface IRepository<T extends BaseEntity> {
|
|
||||||
findById(id: string): Promise<T | null>;
|
|
||||||
findAll(): Promise<T[]>;
|
|
||||||
save(entity: T): Promise<T>;
|
|
||||||
update(entity: T): Promise<T>;
|
|
||||||
delete(id: string): Promise<boolean>;
|
|
||||||
exists(id: string): Promise<boolean>;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* Base class for Value Objects
|
|
||||||
* Value objects are immutable and compared by value, not identity
|
|
||||||
*/
|
|
||||||
export abstract class ValueObject<T> {
|
|
||||||
protected readonly props: T;
|
|
||||||
|
|
||||||
constructor(props: T) {
|
|
||||||
this.props = Object.freeze(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
public equals(vo?: ValueObject<T>): boolean {
|
|
||||||
if (vo === null || vo === undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vo.props === undefined) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.stringify(this.props) === JSON.stringify(vo.props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './domain';
|
|
||||||
export * from './application';
|
|
||||||
export * from './infrastructure';
|
|
||||||
export * from './shared';
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import simpleGit, { SimpleGit, SimpleGitOptions } from 'simple-git';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Git operations service using simple-git
|
|
||||||
*/
|
|
||||||
export class GitService {
|
|
||||||
private readonly git: SimpleGit;
|
|
||||||
|
|
||||||
constructor(baseDir: string, options?: Partial<SimpleGitOptions>) {
|
|
||||||
this.git = simpleGit(baseDir, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async clone(repoUrl: string, localPath: string): Promise<void> {
|
|
||||||
await this.git.clone(repoUrl, localPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async status(): Promise<string> {
|
|
||||||
const statusSummary = await this.git.status();
|
|
||||||
return JSON.stringify(statusSummary, null, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async log(maxCount: number = 10): Promise<string> {
|
|
||||||
const logResult = await this.git.log({ maxCount });
|
|
||||||
return JSON.stringify(logResult, null, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async add(files: string | string[]): Promise<void> {
|
|
||||||
await this.git.add(files);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async commit(message: string): Promise<void> {
|
|
||||||
await this.git.commit(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async push(remote: string = 'origin', branch: string = 'main'): Promise<void> {
|
|
||||||
await this.git.push(remote, branch);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async pull(remote: string = 'origin', branch: string = 'main'): Promise<void> {
|
|
||||||
await this.git.pull(remote, branch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './repositories/BaseRepository';
|
|
||||||
export * from './git/GitService';
|
|
||||||
export * from './parsers/CodeParser';
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import Parser from 'tree-sitter';
|
|
||||||
import JavaScript from 'tree-sitter-javascript';
|
|
||||||
import TypeScript from 'tree-sitter-typescript';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Code parser service using tree-sitter
|
|
||||||
*/
|
|
||||||
export class CodeParser {
|
|
||||||
private readonly parser: Parser;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.parser = new Parser();
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseJavaScript(code: string): Parser.Tree {
|
|
||||||
this.parser.setLanguage(JavaScript);
|
|
||||||
return this.parser.parse(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseTypeScript(code: string): Parser.Tree {
|
|
||||||
this.parser.setLanguage(TypeScript.typescript);
|
|
||||||
return this.parser.parse(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseTsx(code: string): Parser.Tree {
|
|
||||||
this.parser.setLanguage(TypeScript.tsx);
|
|
||||||
return this.parser.parse(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public extractFunctions(tree: Parser.Tree): string[] {
|
|
||||||
const functions: string[] = [];
|
|
||||||
const cursor = tree.walk();
|
|
||||||
|
|
||||||
const visit = (): void => {
|
|
||||||
const node = cursor.currentNode;
|
|
||||||
|
|
||||||
if (
|
|
||||||
node.type === 'function_declaration' ||
|
|
||||||
node.type === 'arrow_function' ||
|
|
||||||
node.type === 'function_expression'
|
|
||||||
) {
|
|
||||||
functions.push(node.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor.gotoFirstChild()) {
|
|
||||||
do {
|
|
||||||
visit();
|
|
||||||
} while (cursor.gotoNextSibling());
|
|
||||||
cursor.gotoParent();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
visit();
|
|
||||||
return functions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { BaseEntity } from '../../domain/entities/BaseEntity';
|
|
||||||
import { IRepository } from '../../domain/repositories/IRepository';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract base repository implementation
|
|
||||||
* Provides common repository functionality
|
|
||||||
*/
|
|
||||||
export abstract class BaseRepository<T extends BaseEntity> implements IRepository<T> {
|
|
||||||
protected readonly items: Map<string, T> = new Map();
|
|
||||||
|
|
||||||
public async findById(id: string): Promise<T | null> {
|
|
||||||
return this.items.get(id) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async findAll(): Promise<T[]> {
|
|
||||||
return Array.from(this.items.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
public async save(entity: T): Promise<T> {
|
|
||||||
this.items.set(entity.id, entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async update(entity: T): Promise<T> {
|
|
||||||
if (!this.items.has(entity.id)) {
|
|
||||||
throw new Error(`Entity with id ${entity.id} not found`);
|
|
||||||
}
|
|
||||||
this.items.set(entity.id, entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async delete(id: string): Promise<boolean> {
|
|
||||||
return this.items.delete(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async exists(id: string): Promise<boolean> {
|
|
||||||
return this.items.has(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
export const APP_CONSTANTS = {
|
|
||||||
DEFAULT_TIMEOUT: 5000,
|
|
||||||
MAX_RETRIES: 3,
|
|
||||||
VERSION: '0.0.1',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const ERROR_MESSAGES = {
|
|
||||||
VALIDATION_FAILED: 'Validation failed',
|
|
||||||
NOT_FOUND: 'Resource not found',
|
|
||||||
UNAUTHORIZED: 'Unauthorized access',
|
|
||||||
INTERNAL_ERROR: 'Internal server error',
|
|
||||||
} as const;
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Base error class for custom application errors
|
|
||||||
*/
|
|
||||||
export abstract class BaseError extends Error {
|
|
||||||
public readonly timestamp: Date;
|
|
||||||
public readonly code: string;
|
|
||||||
|
|
||||||
constructor(message: string, code: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = this.constructor.name;
|
|
||||||
this.code = code;
|
|
||||||
this.timestamp = new Date();
|
|
||||||
Error.captureStackTrace(this, this.constructor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ValidationError extends BaseError {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message, 'VALIDATION_ERROR');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class NotFoundError extends BaseError {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message, 'NOT_FOUND');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UnauthorizedError extends BaseError {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message, 'UNAUTHORIZED');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class InternalError extends BaseError {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message, 'INTERNAL_ERROR');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './types/Result';
|
|
||||||
export * from './errors/BaseError';
|
|
||||||
export * from './utils/Guards';
|
|
||||||
export * from './constants';
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* Result type for handling success/failure scenarios
|
|
||||||
*/
|
|
||||||
export type Result<T, E = Error> = Success<T> | Failure<E>;
|
|
||||||
|
|
||||||
export class Success<T> {
|
|
||||||
public readonly isSuccess = true;
|
|
||||||
public readonly isFailure = false;
|
|
||||||
|
|
||||||
constructor(public readonly value: T) {}
|
|
||||||
|
|
||||||
public static create<T>(value: T): Success<T> {
|
|
||||||
return new Success(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Failure<E> {
|
|
||||||
public readonly isSuccess = false;
|
|
||||||
public readonly isFailure = true;
|
|
||||||
|
|
||||||
constructor(public readonly error: E) {}
|
|
||||||
|
|
||||||
public static create<E>(error: E): Failure<E> {
|
|
||||||
return new Failure(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ok = <T>(value: T): Result<T> => new Success(value);
|
|
||||||
export const fail = <E>(error: E): Result<never, E> => new Failure(error);
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* Type guard utilities for runtime type checking
|
|
||||||
*/
|
|
||||||
export class Guards {
|
|
||||||
public static isNullOrUndefined(value: unknown): value is null | undefined {
|
|
||||||
return value === null || value === undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isString(value: unknown): value is string {
|
|
||||||
return typeof value === 'string';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isNumber(value: unknown): value is number {
|
|
||||||
return typeof value === 'number' && !isNaN(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isBoolean(value: unknown): value is boolean {
|
|
||||||
return typeof value === 'boolean';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isObject(value: unknown): value is object {
|
|
||||||
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isArray<T>(value: unknown): value is T[] {
|
|
||||||
return Array.isArray(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static isEmpty(value: string | unknown[] | object | null | undefined): boolean {
|
|
||||||
if (Guards.isNullOrUndefined(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Guards.isString(value) || Guards.isArray(value)) {
|
|
||||||
return value.length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Guards.isObject(value)) {
|
|
||||||
return Object.keys(value).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
export function add(a: number, b: number): number {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const multiply = (a: number, b: number): number => {
|
|
||||||
return a * b;
|
|
||||||
};
|
|
||||||
|
|
||||||
export class Calculator {
|
|
||||||
public divide(a: number, b: number): number {
|
|
||||||
if (b === 0) {
|
|
||||||
throw new Error('Division by zero');
|
|
||||||
}
|
|
||||||
return a / b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
|
||||||
import { BaseEntity } from '../../../src/domain/entities/BaseEntity';
|
|
||||||
|
|
||||||
class TestEntity extends BaseEntity {
|
|
||||||
constructor(id?: string) {
|
|
||||||
super(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('BaseEntity', () => {
|
|
||||||
it('should create an entity with generated id', () => {
|
|
||||||
const entity = new TestEntity();
|
|
||||||
expect(entity.id).toBeDefined();
|
|
||||||
expect(typeof entity.id).toBe('string');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an entity with provided id', () => {
|
|
||||||
const customId = 'custom-id-123';
|
|
||||||
const entity = new TestEntity(customId);
|
|
||||||
expect(entity.id).toBe(customId);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should have createdAt and updatedAt timestamps', () => {
|
|
||||||
const entity = new TestEntity();
|
|
||||||
expect(entity.createdAt).toBeInstanceOf(Date);
|
|
||||||
expect(entity.updatedAt).toBeInstanceOf(Date);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true when comparing same entity', () => {
|
|
||||||
const entity = new TestEntity();
|
|
||||||
expect(entity.equals(entity)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true when comparing entities with same id', () => {
|
|
||||||
const id = 'same-id';
|
|
||||||
const entity1 = new TestEntity(id);
|
|
||||||
const entity2 = new TestEntity(id);
|
|
||||||
expect(entity1.equals(entity2)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when comparing entities with different ids', () => {
|
|
||||||
const entity1 = new TestEntity();
|
|
||||||
const entity2 = new TestEntity();
|
|
||||||
expect(entity1.equals(entity2)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
|
||||||
import { Guards } from '../../../src/shared/utils/Guards';
|
|
||||||
|
|
||||||
describe('Guards', () => {
|
|
||||||
describe('isNullOrUndefined', () => {
|
|
||||||
it('should return true for null', () => {
|
|
||||||
expect(Guards.isNullOrUndefined(null)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for undefined', () => {
|
|
||||||
expect(Guards.isNullOrUndefined(undefined)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for other values', () => {
|
|
||||||
expect(Guards.isNullOrUndefined(0)).toBe(false);
|
|
||||||
expect(Guards.isNullOrUndefined('')).toBe(false);
|
|
||||||
expect(Guards.isNullOrUndefined(false)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isString', () => {
|
|
||||||
it('should return true for strings', () => {
|
|
||||||
expect(Guards.isString('hello')).toBe(true);
|
|
||||||
expect(Guards.isString('')).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for non-strings', () => {
|
|
||||||
expect(Guards.isString(123)).toBe(false);
|
|
||||||
expect(Guards.isString(null)).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isEmpty', () => {
|
|
||||||
it('should return true for empty strings', () => {
|
|
||||||
expect(Guards.isEmpty('')).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for empty arrays', () => {
|
|
||||||
expect(Guards.isEmpty([])).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for empty objects', () => {
|
|
||||||
expect(Guards.isEmpty({})).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for null/undefined', () => {
|
|
||||||
expect(Guards.isEmpty(null)).toBe(true);
|
|
||||||
expect(Guards.isEmpty(undefined)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for non-empty values', () => {
|
|
||||||
expect(Guards.isEmpty('text')).toBe(false);
|
|
||||||
expect(Guards.isEmpty([1])).toBe(false);
|
|
||||||
expect(Guards.isEmpty({ key: 'value' })).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "./dist",
|
|
||||||
"rootDir": "./src",
|
|
||||||
"target": "ES2023",
|
|
||||||
"module": "CommonJS",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"composite": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"baseUrl": "./src"
|
|
||||||
},
|
|
||||||
"include": ["src/**/*"],
|
|
||||||
"exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"]
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { defineConfig } from 'vitest/config';
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
globals: true,
|
|
||||||
environment: 'node',
|
|
||||||
coverage: {
|
|
||||||
provider: 'v8',
|
|
||||||
reporter: ['text', 'json', 'html', 'lcov'],
|
|
||||||
exclude: [
|
|
||||||
'**/node_modules/**',
|
|
||||||
'**/dist/**',
|
|
||||||
'**/*.test.ts',
|
|
||||||
'**/*.spec.ts',
|
|
||||||
'**/tests/**',
|
|
||||||
],
|
|
||||||
thresholds: {
|
|
||||||
lines: 80,
|
|
||||||
functions: 80,
|
|
||||||
branches: 80,
|
|
||||||
statements: 80,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user