@freshpointcz/fresh-core 0.0.15 → 0.0.17

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 CHANGED
@@ -1,8 +1,7 @@
1
1
  import dayjs, { Dayjs } from 'dayjs';
2
- import { Logger } from 'winston';
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
- import * as eslint from 'eslint';
4
+ import * as _eslint_core from '@eslint/core';
6
5
  import * as typescript_eslint_dist_compatibility_types from 'typescript-eslint/dist/compatibility-types';
7
6
 
8
7
  /**
@@ -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
 
@@ -574,7 +615,7 @@ declare const FRESH_ESLINT_CONFIG: {
574
615
  };
575
616
  plugins: {
576
617
  "@typescript-eslint": typescript_eslint_dist_compatibility_types.CompatiblePlugin;
577
- prettier: eslint.ESLint.Plugin;
618
+ prettier: _eslint_core.Plugin;
578
619
  };
579
620
  rules: {
580
621
  "prefer-const": string;
@@ -641,4 +682,4 @@ interface HealthCheckResult {
641
682
  };
642
683
  }
643
684
 
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, logger };
685
+ export { AMOUNT_UNIT, ActionCommandCode, ApiError, BaseEntityChangeSubscriber, 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, TimestampColumn, TransactionType, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import dayjs, { Dayjs } from 'dayjs';
2
- import { Logger } from 'winston';
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
- import * as eslint from 'eslint';
4
+ import * as _eslint_core from '@eslint/core';
6
5
  import * as typescript_eslint_dist_compatibility_types from 'typescript-eslint/dist/compatibility-types';
7
6
 
8
7
  /**
@@ -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
 
@@ -574,7 +615,7 @@ declare const FRESH_ESLINT_CONFIG: {
574
615
  };
575
616
  plugins: {
576
617
  "@typescript-eslint": typescript_eslint_dist_compatibility_types.CompatiblePlugin;
577
- prettier: eslint.ESLint.Plugin;
618
+ prettier: _eslint_core.Plugin;
578
619
  };
579
620
  rules: {
580
621
  "prefer-const": string;
@@ -641,4 +682,4 @@ interface HealthCheckResult {
641
682
  };
642
683
  }
643
684
 
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, logger };
685
+ export { AMOUNT_UNIT, ActionCommandCode, ApiError, BaseEntityChangeSubscriber, 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, TimestampColumn, TransactionType, createDeferred, FRESH_ESLINT_CONFIG as freshEslintConfig, hasOwn, isEnumValue, isFlag01, isMaybe, isNumber, isNumberInRange, isObject, isString, isValidCron };
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 crypto = require("crypto");
111
+ var crypto3 = 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 = crypto.createDecipheriv("aes-256-gcm", key, nonce);
358
+ const aesgcm = crypto3.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,7 @@ __export(index_exports, {
428
428
  AMOUNT_UNIT: () => AMOUNT_UNIT,
429
429
  ActionCommandCode: () => ActionCommandCode,
430
430
  ApiError: () => ApiError,
431
+ BaseEntityChangeSubscriber: () => BaseEntityChangeSubscriber,
431
432
  Category: () => Category,
432
433
  DataHelper: () => DataHelper,
433
434
  DateUtils: () => DateUtils,
@@ -460,8 +461,7 @@ __export(index_exports, {
460
461
  isNumberInRange: () => isNumberInRange,
461
462
  isObject: () => isObject,
462
463
  isString: () => isString,
463
- isValidCron: () => isValidCron,
464
- logger: () => logger
464
+ isValidCron: () => isValidCron
465
465
  });
466
466
  module.exports = __toCommonJS(index_exports);
467
467
 
@@ -691,56 +691,6 @@ __name(_SinglePromiseWaiter, "SinglePromiseWaiter");
691
691
  __publicField(_SinglePromiseWaiter, "_instance");
692
692
  var SinglePromiseWaiter = _SinglePromiseWaiter;
693
693
 
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
694
  // src/common/utils/is-cron-valid.ts
745
695
  function isValidCron(expr) {
746
696
  const parts = expr.trim().split(/\s+/);
@@ -865,53 +815,46 @@ var import_typeorm5 = require("typeorm");
865
815
  // src/database/entities/fresh-entity.ts
866
816
  var import_typeorm = require("typeorm");
867
817
 
868
- // ../../node_modules/uuid/dist/esm/stringify.js
869
- var byteToHex = [];
870
- for (let i = 0; i < 256; ++i) {
871
- byteToHex.push((i + 256).toString(16).slice(1));
872
- }
873
- function unsafeStringify(arr, offset = 0) {
874
- 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();
875
- }
876
- __name(unsafeStringify, "unsafeStringify");
877
-
878
- // ../../node_modules/uuid/dist/esm/rng.js
879
- var import_crypto = require("crypto");
818
+ // ../../node_modules/uuid/dist/esm-node/rng.js
819
+ var import_crypto = __toESM(require("crypto"));
880
820
  var rnds8Pool = new Uint8Array(256);
881
821
  var poolPtr = rnds8Pool.length;
882
822
  function rng() {
883
823
  if (poolPtr > rnds8Pool.length - 16) {
884
- (0, import_crypto.randomFillSync)(rnds8Pool);
824
+ import_crypto.default.randomFillSync(rnds8Pool);
885
825
  poolPtr = 0;
886
826
  }
887
827
  return rnds8Pool.slice(poolPtr, poolPtr += 16);
888
828
  }
889
829
  __name(rng, "rng");
890
830
 
891
- // ../../node_modules/uuid/dist/esm/native.js
892
- var import_crypto2 = require("crypto");
831
+ // ../../node_modules/uuid/dist/esm-node/stringify.js
832
+ var byteToHex = [];
833
+ for (let i = 0; i < 256; ++i) {
834
+ byteToHex.push((i + 256).toString(16).slice(1));
835
+ }
836
+ function unsafeStringify(arr, offset = 0) {
837
+ 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]];
838
+ }
839
+ __name(unsafeStringify, "unsafeStringify");
840
+
841
+ // ../../node_modules/uuid/dist/esm-node/native.js
842
+ var import_crypto2 = __toESM(require("crypto"));
893
843
  var native_default = {
894
- randomUUID: import_crypto2.randomUUID
844
+ randomUUID: import_crypto2.default.randomUUID
895
845
  };
896
846
 
897
- // ../../node_modules/uuid/dist/esm/v4.js
847
+ // ../../node_modules/uuid/dist/esm-node/v4.js
898
848
  function v4(options, buf, offset) {
899
- var _a, _b, _c;
900
849
  if (native_default.randomUUID && !buf && !options) {
901
850
  return native_default.randomUUID();
902
851
  }
903
852
  options = options || {};
904
- const rnds = (_c = (_b = options.random) != null ? _b : (_a = options.rng) == null ? void 0 : _a.call(options)) != null ? _c : rng();
905
- if (rnds.length < 16) {
906
- throw new Error("Random bytes length must be >= 16");
907
- }
853
+ const rnds = options.random || (options.rng || rng)();
908
854
  rnds[6] = rnds[6] & 15 | 64;
909
855
  rnds[8] = rnds[8] & 63 | 128;
910
856
  if (buf) {
911
857
  offset = offset || 0;
912
- if (offset < 0 || offset + 16 > buf.length) {
913
- throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
914
- }
915
858
  for (let i = 0; i < 16; ++i) {
916
859
  buf[offset + i] = rnds[i];
917
860
  }
@@ -964,7 +907,7 @@ _ts_decorate([
964
907
  }),
965
908
  (0, import_typeorm.Column)({
966
909
  type: "uuid",
967
- default: /* @__PURE__ */ __name(() => "timescale.uuid_generate_v4()", "default")
910
+ default: /* @__PURE__ */ __name(() => "gen_random_uuid()", "default")
968
911
  }),
