@dwtechs/antity-pgsql 0.15.2 → 0.16.0

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/README.md CHANGED
@@ -22,24 +22,14 @@
22
22
  - 🚚 Shipped as EcmaScrypt module
23
23
  - 📝 Written in Typescript
24
24
 
25
-
26
- ## Support
27
-
28
- - node: 22
29
-
30
- This is the oldest targeted versions. The library should work properly on older versions of Node.js but we do not support it officially.
31
-
32
-
33
25
  ## Installation
34
26
 
35
27
  ```bash
36
28
  $ npm i @dwtechs/antity-pgsql
37
29
  ```
38
30
 
39
-
40
31
  ## Usage
41
32
 
42
-
43
33
  ```javascript
44
34
 
45
35
  import { SQLEntity } from "@dwtechs/antity-pgsql";
@@ -140,6 +130,8 @@ router.get("/:id/history", ..., entity.getHistory);
140
130
 
141
131
  type Operation = "SELECT" | "INSERT" | "UPDATE";
142
132
 
133
+ type Row = Record<string, string | number | boolean | Date | number[]>;
134
+
143
135
  type MatchMode =
144
136
  "startsWith" |
145
137
  "endsWith" |
@@ -149,6 +141,7 @@ type MatchMode =
149
141
  "notEquals" |
150
142
  "between" |
151
143
  "in" |
144
+ "notIn" |
152
145
  "lt" |
153
146
  "lte" |
154
147
  "gt" |
@@ -171,6 +164,21 @@ type Filter = {
171
164
  operator?: string; // 'and' | 'or' - Used when multiple filters apply to the same property
172
165
  }
173
166
 
167
+ type PGClient = {
168
+ query(text: string, values?: unknown[]): Promise<PGResponse>;
169
+ };
170
+
171
+ type PGResponse = {
172
+ rows: Record<string, unknown>[];
173
+ rowCount: number | null;
174
+ total?: number;
175
+ };
176
+
177
+ type SelectResponse = {
178
+ rows: Record<string, unknown>[];
179
+ total?: number;
180
+ };
181
+
174
182
  type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void;
175
183
  type ExpressMiddlewareAsync = (req: Request, res: Response, next: NextFunction) => Promise<void>;
176
184
  type SubstackTuple = [ExpressMiddleware, ExpressMiddleware, ExpressMiddlewareAsync];
@@ -206,32 +214,28 @@ class SQLEntity {
206
214
  args: (Filter["value"])[];
207
215
  };
208
216
  update: (
209
- rows: Record<string, unknown>[],
210
- consumerId?: number | string,
211
- consumerName?: string) => {
217
+ rows: Row[],
218
+ consumer?: { id?: number | string, nickname?: string }) => {
212
219
  query: string;
213
220
  args: unknown[];
214
221
  };
215
222
  archive: (
216
- rows: Record<string, unknown>[],
217
- consumerId?: number | string,
218
- consumerName?: string) => {
223
+ rows: Row[],
224
+ consumer?: { id?: number | string, nickname?: string }) => {
219
225
  query: string;
220
226
  args: unknown[];
221
227
  };
222
228
  insert: (
223
- rows: Record<string, unknown>[],
224
- consumerId?: number | string,
225
- consumerName?: string,
229
+ rows: Row[],
230
+ consumer?: { id?: number | string, nickname?: string },
226
231
  rtn?: string) => {
227
232
  query: string;
228
233
  args: unknown[];
229
234
  };
230
235
  upsert: (
231
- rows: Record<string, unknown>[],
236
+ rows: Row[],
232
237
  conflictTarget: string | string[],
233
- consumerId?: number | string,
234
- consumerName?: string,
238
+ consumer?: { id?: number | string, nickname?: string },
235
239
  rtn?: string) => {
236
240
  query: string;
237
241
  args: unknown[];
@@ -266,7 +270,7 @@ function filter(
266
270
  function execute(
267
271
  query: string,
268
272
  args: (string | number | boolean | Date | number[])[],
269
- client: any,
273
+ client: PGClient | null,
270
274
  ): Promise<PGResponse>;
271
275
 
272
276
 
@@ -307,10 +311,10 @@ Using substacks simplifies your route definitions and ensures consistent data pr
307
311
  ### Query Methods
308
312
 
309
313
  - **query.select()**: Generates a SELECT query. When the `rows` parameter is provided (not null), pagination is automatically enabled and the query includes `COUNT(*) OVER () AS total` to return the total number of rows. The total count is extracted from results and returned separately from the row data.
310
- - **query.insert()**: Generates an INSERT query. Accepts an array of objects with properties matching the entity definition. Optionally appends `consumerId` and `consumerName` for history tracking. Supports `RETURNING` clause via the `rtn` parameter.
311
- - **query.update()**: Generates an UPDATE query using CASE statements. Accepts an array of objects with `id` property. Optionally appends `consumerId` and `consumerName` for history tracking.
312
- - **query.upsert()**: Generates an INSERT ... ON CONFLICT ... DO UPDATE query. (See [Upsert](#upsert-insert-or-update) section below.) Accepts an array of objects and a `conflictTarget` (single column name or array of column names) that defines uniqueness. If a conflict occurs on the specified column(s), the row is updated; otherwise, it is inserted. Properties are automatically included if they have both INSERT and UPDATE operations. Optionally appends `consumerId` and `consumerName` for history tracking. Supports `RETURNING` clause via the `rtn` parameter.
313
- - **query.archive()**: Generates a simplified `UPDATE ... SET archived = true WHERE id IN (...)` query. Accepts an array of objects with `id` property. Optionally appends `consumerId` and `consumerName` for history tracking. Does not require an `archived` field in the rows — it is set directly in the SQL.
314
+ - **query.insert()**: Generates an INSERT query. Accepts an array of `Row` objects with properties matching the entity definition. Consumer fields are appended directly to the query arguments — row objects are **not mutated**. Optionally appends `consumer.id` and `consumer.nickname` for history tracking. Supports `RETURNING` clause via the `rtn` parameter.
315
+ - **query.update()**: Generates an UPDATE query using CASE statements. Accepts an array of `Row` objects with `id` property. Optionally appends `consumer.id` and `consumer.nickname` for history tracking.
316
+ - **query.upsert()**: Generates an INSERT ... ON CONFLICT ... DO UPDATE query. (See [Upsert](#upsert-insert-or-update) section below.) Accepts an array of `Row` objects and a `conflictTarget` (single column name or array of column names) that defines uniqueness. If a conflict occurs on the specified column(s), the row is updated; otherwise, it is inserted. Properties are automatically included if they have both INSERT and UPDATE operations. Consumer fields are appended directly to the query arguments — row objects are **not mutated**. Optionally appends `consumer.id` and `consumer.nickname` for history tracking. Supports `RETURNING` clause via the `rtn` parameter.
317
+ - **query.archive()**: Generates a simplified `UPDATE ... SET archived = true WHERE id IN (...)` query. Accepts an array of `Row` objects with `id` property. Optionally appends `consumer.id` and `consumer.nickname` for history tracking. Does not require an `archived` field in the rows — it is set directly in the SQL.
314
318
  - **sync()**: Atomically synchronises the table with the provided rows inside a single PostgreSQL transaction. Missing rows are inserted, existing rows are updated, and rows absent from the list are deleted. Accepts optional `idField` (default `'id'`) and `filters` to restrict the scope of managed rows. Stores the result in `res.locals.rows` and a summary `{ inserted, updated, deleted }` in `res.locals.sync`.
315
319
  - **delete()**: Deletes rows by their IDs. Expects `req.body.rows` to be an array of objects with `id` property: `[{id: 1}, {id: 2}]`
316
320
  - **deleteArchive()**: Deletes archived rows that were archived before a specific date using a PostgreSQL SECURITY DEFINER function. Expects `req.body.date` to be a Date object.
@@ -372,7 +376,7 @@ res.locals.sync // { inserted: 1, updated: 1, deleted: 1 }
372
376
  - **Atomic**: All insert / update / delete operations are wrapped in a single transaction.
373
377
  - **Filter scope**: When `filters` are provided, only rows matching the filter are considered "managed". Rows outside the filter are never touched.
374
378
  - **Property selection**: Insert uses `INSERT` properties; update uses `UPDATE` properties — same as the standalone `add` and `update` middlewares.
375
- - **Consumer tracking**: `consumerId` and `consumerName` from `res.locals` are forwarded to inserts and updates for history tracking.
379
+ - **Consumer tracking**: `consumer.id` and `consumer.nickname` from `res.locals.consumer` are forwarded to inserts and updates for history tracking.
376
380
 
377
381
  ### Upsert (Insert or Update)
378
382
 
@@ -432,8 +436,7 @@ router.post('/users/upsert', ...entity.upsertArraySubstack);
432
436
  const { query, args } = entity.query.upsert(
433
437
  [{ id: 1, name: 'John', email: 'john@example.com' }],
434
438
  'id',
435
- 1, // consumerId (optional)
436
- 'admin', // consumerName (optional)
439
+ { id: 1, nickname: 'admin' }, // consumer (optional)
437
440
  'RETURNING id' // return clause (optional)
438
441
  );
439
442
  // Generates:
@@ -538,7 +541,8 @@ List of possible match modes :
538
541
  | notContains | | string | Whether the value does not contain filter value |
539
542
  | equals | | string \| number | Whether the value equals the filter value |
540
543
  | notEquals | | string \| number | Whether the value does not equal the filter value |
541
- | in | | string[] \| number[] | Whether the value contains the filter value |
544
+ | in | | string[] \| number[] | Whether the value is included in the list |
545
+ | notIn | | string[] \| number[] | Whether the value is not included in the list |
542
546
  | lt | | string \| number | Whether the value is less than the filter value |
543
547
  | lte | | string \| number | Whether the value is less than or equals to the filter value |
544
548
  | gt | | string \| number | Whether the value is greater than the filter value |
@@ -557,8 +561,8 @@ List of compatible match modes for each property types
557
561
 
558
562
  | Name | Match modes |
559
563
  | :---------- | :---------------------- |
560
- | string | startsWith,<br>contains,<br>endsWith,<br>notContains,<br>equals,<br>notEquals,<br>lt,<br>lte,<br>gt,<br>gte |
561
- | number | equals,<br>notEquals,<br>lt,<br>lte,<br>gt,<br>gte |
564
+ | string | startsWith,<br>contains,<br>endsWith,<br>notContains,<br>equals,<br>notEquals,<br>in,<br>notIn,<br>lt,<br>lte,<br>gt,<br>gte |
565
+ | number | equals,<br>notEquals,<br>in,<br>notIn,<br>lt,<br>lte,<br>gt,<br>gte |
562
566
  | date | is,<br>isNot,<br>before,<br>after |
563
567
  | boolean | is,<br>isNot |
564
568
  | string[] | in |
@@ -612,21 +616,25 @@ Any of these can be passed into the options object for each function.
612
616
  | isTypeChecked | boolean | Type is checked during validation | false
613
617
  | isFilterable | boolean | property is filterable in a SELECT operation | true
614
618
  | operations | Operation[] | Property is used for the DML operations only | ["SELECT", "INSERT", "UPDATE"]
615
- | sanitizer | ((v:any) => any) \| null | Custom sanitizer function if sanitize is true | null
616
- | normalizer | ((v:any) => any) \| null | Custom Normalizer function if normalize is true | null
617
- | validator | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | validator function if validate is true | null
619
+ | sanitizer | ((v: unknown) => unknown) \| null | Custom sanitizer function if sanitize is true | null
620
+ | normalizer | ((v: unknown) => unknown) \| null | Custom Normalizer function if normalize is true | null
621
+ | validator | ((v: unknown) => unknown) \| null | validator function if validate is true | null
618
622
 
619
623
 
620
624
  * *Min and max parameters are not used for boolean type*
621
625
  * *TypeCheck Parameter is not used for boolean, string and array types*
622
626
 
627
+ ## Support
628
+
629
+ | Environment | Version |
630
+ | :---------- | :-----: |
631
+ | Node.js | >= 22 |
623
632
 
624
633
  ## Contributors
625
634
 
626
635
  Antity.js is still in development and we would be glad to get all the help you can provide.
627
636
  To contribute please read **[contributor.md](https://github.com/DWTechs/Antity.js/blob/main/contributor.md)** for detailed installation guide.
628
637
 
629
-
630
638
  ## Stack
631
639
 
632
640
  | Purpose | Choice | Motivation |
@@ -27,7 +27,6 @@ https://github.com/DWTechs/Antity-pgsql.js
27
27
  import { Entity, Property as BaseProperty } from "@dwtechs/antity";
28
28
  import type { Type, Method } from "@dwtechs/antity";
29
29
  import type { Request, Response, NextFunction } from 'express';
30
- import type { Pool, PoolClient } from 'pg';
31
30
 
32
31
  export type Operation = "SELECT" | "INSERT" | "UPDATE";
33
32
  export type Sort = "ASC" | "DESC";
@@ -75,9 +74,20 @@ export type Geometry = {
75
74
  maxLat: number;
76
75
  };
77
76
  };
77
+ export type Row = Record<string, Filter["value"]>;
78
+
79
+ export type PGClient = {
80
+ query(text: string, values?: unknown[]): Promise<PGResponse>;
81
+ };
82
+
83
+ export type SelectResponse = {
84
+ rows: Record<string, unknown>[];
85
+ total?: number;
86
+ };
87
+
78
88
  export type PGResponse = {
79
89
  rows: Record<string, unknown>[];
80
- rowCount: number;
90
+ rowCount: number | null;
81
91
  total?: number;
82
92
  command?: string;
83
93
  oid?: number;
@@ -132,27 +142,24 @@ export declare class SQLEntity extends Entity {
132
142
  };
133
143
 
134
144
  update: (
135
- rows: Record<string, unknown>[],
136
- consumerId?: number | string,
137
- consumerName?: string
145
+ rows: Row[],
146
+ consumer?: { id?: number | string, nickname?: string }
138
147
  ) => {
139
148
  query: string;
140
149
  args: unknown[];
141
150
  };
142
151
 
143
152
  archive: (
144
- rows: Record<string, unknown>[],
145
- consumerId?: number | string,
146
- consumerName?: string
153
+ rows: Row[],
154
+ consumer?: { id?: number | string, nickname?: string }
147
155
  ) => {
148
156
  query: string;
149
157
  args: unknown[];
150
158
  };
151
159
 
152
160
  insert: (
153
- rows: Record<string, unknown>[],
154
- consumerId?: number | string,
155
- consumerName?: string,
161
+ rows: Row[],
162
+ consumer?: { id?: number | string, nickname?: string },
156
163
  rtn?: string
157
164
  ) => {
158
165
  query: string;
@@ -160,10 +167,9 @@ export declare class SQLEntity extends Entity {
160
167
  };
161
168
 
162
169
  upsert: (
163
- rows: Record<string, unknown>[],
170
+ rows: Row[],
164
171
  conflictTarget: string | string[],
165
- consumerId?: number | string,
166
- consumerName?: string,
172
+ consumer?: { id?: number | string, nickname?: string },
167
173
  rtn?: string
168
174
  ) => {
169
175
  query: string;
@@ -202,6 +208,6 @@ export declare function filter(
202
208
  export declare function execute(
203
209
  query: string,
204
210
  args: (string | number | boolean | Date | number[])[],
205
- client: Pool | PoolClient | null
211
+ client: PGClient | null
206
212
  ): Promise<PGResponse>;
207
213
 
@@ -43,15 +43,15 @@ var pool = new Pool({
43
43
  const LOGS_PREFIX = '[Antity-PGSQL] ';
44
44
 
45
45
  function start(query, args) {
46
- const a = JSON.stringify(args);
47
- const q = query.replace(/[\n\r]+/g, "").replace(/\s{2,}/g, " ");
48
- log.debug(`${LOGS_PREFIX}Pgsql: { Query : '${q}', Args : '${a}' }`);
46
+ log.debug(() => {
47
+ const a = JSON.stringify(args);
48
+ const q = query.replace(/[\n\r]+/g, "").replace(/\s{2,}/g, " ");
49
+ return `${LOGS_PREFIX}Pgsql: { Query : '${q}', Args : '${a}' }`;
50
+ });
49
51
  return Date.now();
50
52
  }
51
53
  function end(res, time) {
52
- const r = JSON.stringify(res);
53
- const t = Date.now() - time;
54
- log.debug(`Pgsql response in ${t}ms : ${r}`);
54
+ log.debug(() => `Pgsql response in ${Date.now() - time}ms : ${JSON.stringify(res)}`);
55
55
  }
56
56
  var perf = {
57
57
  start,
@@ -311,13 +311,14 @@ class Insert {
311
311
  const args = [];
312
312
  let i = 0;
313
313
  for (const row of rows) {
314
- if (consumerId !== undefined && consumerName !== undefined) {
315
- row.consumerId = consumerId;
316
- row.consumerName = consumerName;
317
- }
318
314
  query += `${$i(nbProps, i)}, `;
319
315
  for (const prop of propsToUse) {
320
- args.push(row[prop]);
316
+ if (prop === "consumerId")
317
+ args.push(consumerId);
318
+ else if (prop === "consumerName")
319
+ args.push(consumerName);
320
+ else
321
+ args.push(row[prop]);
321
322
  }
322
323
  i += nbProps;
323
324
  }
@@ -356,7 +357,7 @@ class Update {
356
357
  const propsToUse = [...this._props];
357
358
  if (consumerId !== undefined && consumerName !== undefined)
358
359
  propsToUse.push("consumerId", "consumerName");
359
- log.debug(`${LOGS_PREFIX}Update query input rows: ${JSON.stringify(rows, null, 2)}`);
360
+ log.debug(() => `${LOGS_PREFIX}Update query input rows: ${JSON.stringify(rows, null, 2)}`);
360
361
  const l = rows.length;
361
362
  const args = rows.map(row => row.id);
362
363
  let query = `UPDATE ${quoteIfUppercase(schema)}.${quoteIfUppercase(table)} SET `;
@@ -422,14 +423,13 @@ class Upsert {
422
423
  const args = [];
423
424
  let i = 0;
424
425
  for (const row of rows) {
425
- if (consumerId !== undefined && consumerName !== undefined) {
426
- row.consumerId = consumerId;
427
- row.consumerName = consumerName;
428
- }
429
426
  query += `${$i(nbProps, i)}, `;
430
- for (const prop of propsToUse) {
427
+ for (const prop of this._props) {
431
428
  args.push(row[prop]);
432
429
  }
430
+ if (consumerId !== undefined && consumerName !== undefined) {
431
+ args.push(consumerId, consumerName);
432
+ }
433
433
  i += nbProps;
434
434
  }
435
435
  query = query.slice(0, -2);
@@ -466,7 +466,7 @@ var __awaiter$2 = (undefined && undefined.__awaiter) || function (thisArg, _argu
466
466
  };
467
467
  class Archive {
468
468
  query(schema, table, rows, consumerId, consumerName) {
469
- log.debug(`${LOGS_PREFIX}Archive query input rows: ${JSON.stringify(rows, null, 2)}`);
469
+ log.debug(() => `${LOGS_PREFIX}Archive query input rows: ${JSON.stringify(rows, null, 2)}`);
470
470
  const l = rows.length;
471
471
  const args = rows.map(row => row.id);
472
472
  let query = `UPDATE ${quoteIfUppercase(schema)}.${quoteIfUppercase(table)} SET archived = true`;
@@ -587,12 +587,12 @@ function cleanFilters(filters, properties) {
587
587
  if (filters.hasOwnProperty(k)) {
588
588
  const prop = properties.find(p => p.key === k);
589
589
  if (!prop) {
590
- log.warn(`${LOGS_PREFIX}Filters: skipping unknown property: ${k}`);
590
+ log.warn(() => `${LOGS_PREFIX}Filters: skipping unknown property: ${k}`);
591
591
  delete filters[k];
592
592
  continue;
593
593
  }
594
594
  if (!prop.isFilterable) {
595
- log.warn(`${LOGS_PREFIX}Filters: skipping unfilterable property: ${k}`);
595
+ log.warn(() => `${LOGS_PREFIX}Filters: skipping unfilterable property: ${k}`);
596
596
  delete filters[k];
597
597
  continue;
598
598
  }
@@ -602,7 +602,7 @@ function cleanFilters(filters, properties) {
602
602
  const validFilters = filterArray.filter((f) => {
603
603
  const { matchMode: matchMode$1 } = f;
604
604
  if (!matchMode$1 || !matchMode(type$1, matchMode$1)) {
605
- log.warn(`${LOGS_PREFIX}Filters: skipping invalid match mode: "${matchMode$1}" for type: "${type$1}" at property: "${k}"`);
605
+ log.warn(() => `${LOGS_PREFIX}Filters: skipping invalid match mode: "${matchMode$1}" for type: "${type$1}" at property: "${k}"`);
606
606
  return false;
607
607
  }
608
608
  return true;
@@ -617,9 +617,8 @@ function cleanFilters(filters, properties) {
617
617
  }
618
618
 
619
619
  function logSummary(name, table, properties) {
620
- const summary = generateSummary(name, table, properties);
621
620
  log.info(`${LOGS_PREFIX}Entity "${name}" created successfully`);
622
- log.info(`${LOGS_PREFIX}Entity Summary:\n${summary}`);
621
+ log.info(() => `${LOGS_PREFIX}Entity Summary:\n${generateSummary(name, table, properties)}`);
623
622
  }
624
623
  function generateSummary(name, table, properties) {
625
624
  const lines = [];
@@ -702,20 +701,20 @@ class SQLEntity extends Entity {
702
701
  select: (first = 0, rows = null, sortField = null, sortOrder = null, filters = null) => {
703
702
  return this.sel.query(this.schema, this.table, first, rows, sortField, sortOrder, filters);
704
703
  },
705
- update: (rows, consumerId, consumerName) => {
706
- return this.upd.query(this.schema, this.table, rows, consumerId, consumerName);
704
+ update: (rows, consumer) => {
705
+ return this.upd.query(this.schema, this.table, rows, consumer === null || consumer === void 0 ? void 0 : consumer.id, consumer === null || consumer === void 0 ? void 0 : consumer.nickname);
707
706
  },
708
- insert: (rows, consumerId, consumerName, rtn = "") => {
709
- return this.ins.query(this.schema, this.table, rows, consumerId, consumerName, rtn);
707
+ insert: (rows, consumer, rtn = "") => {
708
+ return this.ins.query(this.schema, this.table, rows, consumer === null || consumer === void 0 ? void 0 : consumer.id, consumer === null || consumer === void 0 ? void 0 : consumer.nickname, rtn);
710
709
  },
711
- upsert: (rows, conflictTarget, consumerId, consumerName, rtn = "") => {
712
- return this.ups.query(this.schema, this.table, rows, conflictTarget, consumerId, consumerName, rtn);
710
+ upsert: (rows, conflictTarget, consumer, rtn = "") => {
711
+ return this.ups.query(this.schema, this.table, rows, conflictTarget, consumer === null || consumer === void 0 ? void 0 : consumer.id, consumer === null || consumer === void 0 ? void 0 : consumer.nickname, rtn);
713
712
  },
714
713
  delete: (ids) => {
715
714
  return queryById(this.schema, this.table, ids);
716
715
  },
717
- archive: (rows, consumerId, consumerName) => {
718
- return this.arc.query(this.schema, this.table, rows, consumerId, consumerName);
716
+ archive: (rows, consumer) => {
717
+ return this.arc.query(this.schema, this.table, rows, consumer === null || consumer === void 0 ? void 0 : consumer.id, consumer === null || consumer === void 0 ? void 0 : consumer.nickname);
719
718
  },
720
719
  deleteArchive: () => {
721
720
  return queryByDate();
@@ -735,9 +734,7 @@ class SQLEntity extends Entity {
735
734
  const filters = cleanFilters(b.filters, this.properties) || null;
736
735
  const pagination = b.pagination || false;
737
736
  const dbClient = l.dbClient || null;
738
- log.debug(`get(first='${first}', rows='${rows}',
739
- sortOrder='${sortOrder}', sortField='${sortField}',
740
- pagination=${pagination}, filters=${JSON.stringify(filters)}`);
737
+ log.debug(() => `get(first='${first}', rows='${rows}', sortOrder='${sortOrder}', sortField='${sortField}', pagination=${pagination}, filters=${JSON.stringify(filters)}`);
741
738
  const { query, args } = this.sel.query(this._schema, this._table, first, rows, sortField, sortOrder, filters);
742
739
  this.sel.execute(query, args, dbClient)
743
740
  .then((r) => {
@@ -748,12 +745,13 @@ class SQLEntity extends Entity {
748
745
  .catch((err) => next(err));
749
746
  };
750
747
  this.add = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
748
+ var _a, _b;
751
749
  const l = res.locals;
752
750
  const rows = req.body.rows;
753
751
  const dbClient = l.dbClient || null;
754
- const cId = l.consumerId;
755
- const cName = l.consumerName;
756
- log.debug(`${LOGS_PREFIX}addMany(rows=${rows.length}, consumerId=${cId})`);
752
+ const cId = (_a = l.consumer) === null || _a === void 0 ? void 0 : _a.id;
753
+ const cName = (_b = l.consumer) === null || _b === void 0 ? void 0 : _b.nickname;
754
+ log.debug(() => `${LOGS_PREFIX}addMany(rows=${rows.length}, consumerId=${cId})`);
757
755
  const rtn = this.ins.rtn("id");
758
756
  const chunks = chunk(rows);
759
757
  for (const c of chunks) {
@@ -774,12 +772,13 @@ class SQLEntity extends Entity {
774
772
  next();
775
773
  });
776
774
  this.update = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
775
+ var _a, _b;
777
776
  const l = res.locals;
778
777
  const r = req.body.rows;
779
778
  const dbClient = l.dbClient || null;
780
- const cId = l.consumerId;
781
- const cName = l.consumerName;
782
- log.debug(`${LOGS_PREFIX}update(rows=${r.length}, consumerId=${cId})`);
779
+ const cId = (_a = l.consumer) === null || _a === void 0 ? void 0 : _a.id;
780
+ const cName = (_b = l.consumer) === null || _b === void 0 ? void 0 : _b.nickname;
781
+ log.debug(() => `${LOGS_PREFIX}update(rows=${r.length}, consumerId=${cId})`);
783
782
  const chunks = chunk(r);
784
783
  for (const c of chunks) {
785
784
  const { query, args } = this.upd.query(this._schema, this._table, c, cId, cName);
@@ -794,19 +793,20 @@ class SQLEntity extends Entity {
794
793
  next();
795
794
  });
796
795
  this.upsert = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
796
+ var _a, _b;
797
797
  const l = res.locals;
798
798
  const rows = req.body.rows;
799
799
  const conflictTarget = req.body.conflictTarget;
800
800
  const dbClient = l.dbClient || null;
801
- const cId = l.consumerId;
802
- const cName = l.consumerName;
801
+ const cId = (_a = l.consumer) === null || _a === void 0 ? void 0 : _a.id;
802
+ const cName = (_b = l.consumer) === null || _b === void 0 ? void 0 : _b.nickname;
803
803
  if (!conflictTarget) {
804
804
  return next({ status: 400, msg: "Missing conflictTarget for upsert operation" });
805
805
  }
806
806
  if (!rows || !Array.isArray(rows) || rows.length === 0) {
807
807
  return next({ status: 400, msg: "Missing or empty rows array for upsert operation" });
808
808
  }
809
- log.debug(`${LOGS_PREFIX}upsert(rows=${rows.length}, conflictTarget=${conflictTarget}, consumerId=${cId})`);
809
+ log.debug(() => `${LOGS_PREFIX}upsert(rows=${rows.length}, conflictTarget=${conflictTarget}, consumerId=${cId})`);
810
810
  const rtn = this.ups.rtn("id");
811
811
  const chunks = chunk(rows);
812
812
  for (const c of chunks) {
@@ -827,12 +827,13 @@ class SQLEntity extends Entity {
827
827
  next();
828
828
  });
829
829
  this.archive = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
830
+ var _a, _b;
830
831
  const l = res.locals;
831
- let r = req.body.rows;
832
+ const r = req.body.rows;
832
833
  const dbClient = l.dbClient || null;
833
- const cId = l.consumerId;
834
- const cName = l.consumerName;
835
- log.debug(`${LOGS_PREFIX}archive(rows=${r.length}, consumerId=${cId})`);
834
+ const cId = (_a = l.consumer) === null || _a === void 0 ? void 0 : _a.id;
835
+ const cName = (_b = l.consumer) === null || _b === void 0 ? void 0 : _b.nickname;
836
+ log.debug(() => `${LOGS_PREFIX}archive(rows=${r.length}, consumerId=${cId})`);
836
837
  const chunks = chunk(r);
837
838
  for (const c of chunks) {
838
839
  const { query, args } = this.arc.query(this._schema, this._table, c, cId, cName);
@@ -849,7 +850,7 @@ class SQLEntity extends Entity {
849
850
  const rows = req.body.rows;
850
851
  const dbClient = res.locals.dbClient || null;
851
852
  const ids = rows.map((row) => row.id);
852
- log.debug(`${LOGS_PREFIX}delete ${rows.length} rows : (${ids.join(", ")})`);
853
+ log.debug(() => `${LOGS_PREFIX}delete ${rows.length} rows : (${ids.join(", ")})`);
853
854
  const { query, args } = queryById(this._schema, this._table, ids);
854
855
  try {
855
856
  yield execute(query, args, dbClient);
@@ -862,7 +863,7 @@ class SQLEntity extends Entity {
862
863
  this.deleteArchive = (req, res, next) => {
863
864
  const date = req.body.date;
864
865
  const dbClient = res.locals.dbClient || null;
865
- log.debug(`${LOGS_PREFIX}deleteArchive(schema=${this._schema}, table=${this._table}, date=${date})`);
866
+ log.debug(() => `${LOGS_PREFIX}deleteArchive(schema=${this._schema}, table=${this._table}, date=${date})`);
866
867
  executeArchived(this._schema, this._table, date, queryByDate(), dbClient)
867
868
  .then(() => next())
868
869
  .catch((err) => next(err));
@@ -871,9 +872,10 @@ class SQLEntity extends Entity {
871
872
  const id = req.params.id;
872
873
  const dbClient = res.locals.dbClient || null;
873
874
  if (!id) {
874
- return next({ status: 400, msg: "Missing id" });
875
+ next({ status: 400, msg: "Missing id" });
876
+ return;
875
877
  }
876
- log.debug(`${LOGS_PREFIX}getHistory(schema=${this._schema}, table=${this._table}, id=${id})`);
878
+ log.debug(() => `${LOGS_PREFIX}getHistory(schema=${this._schema}, table=${this._table}, id=${id})`);
877
879
  const sql = `
878
880
  SELECT id, tstamp, operation, "consumerId", "consumerName"
879
881
  FROM log.history
@@ -895,16 +897,16 @@ class SQLEntity extends Entity {
895
897
  .catch((err) => next(err));
896
898
  };
897
899
  this.sync = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
898
- var _a;
900
+ var _a, _b, _c;
899
901
  const l = res.locals;
900
902
  const rows = req.body.rows;
901
903
  const idField = (_a = req.body.idField) !== null && _a !== void 0 ? _a : 'id';
902
- const cId = l.consumerId;
903
- const cName = l.consumerName;
904
+ const cId = (_b = l.consumer) === null || _b === void 0 ? void 0 : _b.id;
905
+ const cName = (_c = l.consumer) === null || _c === void 0 ? void 0 : _c.nickname;
904
906
  if (!rows || !Array.isArray(rows)) {
905
907
  return next({ status: 400, msg: "Missing or invalid rows array for sync operation" });
906
908
  }
907
- log.debug(`${LOGS_PREFIX}sync(rows=${rows.length}, idField=${idField}, consumerId=${cId})`);
909
+ log.debug(() => `${LOGS_PREFIX}sync(rows=${rows.length}, idField=${idField}, consumerId=${cId})`);
908
910
  const cleanedFilters = cleanFilters(req.body.filters, this.properties) || null;
909
911
  const { conditions, args: filterArgs } = add(cleanedFilters);
910
912
  const whereClause = conditions.length ? ` WHERE ${conditions.join(' AND ')}` : '';
@@ -964,7 +966,7 @@ class SQLEntity extends Entity {
964
966
  });
965
967
  this._table = name;
966
968
  this._schema = schema;
967
- log.info(`${LOGS_PREFIX}Creating SQLEntity: "${name}"`);
969
+ log.info(() => `${LOGS_PREFIX}Creating SQLEntity: "${name}"`);
968
970
  for (const p of properties) {
969
971
  this.mapProps(p.operations, p.key);
970
972
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwtechs/antity-pgsql",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "Open source library to add PostgreSQL support to @dwtechs/Antity entities.",
5
5
  "keywords": [
6
6
  "entities"
@@ -37,7 +37,7 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@dwtechs/checkard": "3.6.0",
40
- "@dwtechs/winstan": "0.5.0",
40
+ "@dwtechs/winstan": "0.7.0",
41
41
  "@dwtechs/antity": "0.16.0",
42
42
  "@dwtechs/sparray": "0.2.1",
43
43
  "pg": "8.20.0"