elseware-nodejs 1.8.7 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,86 +1,13 @@
1
- import * as express from 'express';
2
- import { Request, Response, NextFunction } from 'express';
3
- import { Model, PopulateOptions, Query, UpdateQuery } from 'mongoose';
4
- import { ZodTypeAny, infer } from 'zod';
1
+ import { ZodTypeAny, infer, ZodSchema } from 'zod';
5
2
  import { CorsOptions } from 'cors';
3
+ import * as express from 'express';
4
+ import { Request, Response, NextFunction, RequestHandler } from 'express';
5
+ import * as qs from 'qs';
6
+ import * as express_serve_static_core from 'express-serve-static-core';
6
7
  import { Schema } from 'joi';
8
+ import { Model, UpdateQuery } from 'mongoose';
7
9
  import { SignOptions, JwtPayload } from 'jsonwebtoken';
8
10
 
9
- /**
10
- * Options for API factory methods
11
- */
12
- interface ApiFactoryOptions<T = unknown> {
13
- message?: string;
14
- notFoundMessage?: string;
15
- populate?: PopulateOptions | PopulateOptions[];
16
- filter?: (req: Request) => Record<string, unknown>;
17
- }
18
- /**
19
- * Generic API Factory (Hybrid Pattern)
20
- * For simple CRUD operations without business logic
21
- */
22
- declare class APIFactory {
23
- static getAll<T>(Model: Model<T>, options?: ApiFactoryOptions<T>): (req: Request, res: express.Response, next: express.NextFunction) => Promise<void>;
24
- static getOne<T>(Model: Model<T>, options?: ApiFactoryOptions<T>): (req: Request, res: express.Response, next: express.NextFunction) => Promise<void>;
25
- static createOne<T>(Model: Model<T>, options?: ApiFactoryOptions<T>): (req: Request, res: express.Response, next: express.NextFunction) => Promise<void>;
26
- static updateOne<T>(Model: Model<T>, options?: ApiFactoryOptions<T>): (req: Request, res: express.Response, next: express.NextFunction) => Promise<void>;
27
- static deleteOne<T>(Model: Model<T>, options?: ApiFactoryOptions<T>): (req: Request, res: express.Response, next: express.NextFunction) => Promise<void>;
28
- }
29
-
30
- /**
31
- * Generic API Features helper for Mongoose queries
32
- */
33
- declare class APIFeatures<T> {
34
- query: Query<T[], T>;
35
- queryString: Record<string, unknown>;
36
- page: number;
37
- limit: number;
38
- constructor(query: Query<T[], T>, queryString: Record<string, unknown>);
39
- filter(): this;
40
- sort(): this;
41
- limitFields(): this;
42
- paginate(): this;
43
- populate(populateOptions?: PopulateOptions | PopulateOptions[]): this;
44
- }
45
-
46
- declare class APIResponse {
47
- static send(res: Response, options: {
48
- statusCode?: number;
49
- success?: boolean;
50
- message?: string;
51
- data?: unknown;
52
- meta?: Record<string, unknown>;
53
- }): Response<any, Record<string, any>>;
54
- static ok(res: Response, data?: unknown, message?: string, meta?: Record<string, unknown>): Response<any, Record<string, any>>;
55
- static created(res: Response, data?: unknown, message?: string): Response<any, Record<string, any>>;
56
- static noContent(res: Response): Response<any, Record<string, any>>;
57
- static error(res: Response, message?: string, statusCode?: number, meta?: Record<string, unknown>): Response<any, Record<string, any>>;
58
- static paginated(res: Response, data: unknown, options: {
59
- total: number;
60
- page: number;
61
- limit: number;
62
- }, message?: string): Response<any, Record<string, any>>;
63
- }
64
-
65
- declare const asyncHandler: (fn: (req: Request, res: Response, next: NextFunction) => Promise<void>) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
66
-
67
- type FieldTransform<T> = (value: T) => any;
68
- type PickOptions<T extends Record<string, any>, K extends keyof T> = {
69
- removeUndefined?: boolean;
70
- removeNull?: boolean;
71
- removeEmptyString?: boolean;
72
- strict?: boolean;
73
- defaults?: Partial<Record<K, any>>;
74
- rename?: Partial<Record<K, string>>;
75
- transform?: Partial<Record<K, FieldTransform<T[K]>>>;
76
- };
77
- declare function pickFields<T extends Record<string, any>, K extends keyof T>(obj: T, fields: readonly K[], options?: PickOptions<T, K>): Partial<Record<K | string, any>>;
78
-
79
- interface DatabaseConfig {
80
- uri: string;
81
- }
82
- declare function connectMongoDB(config: DatabaseConfig): Promise<void>;
83
-
84
11
  declare function loadEnv<TSchema extends ZodTypeAny, TTransform = undefined>(options: {
85
12
  schema: TSchema;
86
13
  transform?: (env: infer<TSchema>) => TTransform;
@@ -1804,6 +1731,41 @@ declare class SegmentTree<T> {
1804
1731
  private updatePoint;
1805
1732
  }
1806
1733
 
1734
+ interface DatabaseProvider {
1735
+ connect(): Promise<void>;
1736
+ disconnect(): Promise<void>;
1737
+ isConnected(): boolean;
1738
+ getConnectionState(): string;
1739
+ }
1740
+
1741
+ interface DatabaseConnectionOptions {
1742
+ enableShutdownHooks?: boolean;
1743
+ }
1744
+ interface MongoDatabaseConfig {
1745
+ uri: string;
1746
+ strictQuery?: boolean;
1747
+ }
1748
+
1749
+ declare class DatabaseManager {
1750
+ private readonly provider;
1751
+ private readonly options;
1752
+ constructor(provider: DatabaseProvider, options?: DatabaseConnectionOptions);
1753
+ connect(): Promise<void>;
1754
+ disconnect(): Promise<void>;
1755
+ isConnected(): boolean;
1756
+ getConnectionState(): string;
1757
+ private registerShutdownHooks;
1758
+ }
1759
+
1760
+ declare class MongoDatabaseProvider implements DatabaseProvider {
1761
+ private readonly config;
1762
+ constructor(config: MongoDatabaseConfig);
1763
+ connect(): Promise<void>;
1764
+ disconnect(): Promise<void>;
1765
+ isConnected(): boolean;
1766
+ getConnectionState(): string;
1767
+ }
1768
+
1807
1769
  declare class AppError extends Error {
1808
1770
  statusCode: number;
1809
1771
  status: string;
@@ -1816,31 +1778,25 @@ declare class AppError extends Error {
1816
1778
  });
1817
1779
  }
1818
1780
 
1819
- declare const authMiddleware: (_req: Request, _res: Response, next: NextFunction) => void;
1820
-
1821
- declare const GlobalErrorHandler: (isProd?: boolean) => (err: unknown, _req: Request, res: Response, _next: NextFunction) => Response;
1822
-
1823
- declare const validate: (schema: Schema) => (req: Request, _res: Response, next: NextFunction) => void;
1824
-
1825
1781
  type Filter<T> = Partial<Record<keyof T, unknown>>;
1826
1782
  type Field<T> = Extract<keyof T, string>;
1827
1783
  type PrefixedField<T> = `+${Field<T>}` | `-${Field<T>}`;
1828
1784
  type Select<T> = (Field<T> | PrefixedField<T>)[] | Partial<Record<Field<T>, 0 | 1>>;
1829
1785
  type Sort<T> = Partial<Record<keyof T, 1 | -1>>;
1830
1786
 
1831
- interface IQueryOptions<T> {
1787
+ interface QueryOptions<T> {
1832
1788
  select?: Select<T>;
1833
1789
  sort?: Sort<T>;
1834
1790
  limit?: number;
1835
1791
  skip?: number;
1836
1792
  populate?: string | string[];
1837
1793
  }
1838
- interface IUpdateQueryOptions {
1794
+ interface UpdateQueryOptions {
1839
1795
  new?: boolean;
1840
1796
  runValidators: boolean;
1841
1797
  upsert?: boolean;
1842
1798
  }
1843
- interface IRepository<T> {
1799
+ interface Repository<T> {
1844
1800
  /**
1845
1801
  * Create
1846
1802
  */
@@ -1849,17 +1805,17 @@ interface IRepository<T> {
1849
1805
  /**
1850
1806
  * Read
1851
1807
  */
1852
- findAll(filter?: Filter<T>, options?: IQueryOptions<T>): Promise<T[]>;
1853
- findById(id: string, options?: IQueryOptions<T>): Promise<T | null>;
1854
- findOne(filter: Filter<T>, options?: IQueryOptions<T>): Promise<T | null>;
1855
- findManyByIds(ids: string[], options?: IQueryOptions<T>): Promise<T[]>;
1808
+ findAll(filter?: Filter<T>, options?: QueryOptions<T>): Promise<T[]>;
1809
+ findById(id: string, options?: QueryOptions<T>): Promise<T | null>;
1810
+ findOne(filter: Filter<T>, options?: QueryOptions<T>): Promise<T | null>;
1811
+ findManyByIds(ids: string[], options?: QueryOptions<T>): Promise<T[]>;
1856
1812
  count(filter?: Filter<T>): Promise<number>;
1857
1813
  exists(filter?: Filter<T>): Promise<boolean>;
1858
1814
  /**
1859
1815
  * Update
1860
1816
  */
1861
- updateById(id: string, data: Partial<T>, options?: IUpdateQueryOptions): Promise<T | null>;
1862
- updateOne(filter: Filter<T>, data: Partial<T>, options?: IUpdateQueryOptions): Promise<T | null>;
1817
+ updateById(id: string, data: Partial<T>, options?: UpdateQueryOptions): Promise<T | null>;
1818
+ updateOne(filter: Filter<T>, data: Partial<T>, options?: UpdateQueryOptions): Promise<T | null>;
1863
1819
  updateMany(filter: Filter<T>, data: Partial<T>): Promise<number>;
1864
1820
  /**
1865
1821
  * Delete
@@ -1869,12 +1825,182 @@ interface IRepository<T> {
1869
1825
  deleteMany(filter: Filter<T>): Promise<number>;
1870
1826
  }
1871
1827
 
1872
- declare class BaseMongoRepository<T> implements IRepository<T> {
1828
+ interface CrudControllerOptions<T> {
1829
+ resourceName?: string;
1830
+ filter?: (req: Request) => Filter<T>;
1831
+ }
1832
+ declare class CrudControllerFactory {
1833
+ static create<T>(repository: Repository<T>, options?: CrudControllerOptions<T>): {
1834
+ /**
1835
+ * GET /
1836
+ */
1837
+ getAll: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
1838
+ /**
1839
+ * GET /:id
1840
+ */
1841
+ getOne: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
1842
+ /**
1843
+ * POST /
1844
+ */
1845
+ create: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
1846
+ /**
1847
+ * PATCH /:id
1848
+ */
1849
+ update: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
1850
+ /**
1851
+ * DELETE /:id
1852
+ */
1853
+ delete: express.RequestHandler<express_serve_static_core.ParamsDictionary, any, any, qs.ParsedQs, Record<string, any>>;
1854
+ };
1855
+ }
1856
+
1857
+ type AsyncRequestHandler = (req: Request, res: Response, next: NextFunction) => Promise<unknown>;
1858
+ declare const AsyncHandler: (fn: AsyncRequestHandler) => RequestHandler;
1859
+
1860
+ interface AuthenticatedUser {
1861
+ id: string;
1862
+ email?: string;
1863
+ username?: string;
1864
+ roles?: string[];
1865
+ permissions?: string[];
1866
+ }
1867
+ declare global {
1868
+ namespace Express {
1869
+ interface Request {
1870
+ user?: AuthenticatedUser;
1871
+ }
1872
+ }
1873
+ }
1874
+ declare const authMiddleware: (_req: Request, _res: Response, next: NextFunction) => void;
1875
+
1876
+ /**
1877
+ * Global Error Middleware
1878
+ */
1879
+ declare const ErrorMiddleware: (isProduction?: boolean) => (err: unknown, _req: Request, res: Response, _next: NextFunction) => Response<any, Record<string, any>>;
1880
+
1881
+ declare const validate: (schema: unknown) => (req: Request, _res: Response, next: NextFunction) => void;
1882
+
1883
+ type QueryOperator = "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in" | "nin" | "contains" | "startsWith" | "endsWith";
1884
+ interface QueryFilter {
1885
+ field: string;
1886
+ operator: QueryOperator;
1887
+ value: unknown;
1888
+ }
1889
+ interface QuerySort {
1890
+ field: string;
1891
+ direction: "asc" | "desc";
1892
+ }
1893
+ interface PaginationQuery {
1894
+ page: number;
1895
+ limit: number;
1896
+ }
1897
+ interface ParsedQuery {
1898
+ filters: QueryFilter[];
1899
+ sort: QuerySort[];
1900
+ fields: string[];
1901
+ pagination: PaginationQuery;
1902
+ populate: string[];
1903
+ }
1904
+
1905
+ declare class ApiFeatures {
1906
+ static parse(query: Record<string, unknown>): ParsedQuery;
1907
+ private static parseFilters;
1908
+ private static parseSort;
1909
+ private static parseFields;
1910
+ private static parsePopulate;
1911
+ private static parsePagination;
1912
+ }
1913
+
1914
+ declare const QUERY_RESERVED_FIELDS: readonly ["page", "limit", "sort", "fields", "populate"];
1915
+ declare const DEFAULT_PAGE = 1;
1916
+ declare const DEFAULT_LIMIT = 100;
1917
+ declare const DEFAULT_SORT_DIRECTION = "asc";
1918
+ declare const SUPPORTED_OPERATORS: readonly ["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "contains", "startsWith", "endsWith"];
1919
+
1920
+ interface ApiResponseOptions<T = unknown> {
1921
+ statusCode?: number;
1922
+ success?: boolean;
1923
+ message?: string;
1924
+ data?: T;
1925
+ meta?: ApiMeta;
1926
+ }
1927
+ interface ApiMeta {
1928
+ [key: string]: unknown;
1929
+ }
1930
+ interface PaginationMeta extends ApiMeta {
1931
+ total: number;
1932
+ page: number;
1933
+ limit: number;
1934
+ totalPages: number;
1935
+ }
1936
+ interface ErrorMeta {
1937
+ errors?: Record<string, unknown>;
1938
+ }
1939
+ interface StandardApiResponse<T = unknown> {
1940
+ success: boolean;
1941
+ message: string;
1942
+ data?: T;
1943
+ meta?: Record<string, unknown>;
1944
+ }
1945
+
1946
+ declare class ApiResponse {
1947
+ static send<T = unknown>(res: Response, options: ApiResponseOptions<T>): Response<any, Record<string, any>>;
1948
+ static ok<T = unknown>(res: Response, data?: T, message?: string, meta?: ApiMeta): Response<any, Record<string, any>>;
1949
+ static created<T = unknown>(res: Response, data?: T, message?: string): Response<any, Record<string, any>>;
1950
+ static accepted<T = unknown>(res: Response, data?: T, message?: string): Response<any, Record<string, any>>;
1951
+ static noContent(res: Response): Response<any, Record<string, any>>;
1952
+ static error(res: Response, message?: string, statusCode?: number, meta?: ApiMeta): Response<any, Record<string, any>>;
1953
+ static paginated<T = unknown>(res: Response, data: T, options: {
1954
+ total: number;
1955
+ page: number;
1956
+ limit: number;
1957
+ }, message?: string): Response<any, Record<string, any>>;
1958
+ }
1959
+
1960
+ type ValidationSchema = Schema | ZodSchema;
1961
+ interface ValidationResult<T = unknown> {
1962
+ success: boolean;
1963
+ data?: T;
1964
+ errors?: Record<string, unknown>;
1965
+ }
1966
+
1967
+ type FieldTransform<T> = (value: T) => any;
1968
+ type PickOptions<T extends Record<string, any>, K extends keyof T> = {
1969
+ removeUndefined?: boolean;
1970
+ removeNull?: boolean;
1971
+ removeEmptyString?: boolean;
1972
+ strict?: boolean;
1973
+ defaults?: Partial<Record<K, any>>;
1974
+ rename?: Partial<Record<K, string>>;
1975
+ transform?: Partial<Record<K, FieldTransform<T[K]>>>;
1976
+ };
1977
+ declare function pickFields<T extends Record<string, any>, K extends keyof T>(obj: T, fields: readonly K[], options?: PickOptions<T, K>): Partial<Record<K | string, any>>;
1978
+
1979
+ interface IValidator {
1980
+ validate<T = unknown>(data: unknown): ValidationResult<T>;
1981
+ }
1982
+ declare const isJoiSchema: (schema: unknown) => schema is Schema;
1983
+ declare const isZodSchema: (schema: unknown) => schema is ZodSchema;
1984
+
1985
+ declare class JoiValidator implements IValidator {
1986
+ private readonly schema;
1987
+ constructor(schema: Schema);
1988
+ validate<T = unknown>(data: unknown): ValidationResult<T>;
1989
+ }
1990
+
1991
+ declare class ZodValidator implements IValidator {
1992
+ private readonly schema;
1993
+ constructor(schema: ZodSchema);
1994
+ validate<T = unknown>(data: unknown): ValidationResult<T>;
1995
+ }
1996
+
1997
+ declare class MongoRepository<T> implements Repository<T> {
1873
1998
  protected model: Model<T>;
1874
1999
  constructor(model: Model<T>);
1875
2000
  private buildSelect;
1876
2001
  private applyQueryOptions;
1877
2002
  private toPlain;
2003
+ private toPlainArray;
1878
2004
  /**
1879
2005
  * Create
1880
2006
  */
@@ -1883,17 +2009,17 @@ declare class BaseMongoRepository<T> implements IRepository<T> {
1883
2009
  /**
1884
2010
  * Read
1885
2011
  */
1886
- findAll(filter?: Filter<T>, options?: IQueryOptions<T>): Promise<T[]>;
1887
- findById(id: string, options?: IQueryOptions<T>): Promise<T | null>;
1888
- findOne(filter?: Filter<T>, options?: IQueryOptions<T>): Promise<T | null>;
1889
- findManyByIds(ids: string[], options?: IQueryOptions<T>): Promise<T[]>;
2012
+ findAll(filter?: Filter<T>, options?: QueryOptions<T>): Promise<T[]>;
2013
+ findById(id: string, options?: QueryOptions<T>): Promise<T | null>;
2014
+ findOne(filter?: Filter<T>, options?: QueryOptions<T>): Promise<T | null>;
2015
+ findManyByIds(ids: string[], options?: QueryOptions<T>): Promise<T[]>;
1890
2016
  count(filter?: Filter<T>): Promise<number>;
1891
2017
  exists(filter?: Filter<T>): Promise<boolean>;
1892
2018
  /**
1893
2019
  * Update
1894
2020
  */
1895
- updateById(id: string, data: UpdateQuery<T>, options?: IUpdateQueryOptions): Promise<T | null>;
1896
- updateOne(filter: Filter<T>, data: Partial<T>, options?: IUpdateQueryOptions): Promise<T | null>;
2021
+ updateById(id: string, data: UpdateQuery<T>, options?: UpdateQueryOptions): Promise<T | null>;
2022
+ updateOne(filter: Filter<T>, data: Partial<T>, options?: UpdateQueryOptions): Promise<T | null>;
1897
2023
  updateMany(filter: Filter<T>, data: Partial<T>): Promise<number>;
1898
2024
  /**
1899
2025
  * Delete
@@ -2050,4 +2176,4 @@ declare function toMinutes(ms: number): number;
2050
2176
  declare function toHours(ms: number): number;
2051
2177
  declare function sleep(ms: number): Promise<void>;
2052
2178
 
2053
- export { APIFactory, APIFeatures, APIResponse, AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, AppError, type AzureBlobStorageConfig, AzureBlobStorageService, BPlusTree, BTree, BaseMongoRepository, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, type DatabaseConfig, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, type EmailProvider, EmailService, FenwickTree, FibNode, FibonacciHeap, GlobalErrorHandler, Graph, HashMap, HashSet, HyperLogLog, type IQueryOptions, type IRepository, type IUpdateQueryOptions, type Interval, IntervalTree, JWTService, type JWTServiceOptions, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, MulterFileHandlerService, MultiSet, Node, OrderedSet, PairingHeap, PairingNode, type Point, type Point2D, PriorityQueue, type ProgressCallback, QuadTree, Queue, RadixTree, type Rect, RedBlackTree, SMTPProvider, SegmentTree, type SendEmailOptions, Set, SinglyLinkedList, SparseTable, SplayTree, Stack, StaticArray, SuffixArray, SuffixTree, TemplateEngine, TernarySearchTree, TreeNode, Trie, type UploadOptions, asyncHandler, authMiddleware, connectMongoDB, createAllowedOrigins, createCorsOptions, days, errorToString, hours, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };
2179
+ export { AVLTree, AdjacencyList, AdjacencyMatrix, type AdjacentEdge, type AllowedOriginsOptions, ApiFeatures, type ApiMeta, ApiResponse, type ApiResponseOptions, AppError, AsyncHandler, type AsyncRequestHandler, type AuthenticatedUser, type AzureBlobStorageConfig, AzureBlobStorageService, BPlusTree, BTree, BinaryHeap, BinarySearchTree, BinaryTree, BloomFilter, CircularArray, CircularLinkedList, CircularQueue, type CloudinaryConfig, CloudinaryService, ConsistentHash, CountMinSketch, CrudControllerFactory, type CrudControllerOptions, DEFAULT_LIMIT, DEFAULT_PAGE, DEFAULT_SORT_DIRECTION, type DatabaseConnectionOptions, DatabaseManager, type DatabaseProvider, Deque, type DirectedEdge, DirectedGraph, DisjointSetUnion, DoublyLinkedList, DynamicArray, type Edge, type EmailProvider, EmailService, type ErrorMeta, ErrorMiddleware, FenwickTree, FibNode, FibonacciHeap, type Filter, Graph, HashMap, HashSet, HyperLogLog, type IValidator, type Interval, IntervalTree, JWTService, type JWTServiceOptions, JoiValidator, KDTree, LFUCache, LRUCache, type LoggerOptions, MaxHeap, MaxStack, MinHeap, MinStack, type MongoDatabaseConfig, MongoDatabaseProvider, MongoRepository, MulterFileHandlerService, MultiSet, Node, OrderedSet, type PaginationMeta, type PaginationQuery, PairingHeap, PairingNode, type ParsedQuery, type PickOptions, type Point, type Point2D, PriorityQueue, type ProgressCallback, QUERY_RESERVED_FIELDS, QuadTree, type QueryFilter, type QueryOperator, type QueryOptions, type QuerySort, Queue, RadixTree, type Rect, RedBlackTree, type Repository, SMTPProvider, SUPPORTED_OPERATORS, SegmentTree, type Select, type SendEmailOptions, Set, SinglyLinkedList, type Sort, SparseTable, SplayTree, Stack, type StandardApiResponse, StaticArray, SuffixArray, SuffixTree, TemplateEngine, TernarySearchTree, TreeNode, Trie, type UpdateQueryOptions, type UploadOptions, type ValidationResult, type ValidationSchema, ZodValidator, authMiddleware, createAllowedOrigins, createCorsOptions, days, errorToString, hours, isJoiSchema, isZodSchema, loadEnv, logger, milliseconds, minutes, pickFields, seconds, sleep, toHours, toMinutes, toSeconds, validate };