@dwtechs/antity-pgsql 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![License: MIT](https://img.shields.io/npm/l/@dwtechs/antity-pgsql.svg?color=brightgreen)](https://opensource.org/licenses/MIT)
3
3
  [![npm version](https://badge.fury.io/js/%40dwtechs%2Fantity-pgsql.svg)](https://www.npmjs.com/package/@dwtechs/antity-pgsql)
4
4
  [![last version release date](https://img.shields.io/github/release-date/DWTechs/Antity-pgsql.js)](https://www.npmjs.com/package/@dwtechs/antity-pgsql)
5
- ![Jest:coverage](https://img.shields.io/badge/Jest:coverage-54%25-brightgreen.svg)
5
+ ![Jest:coverage](https://img.shields.io/badge/Jest:coverage-87%25-brightgreen.svg)
6
6
 
7
7
  - [Synopsis](#synopsis)
8
8
  - [Support](#support)
@@ -311,10 +311,10 @@ Using substacks simplifies your route definitions and ensures consistent data pr
311
311
  ### Query Methods
312
312
 
313
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.
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` as `creatorid` and `consumer.nickname` as `name` for audit 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` as `updaterid` and `consumer.nickname` as `name` for audit 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` as `creatorid` and `consumer.nickname` as `name` for audit 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` as `updaterid` and `consumer.nickname` as `name` for audit 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` as `creatorId` and `consumer.nickname` as `name` for audit 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` as `updaterId` and `consumer.nickname` as `name` for audit 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` as `creatorId` and `consumer.nickname` as `name` for audit 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` as `updaterId` and `consumer.nickname` as `name` for audit tracking. Does not require an `archived` field in the rows — it is set directly in the SQL.
318
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`.
319
319
  - **delete()**: Deletes rows by their IDs. Expects `req.body.rows` to be an array of objects with `id` property: `[{id: 1}, {id: 2}]`
320
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.
@@ -376,7 +376,7 @@ res.locals.sync // { inserted: 1, updated: 1, deleted: 1 }
376
376
  - **Atomic**: All insert / update / delete operations are wrapped in a single transaction.
377
377
  - **Filter scope**: When `filters` are provided, only rows matching the filter are considered "managed". Rows outside the filter are never touched.
378
378
  - **Property selection**: Insert uses `INSERT` properties; update uses `UPDATE` properties — same as the standalone `add` and `update` middlewares.
379
- - **Consumer tracking**: `consumer.id` and `consumer.nickname` from `res.locals.consumer` are forwarded to inserts as `creatorid`/`name` and to updates as `updaterid`/`name` for audit tracking.
379
+ - **Consumer tracking**: `consumer.id` and `consumer.nickname` from `res.locals.consumer` are forwarded to inserts as `creatorId`/`name` and to updates as `updaterId`/`name` for audit tracking.
380
380
 
381
381
  ### Upsert (Insert or Update)
382
382
 
@@ -440,12 +440,12 @@ const { query, args } = entity.query.upsert(
440
440
  'RETURNING id' // return clause (optional)
441
441
  );
442
442
  // Generates:
443
- // INSERT INTO public.users (name, email, creatorid, name)
443
+ // INSERT INTO public.users (name, email, creatorId, name)
444
444
  // VALUES ($1, $2, $3, $4)
445
445
  // ON CONFLICT (id) DO UPDATE SET
446
446
  // name = EXCLUDED.name,
447
447
  // email = EXCLUDED.email,
448
- // creatorid = EXCLUDED.creatorid,
448
+ // creatorId = EXCLUDED.creatorId,
449
449
  // name = EXCLUDED.name
450
450
  // RETURNING id
451
451
  ```
@@ -305,7 +305,7 @@ class Insert {
305
305
  if (consumerId !== undefined && consumerName !== undefined) {
306
306
  propsToUse.push("consumerId", "consumerName");
307
307
  nbProps += 2;
308
- cols += `, creatorid, name`;
308
+ cols += `, creatorId, name`;
309
309
  }
310
310
  let query = `INSERT INTO ${quoteIfUppercase(schema)}.${quoteIfUppercase(table)} (${cols}) VALUES `;
311
311
  const args = [];
@@ -365,7 +365,7 @@ class Update {
365
365
  for (const p of propsToUse) {
366
366
  if (rows[0][p] === undefined)
367
367
  continue;
368
- const colName = p === "consumerId" ? "updaterid" : p === "consumerName" ? "name" : quoteIfUppercase(p);
368
+ const colName = p === "consumerId" ? "updaterId" : p === "consumerName" ? "name" : quoteIfUppercase(p);
369
369
  query += `${colName} = CASE `;
370
370
  for (let j = 0; j < l; j++) {
371
371
  const row = rows[j];
@@ -413,9 +413,9 @@ class Upsert {
413
413
  let cols = this._cols;
414
414
  if (consumerId !== undefined && consumerName !== undefined) {
415
415
  propsToUse.push("consumerId", "consumerName");
416
- quotedPropsToUse.push(`creatorid`, `name`);
416
+ quotedPropsToUse.push(`creatorId`, `name`);
417
417
  nbProps += 2;
418
- cols += `, creatorid, name`;
418
+ cols += `, creatorId, name`;
419
419
  }
420
420
  const conflictColumns = Array.isArray(conflictTarget)
421
421
  ? conflictTarget.map(col => quoteIfUppercase(col)).join(", ")
@@ -472,7 +472,7 @@ class Archive {
472
472
  const args = rows.map(row => row.id);
473
473
  let query = `UPDATE ${quoteIfUppercase(schema)}.${quoteIfUppercase(table)} SET archived = true`;
474
474
  if (consumerId !== undefined && consumerName !== undefined) {
475
- query += `, updaterid = $${l + 1}, name = $${l + 2}`;
475
+ query += `, updaterId = $${l + 1}, name = $${l + 2}`;
476
476
  args.push(consumerId, consumerName);
477
477
  }
478
478
  query += ` WHERE id IN ${$i(l, 0)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwtechs/antity-pgsql",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Open source library to add PostgreSQL support to @dwtechs/Antity entities.",
5
5
  "keywords": [
6
6
  "entities"