@unchainedshop/utils 4.6.0 → 4.6.2

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.
@@ -0,0 +1,43 @@
1
+ export interface Entity<TId = string> {
2
+ _id: TId;
3
+ }
4
+ export interface IRepository<T extends Entity<TId>, TId = string> {
5
+ findById(id: TId): Promise<T | null>;
6
+ save(aggregate: T): Promise<void>;
7
+ delete(id: TId): Promise<boolean>;
8
+ exists(id: TId): Promise<boolean>;
9
+ }
10
+ export interface IQueryableRepository<T extends Entity<TId>, TId = string, TQuery = Partial<T>> extends IRepository<T, TId> {
11
+ findAll(query?: TQuery): Promise<T[]>;
12
+ findOne(query: TQuery): Promise<T | null>;
13
+ count(query?: TQuery): Promise<number>;
14
+ }
15
+ export interface IPaginatedRepository<T extends Entity<TId>, TId = string, TQuery = Partial<T>> extends IQueryableRepository<T, TId, TQuery> {
16
+ findPaginated(query: TQuery, options: PaginationOptions): Promise<PaginatedResult<T>>;
17
+ }
18
+ export interface PaginationOptions {
19
+ offset?: number;
20
+ limit?: number;
21
+ sortBy?: string;
22
+ sortDirection?: 'asc' | 'desc';
23
+ }
24
+ export interface PaginatedResult<T> {
25
+ items: T[];
26
+ totalCount: number;
27
+ hasMore: boolean;
28
+ offset: number;
29
+ limit: number;
30
+ }
31
+ export interface IReadOnlyRepository<T extends Entity<TId>, TId = string, TQuery = Partial<T>> {
32
+ findById(id: TId): Promise<T | null>;
33
+ findAll(query?: TQuery): Promise<T[]>;
34
+ findOne(query: TQuery): Promise<T | null>;
35
+ count(query?: TQuery): Promise<number>;
36
+ exists(id: TId): Promise<boolean>;
37
+ }
38
+ export interface IUnitOfWork {
39
+ begin(): Promise<void>;
40
+ commit(): Promise<void>;
41
+ rollback(): Promise<void>;
42
+ executeInTransaction<T>(fn: () => Promise<T>): Promise<T>;
43
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export type { Entity, IRepository, IQueryableRepository, IPaginatedRepository, IReadOnlyRepository, IUnitOfWork, PaginationOptions, PaginatedResult, } from './Repository.ts';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ export type Specification<T> = (candidate: T) => boolean;
2
+ export declare function and<T>(...specs: Specification<T>[]): Specification<T>;
3
+ export declare function or<T>(...specs: Specification<T>[]): Specification<T>;
4
+ export declare function not<T>(spec: Specification<T>): Specification<T>;
5
+ export declare function alwaysTrue<T>(): Specification<T>;
6
+ export declare function alwaysFalse<T>(): Specification<T>;
7
+ export declare function propEquals<T, K extends keyof T = keyof T>(propertyName: K, expectedValue: T[K]): Specification<T>;
8
+ export declare function propIn<T, K extends keyof T = keyof T>(propertyName: K, values: T[K][]): Specification<T>;
9
+ export declare function dateRange<T>(propertyName: keyof T, range: {
10
+ start?: Date;
11
+ end?: Date;
12
+ }): Specification<T>;
13
+ export declare function numericRange<T>(propertyName: keyof T, range: {
14
+ min?: number;
15
+ max?: number;
16
+ }): Specification<T>;
17
+ export declare function propTruthy<T>(propertyName: keyof T): Specification<T>;
18
+ export declare function propFalsy<T>(propertyName: keyof T): Specification<T>;
19
+ export declare function propNullish<T>(propertyName: keyof T): Specification<T>;
20
+ export declare function propNotNullish<T>(propertyName: keyof T): Specification<T>;
21
+ export declare function propContains<T, V>(propertyName: keyof T, value: V): Specification<T>;
22
+ export declare function spec<T>(predicate: (candidate: T) => boolean): Specification<T>;
23
+ export declare function filterBy<T>(items: T[], specification: Specification<T>): T[];
24
+ export declare function findBy<T>(items: T[], specification: Specification<T>): T | undefined;
25
+ export declare function countBy<T>(items: T[], specification: Specification<T>): number;
26
+ export declare function someBy<T>(items: T[], specification: Specification<T>): boolean;
27
+ export declare function everyBy<T>(items: T[], specification: Specification<T>): boolean;
@@ -0,0 +1,88 @@
1
+ export function and(...specs) {
2
+ return (candidate) => specs.every((spec) => spec(candidate));
3
+ }
4
+ export function or(...specs) {
5
+ return (candidate) => specs.some((spec) => spec(candidate));
6
+ }
7
+ export function not(spec) {
8
+ return (candidate) => !spec(candidate);
9
+ }
10
+ export function alwaysTrue() {
11
+ return () => true;
12
+ }
13
+ export function alwaysFalse() {
14
+ return () => false;
15
+ }
16
+ export function propEquals(propertyName, expectedValue) {
17
+ return (candidate) => candidate[propertyName] === expectedValue;
18
+ }
19
+ export function propIn(propertyName, values) {
20
+ const valueSet = new Set(values);
21
+ return (candidate) => valueSet.has(candidate[propertyName]);
22
+ }
23
+ export function dateRange(propertyName, range) {
24
+ return (candidate) => {
25
+ const value = candidate[propertyName];
26
+ if (!(value instanceof Date)) {
27
+ return false;
28
+ }
29
+ if (range.start && value < range.start) {
30
+ return false;
31
+ }
32
+ if (range.end && value > range.end) {
33
+ return false;
34
+ }
35
+ return true;
36
+ };
37
+ }
38
+ export function numericRange(propertyName, range) {
39
+ return (candidate) => {
40
+ const value = candidate[propertyName];
41
+ if (typeof value !== 'number') {
42
+ return false;
43
+ }
44
+ if (range.min !== undefined && value < range.min) {
45
+ return false;
46
+ }
47
+ if (range.max !== undefined && value > range.max) {
48
+ return false;
49
+ }
50
+ return true;
51
+ };
52
+ }
53
+ export function propTruthy(propertyName) {
54
+ return (candidate) => Boolean(candidate[propertyName]);
55
+ }
56
+ export function propFalsy(propertyName) {
57
+ return (candidate) => !candidate[propertyName];
58
+ }
59
+ export function propNullish(propertyName) {
60
+ return (candidate) => candidate[propertyName] == null;
61
+ }
62
+ export function propNotNullish(propertyName) {
63
+ return (candidate) => candidate[propertyName] != null;
64
+ }
65
+ export function propContains(propertyName, value) {
66
+ return (candidate) => {
67
+ const arr = candidate[propertyName];
68
+ return Array.isArray(arr) && arr.includes(value);
69
+ };
70
+ }
71
+ export function spec(predicate) {
72
+ return predicate;
73
+ }
74
+ export function filterBy(items, specification) {
75
+ return items.filter(specification);
76
+ }
77
+ export function findBy(items, specification) {
78
+ return items.find(specification);
79
+ }
80
+ export function countBy(items, specification) {
81
+ return items.filter(specification).length;
82
+ }
83
+ export function someBy(items, specification) {
84
+ return items.some(specification);
85
+ }
86
+ export function everyBy(items, specification) {
87
+ return items.every(specification);
88
+ }
@@ -0,0 +1 @@
1
+ export { type Specification, and, or, not, alwaysTrue, alwaysFalse, propEquals, propIn, dateRange, numericRange, propTruthy, propFalsy, propNullish, propNotNullish, propContains, spec, filterBy, findBy, countBy, someBy, everyBy, } from './Specification.ts';
@@ -0,0 +1 @@
1
+ export { and, or, not, alwaysTrue, alwaysFalse, propEquals, propIn, dateRange, numericRange, propTruthy, propFalsy, propNullish, propNotNullish, propContains, spec, filterBy, findBy, countBy, someBy, everyBy, } from "./Specification.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unchainedshop/utils",
3
3
  "description": "Common utility functions and base classes for the Unchained Engine",
4
- "version": "4.6.0",
4
+ "version": "4.6.2",
5
5
  "main": "lib/utils-index.js",
6
6
  "types": "lib/utils-index.d.ts",
7
7
  "type": "module",