@freshpointcz/fresh-core 0.0.16 → 0.0.18
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.mts +98 -5
- package/dist/index.d.ts +98 -5
- package/dist/index.js +160 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +155 -71
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import dayjs, { Dayjs } from 'dayjs';
|
|
2
|
-
import {
|
|
3
|
-
import { BaseEntity, ColumnOptions, Repository, EntityTarget, EntityManager, DataSourceOptions } from 'typeorm';
|
|
2
|
+
import { BaseEntity, ColumnOptions, Repository, EntityTarget, EntityManager, ObjectLiteral, EntitySubscriberInterface, InsertEvent, UpdateEvent, SoftRemoveEvent, TransactionCommitEvent, DataSourceOptions } from 'typeorm';
|
|
4
3
|
import { Job } from 'node-schedule';
|
|
5
4
|
import * as _eslint_core from '@eslint/core';
|
|
6
5
|
import * as typescript_eslint_dist_compatibility_types from 'typescript-eslint/dist/compatibility-types';
|
|
@@ -54,8 +53,6 @@ declare class SinglePromiseWaiter<T = any> {
|
|
|
54
53
|
get hasPromise(): boolean;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
declare const logger: Logger;
|
|
58
|
-
|
|
59
56
|
declare function isValidCron(expr: string): boolean;
|
|
60
57
|
|
|
61
58
|
/**
|
|
@@ -348,6 +345,50 @@ declare abstract class FreshDao<T extends BaseEntity> {
|
|
|
348
345
|
protected getRepo(manager?: EntityManager, entity?: EntityTarget<T>): Repository<T>;
|
|
349
346
|
}
|
|
350
347
|
|
|
348
|
+
/**
|
|
349
|
+
* Change event types for entity lifecycle tracking.
|
|
350
|
+
*/
|
|
351
|
+
type EntityChangeEvent = "created" | "updated" | "deleted";
|
|
352
|
+
/**
|
|
353
|
+
* Abstract base class for TypeORM EntitySubscribers that need to:
|
|
354
|
+
* 1. Track entity changes (insert/update/soft-remove)
|
|
355
|
+
* 2. Batch pending notifications within a transaction
|
|
356
|
+
* 3. Send notifications only after transaction commit
|
|
357
|
+
*
|
|
358
|
+
* Subclasses must implement:
|
|
359
|
+
* - `listenTo()` — target entity class
|
|
360
|
+
* - `pendingKey` — unique key for storing pending events in `queryRunner.data`
|
|
361
|
+
* - `subscriberName` — name used in log messages
|
|
362
|
+
* - `handleNotification(id, changeEvent, manager)` — actual notification logic
|
|
363
|
+
*/
|
|
364
|
+
declare abstract class BaseEntityChangeSubscriber<Entity extends ObjectLiteral, IdType = number> implements EntitySubscriberInterface<Entity> {
|
|
365
|
+
/**
|
|
366
|
+
* Unique key used to store pending change events in `queryRunner.data`.
|
|
367
|
+
* Must be unique per subscriber to avoid collisions when multiple subscribers
|
|
368
|
+
* share the same queryRunner.
|
|
369
|
+
*/
|
|
370
|
+
protected abstract readonly PENDING_KEY: string;
|
|
371
|
+
/**
|
|
372
|
+
* Human-readable name for log/error messages.
|
|
373
|
+
*/
|
|
374
|
+
protected abstract readonly SUBSCRIBER_NAME: string;
|
|
375
|
+
/**
|
|
376
|
+
* Return the entity class this subscriber listens to.
|
|
377
|
+
*/
|
|
378
|
+
abstract listenTo(): Function;
|
|
379
|
+
/**
|
|
380
|
+
* Implement the actual notification/side-effect logic.
|
|
381
|
+
* Called after transaction commit (or immediately if no transaction is active).
|
|
382
|
+
*/
|
|
383
|
+
protected abstract handleNotification(id: IdType, changeEvent: EntityChangeEvent, manager: EntityManager): Promise<void>;
|
|
384
|
+
afterInsert(event: InsertEvent<Entity>): void;
|
|
385
|
+
afterUpdate(event: UpdateEvent<Entity>): void;
|
|
386
|
+
afterSoftRemove(event: SoftRemoveEvent<Entity>): void;
|
|
387
|
+
afterTransactionCommit(event: TransactionCommitEvent): Promise<void>;
|
|
388
|
+
private addPending;
|
|
389
|
+
private sendNotification;
|
|
390
|
+
}
|
|
391
|
+
|
|
351
392
|
declare class Category extends FreshEntity {
|
|
352
393
|
}
|
|
353
394
|
|
|
@@ -433,6 +474,46 @@ declare function isNumberInRange(v: unknown, min: number, max: number, options?:
|
|
|
433
474
|
includeMin?: boolean;
|
|
434
475
|
includeMax?: boolean;
|
|
435
476
|
}): v is number;
|
|
477
|
+
/**
|
|
478
|
+
* Numeric boolean flag type — either 0 or 1
|
|
479
|
+
*/
|
|
480
|
+
type BinaryFlag = 0 | 1;
|
|
481
|
+
/**
|
|
482
|
+
* Converts a number, boolean, null, or undefined to a BinaryFlag (0 or 1)
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* TO_BINARY_FLAG(true) // 1
|
|
486
|
+
* TO_BINARY_FLAG(1) // 1
|
|
487
|
+
* TO_BINARY_FLAG(false) // 0
|
|
488
|
+
* TO_BINARY_FLAG(null) // 0
|
|
489
|
+
*/
|
|
490
|
+
declare const TO_BINARY_FLAG: (v: number | boolean | null | undefined) => BinaryFlag;
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Runs async worker functions over items with a concurrency limit.
|
|
494
|
+
*
|
|
495
|
+
* @param items - Array of items to process
|
|
496
|
+
* @param concurrency - Maximum number of concurrent workers
|
|
497
|
+
* @param worker - Async function to run for each item
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* await runWithConcurrency(productIds, 5, async (id) => {
|
|
501
|
+
* await processProduct(id);
|
|
502
|
+
* });
|
|
503
|
+
*/
|
|
504
|
+
declare function runWithConcurrency<T>(items: T[], concurrency: number, worker: (item: T) => Promise<void>): Promise<void>;
|
|
505
|
+
|
|
506
|
+
type TransformMap<TIn, TOut, K extends keyof TIn & keyof TOut> = Partial<{
|
|
507
|
+
[P in K]: (val: TIn[P]) => TOut[P];
|
|
508
|
+
}>;
|
|
509
|
+
/**
|
|
510
|
+
* Builds a partial patch object from an input DTO, only including keys that are defined.
|
|
511
|
+
* Optionally applies transform functions to specific keys.
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* const patch = buildPatch(data, ["name", "active"], { active: (v) => v ? 1 : 0 });
|
|
515
|
+
*/
|
|
516
|
+
declare function buildPatch<TOut extends Record<string, any>, TIn extends Record<string, any>, K extends keyof TIn & keyof TOut = keyof TIn & keyof TOut>(data: Partial<TIn>, keys: readonly K[], transforms?: TransformMap<TIn, TOut, K>): Partial<Pick<TOut, K>>;
|
|
436
517
|
|
|
437
518
|
type Maybe<T> = T | null;
|
|
438
519
|
/**
|
|
@@ -564,6 +645,18 @@ declare class ApiError extends Error {
|
|
|
564
645
|
constructor(statusCode: number, status: Status, detail?: string);
|
|
565
646
|
}
|
|
566
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Represents a non-fatal business rule violation that should be
|
|
650
|
+
* communicated to the caller without being treated as a system error.
|
|
651
|
+
*
|
|
652
|
+
* @example
|
|
653
|
+
* throw new BusinessWarning("ORDER_ALREADY_SENT", "Tato objednávka již byla odeslána.");
|
|
654
|
+
*/
|
|
655
|
+
declare class BusinessWarning extends Error {
|
|
656
|
+
readonly code: string;
|
|
657
|
+
constructor(code: string, message: string);
|
|
658
|
+
}
|
|
659
|
+
|
|
567
660
|
declare const FRESH_ESLINT_CONFIG: {
|
|
568
661
|
files: string[];
|
|
569
662
|
ignores: string[];
|
|
@@ -641,4 +734,4 @@ interface HealthCheckResult {
|
|
|
641
734
|
};
|
|
642
735
|
}
|
|
643
736
|
|
|
644
|
-
export { AMOUNT_UNIT, ActionCommandCode, ApiError, type CardNumber, Category, DataHelper, DateUtils, type Deferred, DepotPoolStatus, Device, FreshDao, FreshEntity, FreshHyperEntity, FreshJob, FreshTranslationBase, type HealthCheckResult, HttpStatus, LanguageCode, Manufacturer, type Maybe, PaymentMethod, PG_DATA_SOURCE_OPTIONS as PgDataSourceOptions, Product, SinglePromiseWaiter, Singleton, type Status, StatusDto, Subcategory, TimestampColumn, TransactionType, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron,
|
|
737
|
+
export { AMOUNT_UNIT, ActionCommandCode, ApiError, BaseEntityChangeSubscriber, type BinaryFlag, BusinessWarning, type CardNumber, Category, DataHelper, DateUtils, type Deferred, DepotPoolStatus, Device, type EntityChangeEvent, FreshDao, FreshEntity, FreshHyperEntity, FreshJob, FreshTranslationBase, type HealthCheckResult, HttpStatus, LanguageCode, Manufacturer, type Maybe, PaymentMethod, PG_DATA_SOURCE_OPTIONS as PgDataSourceOptions, Product, SinglePromiseWaiter, Singleton, type Status, StatusDto, Subcategory, TO_BINARY_FLAG, TimestampColumn, TransactionType, buildPatch, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron, runWithConcurrency };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import dayjs, { Dayjs } from 'dayjs';
|
|
2
|
-
import {
|
|
3
|
-
import { BaseEntity, ColumnOptions, Repository, EntityTarget, EntityManager, DataSourceOptions } from 'typeorm';
|
|
2
|
+
import { BaseEntity, ColumnOptions, Repository, EntityTarget, EntityManager, ObjectLiteral, EntitySubscriberInterface, InsertEvent, UpdateEvent, SoftRemoveEvent, TransactionCommitEvent, DataSourceOptions } from 'typeorm';
|
|
4
3
|
import { Job } from 'node-schedule';
|
|
5
4
|
import * as _eslint_core from '@eslint/core';
|
|
6
5
|
import * as typescript_eslint_dist_compatibility_types from 'typescript-eslint/dist/compatibility-types';
|
|
@@ -54,8 +53,6 @@ declare class SinglePromiseWaiter<T = any> {
|
|
|
54
53
|
get hasPromise(): boolean;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
declare const logger: Logger;
|
|
58
|
-
|
|
59
56
|
declare function isValidCron(expr: string): boolean;
|
|
60
57
|
|
|
61
58
|
/**
|
|
@@ -348,6 +345,50 @@ declare abstract class FreshDao<T extends BaseEntity> {
|
|
|
348
345
|
protected getRepo(manager?: EntityManager, entity?: EntityTarget<T>): Repository<T>;
|
|
349
346
|
}
|
|
350
347
|
|
|
348
|
+
/**
|
|
349
|
+
* Change event types for entity lifecycle tracking.
|
|
350
|
+
*/
|
|
351
|
+
type EntityChangeEvent = "created" | "updated" | "deleted";
|
|
352
|
+
/**
|
|
353
|
+
* Abstract base class for TypeORM EntitySubscribers that need to:
|
|
354
|
+
* 1. Track entity changes (insert/update/soft-remove)
|
|
355
|
+
* 2. Batch pending notifications within a transaction
|
|
356
|
+
* 3. Send notifications only after transaction commit
|
|
357
|
+
*
|
|
358
|
+
* Subclasses must implement:
|
|
359
|
+
* - `listenTo()` — target entity class
|
|
360
|
+
* - `pendingKey` — unique key for storing pending events in `queryRunner.data`
|
|
361
|
+
* - `subscriberName` — name used in log messages
|
|
362
|
+
* - `handleNotification(id, changeEvent, manager)` — actual notification logic
|
|
363
|
+
*/
|
|
364
|
+
declare abstract class BaseEntityChangeSubscriber<Entity extends ObjectLiteral, IdType = number> implements EntitySubscriberInterface<Entity> {
|
|
365
|
+
/**
|
|
366
|
+
* Unique key used to store pending change events in `queryRunner.data`.
|
|
367
|
+
* Must be unique per subscriber to avoid collisions when multiple subscribers
|
|
368
|
+
* share the same queryRunner.
|
|
369
|
+
*/
|
|
370
|
+
protected abstract readonly PENDING_KEY: string;
|
|
371
|
+
/**
|
|
372
|
+
* Human-readable name for log/error messages.
|
|
373
|
+
*/
|
|
374
|
+
protected abstract readonly SUBSCRIBER_NAME: string;
|
|
375
|
+
/**
|
|
376
|
+
* Return the entity class this subscriber listens to.
|
|
377
|
+
*/
|
|
378
|
+
abstract listenTo(): Function;
|
|
379
|
+
/**
|
|
380
|
+
* Implement the actual notification/side-effect logic.
|
|
381
|
+
* Called after transaction commit (or immediately if no transaction is active).
|
|
382
|
+
*/
|
|
383
|
+
protected abstract handleNotification(id: IdType, changeEvent: EntityChangeEvent, manager: EntityManager): Promise<void>;
|
|
384
|
+
afterInsert(event: InsertEvent<Entity>): void;
|
|
385
|
+
afterUpdate(event: UpdateEvent<Entity>): void;
|
|
386
|
+
afterSoftRemove(event: SoftRemoveEvent<Entity>): void;
|
|
387
|
+
afterTransactionCommit(event: TransactionCommitEvent): Promise<void>;
|
|
388
|
+
private addPending;
|
|
389
|
+
private sendNotification;
|
|
390
|
+
}
|
|
391
|
+
|
|
351
392
|
declare class Category extends FreshEntity {
|
|
352
393
|
}
|
|
353
394
|
|
|
@@ -433,6 +474,46 @@ declare function isNumberInRange(v: unknown, min: number, max: number, options?:
|
|
|
433
474
|
includeMin?: boolean;
|
|
434
475
|
includeMax?: boolean;
|
|
435
476
|
}): v is number;
|
|
477
|
+
/**
|
|
478
|
+
* Numeric boolean flag type — either 0 or 1
|
|
479
|
+
*/
|
|
480
|
+
type BinaryFlag = 0 | 1;
|
|
481
|
+
/**
|
|
482
|
+
* Converts a number, boolean, null, or undefined to a BinaryFlag (0 or 1)
|
|
483
|
+
*
|
|
484
|
+
* @example
|
|
485
|
+
* TO_BINARY_FLAG(true) // 1
|
|
486
|
+
* TO_BINARY_FLAG(1) // 1
|
|
487
|
+
* TO_BINARY_FLAG(false) // 0
|
|
488
|
+
* TO_BINARY_FLAG(null) // 0
|
|
489
|
+
*/
|
|
490
|
+
declare const TO_BINARY_FLAG: (v: number | boolean | null | undefined) => BinaryFlag;
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Runs async worker functions over items with a concurrency limit.
|
|
494
|
+
*
|
|
495
|
+
* @param items - Array of items to process
|
|
496
|
+
* @param concurrency - Maximum number of concurrent workers
|
|
497
|
+
* @param worker - Async function to run for each item
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* await runWithConcurrency(productIds, 5, async (id) => {
|
|
501
|
+
* await processProduct(id);
|
|
502
|
+
* });
|
|
503
|
+
*/
|
|
504
|
+
declare function runWithConcurrency<T>(items: T[], concurrency: number, worker: (item: T) => Promise<void>): Promise<void>;
|
|
505
|
+
|
|
506
|
+
type TransformMap<TIn, TOut, K extends keyof TIn & keyof TOut> = Partial<{
|
|
507
|
+
[P in K]: (val: TIn[P]) => TOut[P];
|
|
508
|
+
}>;
|
|
509
|
+
/**
|
|
510
|
+
* Builds a partial patch object from an input DTO, only including keys that are defined.
|
|
511
|
+
* Optionally applies transform functions to specific keys.
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* const patch = buildPatch(data, ["name", "active"], { active: (v) => v ? 1 : 0 });
|
|
515
|
+
*/
|
|
516
|
+
declare function buildPatch<TOut extends Record<string, any>, TIn extends Record<string, any>, K extends keyof TIn & keyof TOut = keyof TIn & keyof TOut>(data: Partial<TIn>, keys: readonly K[], transforms?: TransformMap<TIn, TOut, K>): Partial<Pick<TOut, K>>;
|
|
436
517
|
|
|
437
518
|
type Maybe<T> = T | null;
|
|
438
519
|
/**
|
|
@@ -564,6 +645,18 @@ declare class ApiError extends Error {
|
|
|
564
645
|
constructor(statusCode: number, status: Status, detail?: string);
|
|
565
646
|
}
|
|
566
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Represents a non-fatal business rule violation that should be
|
|
650
|
+
* communicated to the caller without being treated as a system error.
|
|
651
|
+
*
|
|
652
|
+
* @example
|
|
653
|
+
* throw new BusinessWarning("ORDER_ALREADY_SENT", "Tato objednávka již byla odeslána.");
|
|
654
|
+
*/
|
|
655
|
+
declare class BusinessWarning extends Error {
|
|
656
|
+
readonly code: string;
|
|
657
|
+
constructor(code: string, message: string);
|
|
658
|
+
}
|
|
659
|
+
|
|
567
660
|
declare const FRESH_ESLINT_CONFIG: {
|
|
568
661
|
files: string[];
|
|
569
662
|
ignores: string[];
|
|
@@ -641,4 +734,4 @@ interface HealthCheckResult {
|
|
|
641
734
|
};
|
|
642
735
|
}
|
|
643
736
|
|
|
644
|
-
export { AMOUNT_UNIT, ActionCommandCode, ApiError, type CardNumber, Category, DataHelper, DateUtils, type Deferred, DepotPoolStatus, Device, FreshDao, FreshEntity, FreshHyperEntity, FreshJob, FreshTranslationBase, type HealthCheckResult, HttpStatus, LanguageCode, Manufacturer, type Maybe, PaymentMethod, PG_DATA_SOURCE_OPTIONS as PgDataSourceOptions, Product, SinglePromiseWaiter, Singleton, type Status, StatusDto, Subcategory, TimestampColumn, TransactionType, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron,
|
|
737
|
+
export { AMOUNT_UNIT, ActionCommandCode, ApiError, BaseEntityChangeSubscriber, type BinaryFlag, BusinessWarning, type CardNumber, Category, DataHelper, DateUtils, type Deferred, DepotPoolStatus, Device, type EntityChangeEvent, FreshDao, FreshEntity, FreshHyperEntity, FreshJob, FreshTranslationBase, type HealthCheckResult, HttpStatus, LanguageCode, Manufacturer, type Maybe, PaymentMethod, PG_DATA_SOURCE_OPTIONS as PgDataSourceOptions, Product, SinglePromiseWaiter, Singleton, type Status, StatusDto, Subcategory, TO_BINARY_FLAG, TimestampColumn, TransactionType, buildPatch, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron, runWithConcurrency };
|
package/dist/index.js
CHANGED
|
@@ -108,7 +108,7 @@ var require_main = __commonJS({
|
|
|
108
108
|
var fs = require("fs");
|
|
109
109
|
var path2 = require("path");
|
|
110
110
|
var os = require("os");
|
|
111
|
-
var
|
|
111
|
+
var crypto = require("crypto");
|
|
112
112
|
var packageJson = require_package();
|
|
113
113
|
var version = packageJson.version;
|
|
114
114
|
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
@@ -355,7 +355,7 @@ var require_main = __commonJS({
|
|
|
355
355
|
const authTag = ciphertext.subarray(-16);
|
|
356
356
|
ciphertext = ciphertext.subarray(12, -16);
|
|
357
357
|
try {
|
|
358
|
-
const aesgcm =
|
|
358
|
+
const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
359
359
|
aesgcm.setAuthTag(authTag);
|
|
360
360
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
361
361
|
} catch (error) {
|
|
@@ -428,6 +428,8 @@ __export(index_exports, {
|
|
|
428
428
|
AMOUNT_UNIT: () => AMOUNT_UNIT,
|
|
429
429
|
ActionCommandCode: () => ActionCommandCode,
|
|
430
430
|
ApiError: () => ApiError,
|
|
431
|
+
BaseEntityChangeSubscriber: () => BaseEntityChangeSubscriber,
|
|
432
|
+
BusinessWarning: () => BusinessWarning,
|
|
431
433
|
Category: () => Category,
|
|
432
434
|
DataHelper: () => DataHelper,
|
|
433
435
|
DateUtils: () => DateUtils,
|
|
@@ -448,8 +450,10 @@ __export(index_exports, {
|
|
|
448
450
|
Singleton: () => Singleton,
|
|
449
451
|
StatusDto: () => StatusDto,
|
|
450
452
|
Subcategory: () => Subcategory,
|
|
453
|
+
TO_BINARY_FLAG: () => TO_BINARY_FLAG,
|
|
451
454
|
TimestampColumn: () => TimestampColumn,
|
|
452
455
|
TransactionType: () => TransactionType,
|
|
456
|
+
buildPatch: () => buildPatch,
|
|
453
457
|
createDeferred: () => createDeferred,
|
|
454
458
|
freshEslintConfig: () => eslint_config_default,
|
|
455
459
|
hasOwn: () => hasOwn,
|
|
@@ -461,7 +465,7 @@ __export(index_exports, {
|
|
|
461
465
|
isObject: () => isObject,
|
|
462
466
|
isString: () => isString,
|
|
463
467
|
isValidCron: () => isValidCron,
|
|
464
|
-
|
|
468
|
+
runWithConcurrency: () => runWithConcurrency
|
|
465
469
|
});
|
|
466
470
|
module.exports = __toCommonJS(index_exports);
|
|
467
471
|
|
|
@@ -691,56 +695,6 @@ __name(_SinglePromiseWaiter, "SinglePromiseWaiter");
|
|
|
691
695
|
__publicField(_SinglePromiseWaiter, "_instance");
|
|
692
696
|
var SinglePromiseWaiter = _SinglePromiseWaiter;
|
|
693
697
|
|
|
694
|
-
// src/common/winston.ts
|
|
695
|
-
var import_winston = __toESM(require("winston"));
|
|
696
|
-
var SERVICE = process.env.SERVICE_NAME || "depot-ordering-service";
|
|
697
|
-
var ENV = process.env.NODE_ENV || "localhost";
|
|
698
|
-
var levelToSeverity = {
|
|
699
|
-
silly: "debug",
|
|
700
|
-
verbose: "debug",
|
|
701
|
-
debug: "debug",
|
|
702
|
-
http: "info",
|
|
703
|
-
info: "info",
|
|
704
|
-
warn: "warn",
|
|
705
|
-
error: "error"
|
|
706
|
-
};
|
|
707
|
-
var baseFormat = import_winston.default.format.combine(import_winston.default.format.timestamp({
|
|
708
|
-
format: /* @__PURE__ */ __name(() => (/* @__PURE__ */ new Date()).toISOString(), "format")
|
|
709
|
-
}), import_winston.default.format.errors({
|
|
710
|
-
stack: true
|
|
711
|
-
}), import_winston.default.format.printf((info) => {
|
|
712
|
-
const payload = {
|
|
713
|
-
ts: info.timestamp,
|
|
714
|
-
level: info.level,
|
|
715
|
-
severity: levelToSeverity[info.level] || info.level,
|
|
716
|
-
message: info.message,
|
|
717
|
-
service: SERVICE,
|
|
718
|
-
env: ENV,
|
|
719
|
-
process_name: process.title || process.argv[1] || "node",
|
|
720
|
-
pid: process.pid,
|
|
721
|
-
device: process.env.DEVICE_ID || void 0,
|
|
722
|
-
traceId: info.traceId,
|
|
723
|
-
spanId: info.spanId,
|
|
724
|
-
extra: info.extra || info.meta || void 0,
|
|
725
|
-
stack: info.stack
|
|
726
|
-
};
|
|
727
|
-
return JSON.stringify(payload);
|
|
728
|
-
}));
|
|
729
|
-
var transports = [
|
|
730
|
-
new import_winston.default.transports.Console({
|
|
731
|
-
level: process.env.LOG_LEVEL || "info"
|
|
732
|
-
})
|
|
733
|
-
];
|
|
734
|
-
var logger = import_winston.default.createLogger({
|
|
735
|
-
level: process.env.LOG_LEVEL || "info",
|
|
736
|
-
format: baseFormat,
|
|
737
|
-
transports,
|
|
738
|
-
exitOnError: false
|
|
739
|
-
});
|
|
740
|
-
logger.stream = {
|
|
741
|
-
write: /* @__PURE__ */ __name((message) => logger.info(message.trim()), "write")
|
|
742
|
-
};
|
|
743
|
-
|
|
744
698
|
// src/common/utils/is-cron-valid.ts
|
|
745
699
|
function isValidCron(expr) {
|
|
746
700
|
const parts = expr.trim().split(/\s+/);
|
|
@@ -865,46 +819,53 @@ var import_typeorm5 = require("typeorm");
|
|
|
865
819
|
// src/database/entities/fresh-entity.ts
|
|
866
820
|
var import_typeorm = require("typeorm");
|
|
867
821
|
|
|
868
|
-
// ../../node_modules/uuid/dist/esm
|
|
869
|
-
var
|
|
822
|
+
// ../../node_modules/uuid/dist/esm/stringify.js
|
|
823
|
+
var byteToHex = [];
|
|
824
|
+
for (let i = 0; i < 256; ++i) {
|
|
825
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
826
|
+
}
|
|
827
|
+
function unsafeStringify(arr, offset = 0) {
|
|
828
|
+
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
829
|
+
}
|
|
830
|
+
__name(unsafeStringify, "unsafeStringify");
|
|
831
|
+
|
|
832
|
+
// ../../node_modules/uuid/dist/esm/rng.js
|
|
833
|
+
var import_crypto = require("crypto");
|
|
870
834
|
var rnds8Pool = new Uint8Array(256);
|
|
871
835
|
var poolPtr = rnds8Pool.length;
|
|
872
836
|
function rng() {
|
|
873
837
|
if (poolPtr > rnds8Pool.length - 16) {
|
|
874
|
-
import_crypto.
|
|
838
|
+
(0, import_crypto.randomFillSync)(rnds8Pool);
|
|
875
839
|
poolPtr = 0;
|
|
876
840
|
}
|
|
877
841
|
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
878
842
|
}
|
|
879
843
|
__name(rng, "rng");
|
|
880
844
|
|
|
881
|
-
// ../../node_modules/uuid/dist/esm
|
|
882
|
-
var
|
|
883
|
-
for (let i = 0; i < 256; ++i) {
|
|
884
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
885
|
-
}
|
|
886
|
-
function unsafeStringify(arr, offset = 0) {
|
|
887
|
-
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
888
|
-
}
|
|
889
|
-
__name(unsafeStringify, "unsafeStringify");
|
|
890
|
-
|
|
891
|
-
// ../../node_modules/uuid/dist/esm-node/native.js
|
|
892
|
-
var import_crypto2 = __toESM(require("crypto"));
|
|
845
|
+
// ../../node_modules/uuid/dist/esm/native.js
|
|
846
|
+
var import_crypto2 = require("crypto");
|
|
893
847
|
var native_default = {
|
|
894
|
-
randomUUID: import_crypto2.
|
|
848
|
+
randomUUID: import_crypto2.randomUUID
|
|
895
849
|
};
|
|
896
850
|
|
|
897
|
-
// ../../node_modules/uuid/dist/esm
|
|
851
|
+
// ../../node_modules/uuid/dist/esm/v4.js
|
|
898
852
|
function v4(options, buf, offset) {
|
|
853
|
+
var _a, _b, _c;
|
|
899
854
|
if (native_default.randomUUID && !buf && !options) {
|
|
900
855
|
return native_default.randomUUID();
|
|
901
856
|
}
|
|
902
857
|
options = options || {};
|
|
903
|
-
const rnds = options.random
|
|
858
|
+
const rnds = (_c = (_b = options.random) != null ? _b : (_a = options.rng) == null ? void 0 : _a.call(options)) != null ? _c : rng();
|
|
859
|
+
if (rnds.length < 16) {
|
|
860
|
+
throw new Error("Random bytes length must be >= 16");
|
|
861
|
+
}
|
|
904
862
|
rnds[6] = rnds[6] & 15 | 64;
|
|
905
863
|
rnds[8] = rnds[8] & 63 | 128;
|
|
906
864
|
if (buf) {
|
|
907
865
|
offset = offset || 0;
|
|
866
|
+
if (offset < 0 || offset + 16 > buf.length) {
|
|
867
|
+
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
|
868
|
+
}
|
|
908
869
|
for (let i = 0; i < 16; ++i) {
|
|
909
870
|
buf[offset + i] = rnds[i];
|
|
910
871
|
}
|
|
@@ -1207,6 +1168,83 @@ var _FreshDao = class _FreshDao {
|
|
|
1207
1168
|
__name(_FreshDao, "FreshDao");
|
|
1208
1169
|
var FreshDao = _FreshDao;
|
|
1209
1170
|
|
|
1171
|
+
// src/database/subscribers/base-entity-change.subscriber.ts
|
|
1172
|
+
var _BaseEntityChangeSubscriber = class _BaseEntityChangeSubscriber {
|
|
1173
|
+
// ─── TypeORM lifecycle hooks ────────────────────────────────────────
|
|
1174
|
+
afterInsert(event) {
|
|
1175
|
+
var _a;
|
|
1176
|
+
const id = (_a = event.entity) == null ? void 0 : _a.id;
|
|
1177
|
+
if (!id) {
|
|
1178
|
+
return;
|
|
1179
|
+
}
|
|
1180
|
+
if (event.queryRunner.isTransactionActive) {
|
|
1181
|
+
this.addPending(event, id, "created");
|
|
1182
|
+
} else {
|
|
1183
|
+
console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
|
|
1184
|
+
this.sendNotification(id, "created", event.queryRunner.manager);
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
afterUpdate(event) {
|
|
1188
|
+
var _a, _b, _c;
|
|
1189
|
+
const id = (_c = (_a = event.entity) == null ? void 0 : _a.id) != null ? _c : (_b = event.databaseEntity) == null ? void 0 : _b.id;
|
|
1190
|
+
if (!id) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
if (event.queryRunner.isTransactionActive) {
|
|
1194
|
+
this.addPending(event, id, "updated");
|
|
1195
|
+
} else {
|
|
1196
|
+
console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
|
|
1197
|
+
this.sendNotification(id, "updated", event.queryRunner.manager);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
afterSoftRemove(event) {
|
|
1201
|
+
var _a, _b, _c;
|
|
1202
|
+
const id = (_c = (_a = event.entity) == null ? void 0 : _a.id) != null ? _c : (_b = event.databaseEntity) == null ? void 0 : _b.id;
|
|
1203
|
+
if (!id) {
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
if (event.queryRunner.isTransactionActive) {
|
|
1207
|
+
this.addPending(event, id, "deleted");
|
|
1208
|
+
} else {
|
|
1209
|
+
console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
|
|
1210
|
+
this.sendNotification(id, "deleted", event.queryRunner.manager);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
async afterTransactionCommit(event) {
|
|
1214
|
+
var _a;
|
|
1215
|
+
const pending = (_a = event.queryRunner.data) == null ? void 0 : _a[this.PENDING_KEY];
|
|
1216
|
+
if (!pending || pending.size === 0) {
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
event.queryRunner.data[this.PENDING_KEY] = /* @__PURE__ */ new Map();
|
|
1220
|
+
for (const [id, changeEvent] of pending) {
|
|
1221
|
+
await this.sendNotification(id, changeEvent, event.connection.manager);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
// ─── Private helpers ───────────────────────────────────────────────
|
|
1225
|
+
addPending(event, id, changeEvent) {
|
|
1226
|
+
if (!event.queryRunner.data) {
|
|
1227
|
+
event.queryRunner.data = {};
|
|
1228
|
+
}
|
|
1229
|
+
if (!event.queryRunner.data[this.PENDING_KEY]) {
|
|
1230
|
+
event.queryRunner.data[this.PENDING_KEY] = /* @__PURE__ */ new Map();
|
|
1231
|
+
}
|
|
1232
|
+
const existing = event.queryRunner.data[this.PENDING_KEY].get(id);
|
|
1233
|
+
if (!existing || changeEvent === "created" || changeEvent === "deleted") {
|
|
1234
|
+
event.queryRunner.data[this.PENDING_KEY].set(id, changeEvent);
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
async sendNotification(id, changeEvent, manager) {
|
|
1238
|
+
try {
|
|
1239
|
+
await this.handleNotification(id, changeEvent, manager);
|
|
1240
|
+
} catch (error) {
|
|
1241
|
+
console.error(`${this.SUBSCRIBER_NAME} - Failed to send notification: ${error instanceof Error ? error.message : error}`);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
};
|
|
1245
|
+
__name(_BaseEntityChangeSubscriber, "BaseEntityChangeSubscriber");
|
|
1246
|
+
var BaseEntityChangeSubscriber = _BaseEntityChangeSubscriber;
|
|
1247
|
+
|
|
1210
1248
|
// src/common/schema/entities/category.entity.ts
|
|
1211
1249
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
1212
1250
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -1340,6 +1378,40 @@ function isNumberInRange(v, min, max, options) {
|
|
|
1340
1378
|
return true;
|
|
1341
1379
|
}
|
|
1342
1380
|
__name(isNumberInRange, "isNumberInRange");
|
|
1381
|
+
var TO_BINARY_FLAG = /* @__PURE__ */ __name((v) => v === 1 || v === true ? 1 : 0, "TO_BINARY_FLAG");
|
|
1382
|
+
|
|
1383
|
+
// src/common/utils/async.utils.ts
|
|
1384
|
+
async function runWithConcurrency(items, concurrency, worker) {
|
|
1385
|
+
const queue = [
|
|
1386
|
+
...items
|
|
1387
|
+
];
|
|
1388
|
+
const runNext = /* @__PURE__ */ __name(async () => {
|
|
1389
|
+
const item = queue.shift();
|
|
1390
|
+
if (!item) {
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
await worker(item);
|
|
1394
|
+
await runNext();
|
|
1395
|
+
}, "runNext");
|
|
1396
|
+
await Promise.all(Array.from({
|
|
1397
|
+
length: Math.min(concurrency, items.length)
|
|
1398
|
+
}, runNext));
|
|
1399
|
+
}
|
|
1400
|
+
__name(runWithConcurrency, "runWithConcurrency");
|
|
1401
|
+
|
|
1402
|
+
// src/common/utils/patch.utils.ts
|
|
1403
|
+
function buildPatch(data, keys, transforms) {
|
|
1404
|
+
const patch = {};
|
|
1405
|
+
for (const k of keys) {
|
|
1406
|
+
const value = data[k];
|
|
1407
|
+
if (value === void 0) {
|
|
1408
|
+
continue;
|
|
1409
|
+
}
|
|
1410
|
+
patch[k] = (transforms == null ? void 0 : transforms[k]) ? transforms[k](value) : value;
|
|
1411
|
+
}
|
|
1412
|
+
return patch;
|
|
1413
|
+
}
|
|
1414
|
+
__name(buildPatch, "buildPatch");
|
|
1343
1415
|
|
|
1344
1416
|
// src/core/data-helper.ts
|
|
1345
1417
|
var _DataHelper = class _DataHelper {
|
|
@@ -1514,6 +1586,18 @@ var _ApiError = class _ApiError extends Error {
|
|
|
1514
1586
|
__name(_ApiError, "ApiError");
|
|
1515
1587
|
var ApiError = _ApiError;
|
|
1516
1588
|
|
|
1589
|
+
// src/core/errors/business-warning.ts
|
|
1590
|
+
var _BusinessWarning = class _BusinessWarning extends Error {
|
|
1591
|
+
constructor(code, message) {
|
|
1592
|
+
super(message);
|
|
1593
|
+
__publicField(this, "code");
|
|
1594
|
+
this.code = code;
|
|
1595
|
+
this.name = "BusinessWarning";
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
__name(_BusinessWarning, "BusinessWarning");
|
|
1599
|
+
var BusinessWarning = _BusinessWarning;
|
|
1600
|
+
|
|
1517
1601
|
// src/types/maybe-type.ts
|
|
1518
1602
|
function isMaybe(v, inner) {
|
|
1519
1603
|
return v === null || inner(v);
|
|
@@ -1707,6 +1791,8 @@ var datasource_default = PG_DATA_SOURCE_OPTIONS;
|
|
|
1707
1791
|
AMOUNT_UNIT,
|
|
1708
1792
|
ActionCommandCode,
|
|
1709
1793
|
ApiError,
|
|
1794
|
+
BaseEntityChangeSubscriber,
|
|
1795
|
+
BusinessWarning,
|
|
1710
1796
|
Category,
|
|
1711
1797
|
DataHelper,
|
|
1712
1798
|
DateUtils,
|
|
@@ -1727,8 +1813,10 @@ var datasource_default = PG_DATA_SOURCE_OPTIONS;
|
|
|
1727
1813
|
Singleton,
|
|
1728
1814
|
StatusDto,
|
|
1729
1815
|
Subcategory,
|
|
1816
|
+
TO_BINARY_FLAG,
|
|
1730
1817
|
TimestampColumn,
|
|
1731
1818
|
TransactionType,
|
|
1819
|
+
buildPatch,
|
|
1732
1820
|
createDeferred,
|
|
1733
1821
|
freshEslintConfig,
|
|
1734
1822
|
hasOwn,
|
|
@@ -1740,6 +1828,6 @@ var datasource_default = PG_DATA_SOURCE_OPTIONS;
|
|
|
1740
1828
|
isObject,
|
|
1741
1829
|
isString,
|
|
1742
1830
|
isValidCron,
|
|
1743
|
-
|
|
1831
|
+
runWithConcurrency
|
|
1744
1832
|
});
|
|
1745
1833
|
//# sourceMappingURL=index.js.map
|