969
912
  _ts_metadata("design:type", String)
970
913
  ], FreshEntity.prototype, "uuid", void 0);
@@ -1214,6 +1157,83 @@ var _FreshDao = class _FreshDao {
1214
1157
  __name(_FreshDao, "FreshDao");
1215
1158
  var FreshDao = _FreshDao;
1216
1159
 
1160
+ // src/database/subscribers/base-entity-change.subscriber.ts
1161
+ var _BaseEntityChangeSubscriber = class _BaseEntityChangeSubscriber {
1162
+ // ─── TypeORM lifecycle hooks ────────────────────────────────────────
1163
+ afterInsert(event) {
1164
+ var _a;
1165
+ const id = (_a = event.entity) == null ? void 0 : _a.id;
1166
+ if (!id) {
1167
+ return;
1168
+ }
1169
+ if (event.queryRunner.isTransactionActive) {
1170
+ this.addPending(event, id, "created");
1171
+ } else {
1172
+ console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
1173
+ this.sendNotification(id, "created", event.queryRunner.manager);
1174
+ }
1175
+ }
1176
+ afterUpdate(event) {
1177
+ var _a, _b, _c;
1178
+ const id = (_c = (_a = event.entity) == null ? void 0 : _a.id) != null ? _c : (_b = event.databaseEntity) == null ? void 0 : _b.id;
1179
+ if (!id) {
1180
+ return;
1181
+ }
1182
+ if (event.queryRunner.isTransactionActive) {
1183
+ this.addPending(event, id, "updated");
1184
+ } else {
1185
+ console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
1186
+ this.sendNotification(id, "updated", event.queryRunner.manager);
1187
+ }
1188
+ }
1189
+ afterSoftRemove(event) {
1190
+ var _a, _b, _c;
1191
+ const id = (_c = (_a = event.entity) == null ? void 0 : _a.id) != null ? _c : (_b = event.databaseEntity) == null ? void 0 : _b.id;
1192
+ if (!id) {
1193
+ return;
1194
+ }
1195
+ if (event.queryRunner.isTransactionActive) {
1196
+ this.addPending(event, id, "deleted");
1197
+ } else {
1198
+ console.warn(`${this.SUBSCRIBER_NAME} - Notification sent outside transaction for id=${id}`);
1199
+ this.sendNotification(id, "deleted", event.queryRunner.manager);
1200
+ }
1201
+ }
1202
+ async afterTransactionCommit(event) {
1203
+ var _a;
1204
+ const pending = (_a = event.queryRunner.data) == null ? void 0 : _a[this.PENDING_KEY];
1205
+ if (!pending || pending.size === 0) {
1206
+ return;
1207
+ }
1208
+ event.queryRunner.data[this.PENDING_KEY] = /* @__PURE__ */ new Map();
1209
+ for (const [id, changeEvent] of pending) {
1210
+ await this.sendNotification(id, changeEvent, event.connection.manager);
1211
+ }
1212
+ }
1213
+ // ─── Private helpers ───────────────────────────────────────────────
1214
+ addPending(event, id, changeEvent) {
1215
+ if (!event.queryRunner.data) {
1216
+ event.queryRunner.data = {};
1217
+ }
1218
+ if (!event.queryRunner.data[this.PENDING_KEY]) {
1219
+ event.queryRunner.data[this.PENDING_KEY] = /* @__PURE__ */ new Map();
1220
+ }
1221
+ const existing = event.queryRunner.data[this.PENDING_KEY].get(id);
1222
+ if (!existing || changeEvent === "created" || changeEvent === "deleted") {
1223
+ event.queryRunner.data[this.PENDING_KEY].set(id, changeEvent);
1224
+ }
1225
+ }
1226
+ async sendNotification(id, changeEvent, manager) {
1227
+ try {
1228
+ await this.handleNotification(id, changeEvent, manager);
1229
+ } catch (error) {
1230
+ console.error(`${this.SUBSCRIBER_NAME} - Failed to send notification: ${error instanceof Error ? error.message : error}`);
1231
+ }
1232
+ }
1233
+ };
1234
+ __name(_BaseEntityChangeSubscriber, "BaseEntityChangeSubscriber");
1235
+ var BaseEntityChangeSubscriber = _BaseEntityChangeSubscriber;
1236
+
1217
1237
  // src/common/schema/entities/category.entity.ts
1218
1238
  function _ts_decorate4(decorators, target, key, desc) {
1219
1239
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1714,6 +1734,7 @@ var datasource_default = PG_DATA_SOURCE_OPTIONS;
1714
1734
  AMOUNT_UNIT,
1715
1735
  ActionCommandCode,
1716
1736
  ApiError,
1737
+ BaseEntityChangeSubscriber,
1717
1738
  Category,
1718
1739
  DataHelper,
1719
1740
  DateUtils,
@@ -1746,7 +1767,6 @@ var datasource_default = PG_DATA_SOURCE_OPTIONS;
1746
1767
  isNumberInRange,
1747
1768
  isObject,
1748
1769
  isString,
1749
- isValidCron,
1750
- logger
1770
+ isValidCron
1751
1771
  });
1752
1772
  //# sourceMappingURL=index.js.map