- Fix audit column names for consumer nickname in generated SQL queries:
- INSERT queries (
query.insert(),query.upsert()) now writeconsumer.nicknameintocreatorNameinstead ofname - UPDATE queries (
query.update(),query.archive()) now writeconsumer.nicknameintoupdaterNameinstead ofname
- INSERT queries (
- Add double quotes around audit column names
creatorId,creatorName,updaterId,updaterNamein generated SQL queries to preserve camelCase
- Fix audit column names to use camelCase in generated SQL queries:
- INSERT queries (
query.insert(),query.upsert()) now write intocreatorIdinstead ofcreatorid - UPDATE queries (
query.update(),query.archive()) now write intoupdaterIdinstead ofupdaterid
- INSERT queries (
- Rename audit columns in INSERT and UPDATE queries to match database conventions:
- INSERT queries (
query.insert(),query.upsert()) now writeconsumer.idintocreatoridandconsumer.nicknameintonameinstead of"consumerId"/"consumerName" - UPDATE queries (
query.update(),query.archive()) now writeconsumer.idintoupdateridandconsumer.nicknameintonameinstead of"consumerId"/"consumerName"
- INSERT queries (
- Replace separate
consumerId/consumerNameparameters with a singleconsumerobject ({ id?, nickname? }) across all relevant APIs:query.update(),query.insert(),query.upsert(),query.archive()now acceptconsumer?: { id?: number | string, nickname?: string }instead of two separate arguments- Express middlewares (
add,update,upsert,archive,sync) now readres.locals.consumer.idandres.locals.consumer.nicknameinstead ofres.locals.consumerId/res.locals.consumerName
- Fix
notInmatch mode not working in filter SQL generation: - Add
"in"and"notIn"to allowed match modes fornumberandstring
- Fix filter handling to exclude empty values from WHERE clauses:
- Filters with empty string values are now skipped
- Filters with empty arrays are now skipped
- Filters with null values are skipped except for
isandisNotmatch modes
- Add bulk sync functionality:
- New
sync()Express middleware atomically synchronises a table with the full provided row list inside a single PostgreSQL transaction (BEGIN / COMMIT / ROLLBACK on failure) - Incoming rows without an ID (or with an unknown ID) are inserted; rows with a known ID are updated; existing rows absent from the list are deleted
- Accepts optional
idFieldin request body (defaults to'id') to specify the identity column - Accepts optional
filtersin request body to scope the managed set — rows outside the filter are never touched - Returns synced rows with generated IDs in
res.locals.rows - Returns operation summary
{ inserted, updated, deleted }inres.locals.sync - Supports
consumerId/consumerNameforwarding for history tracking on inserts and updates
- New
- Add
syncArraySubstackgetter returning[normalizeArray, validateArray, sync]middleware chain
- Add UPSERT functionality using PostgreSQL's
INSERT ... ON CONFLICT ... DO UPDATEsyntax:- New
query.upsert()method generates upsert queries with configurable conflict targets - Supports single or multiple column conflict targets (e.g.,
'id'or['email', 'username']) - Properties with both
INSERTandUPDATEoperations are automatically included in upsert - Supports
consumerIdandconsumerNamefor history tracking - Supports
RETURNINGclause to retrieve updated/inserted row IDs
- New
- Add
upsert()Express middleware for handling upsert operations:- Expects
rowsandconflictTargetin request body - Returns upserted rows with IDs in
res.locals.rows - Supports chunking for bulk operations
- Expects
- Add convenience Express substack middlewares:
upsertArraySubstack: Returns[normalizeArray, validateArray, upsert]middleware chainupsertOneSubstack: Returns[normalizeOne, validateOne, upsert]middleware chain
- Add dedicated
Archivequery :- Replaces the previous approach of passing
archived: truethrough the genericUpdatequery - Generates a simplified
UPDATE ... SET archived = true WHERE id IN (...)query directly - Optionally appends
consumerIdandconsumerNameas single scalar values (not per-row CASE blocks)
- Replaces the previous approach of passing
- Add
query.archive()method toSQLEntityusing the newArchiveclass - Add
propertiesgetter toSQLEntityreturning the list ofPropertyinstances passed at construction
updatemiddleware now forwards sanitized and normalized rows tores.locals.rowsfor use in subsequent middlewares and response handling. Likeaddandgetmiddlewares
- Fix wildcard placement in LIKE queries:
- Wildcards (%) are now added to string values instead of SQL parameter placeholders
- Affects matchModes:
startsWith,endsWith,contains,notContains - SQL now generates
LIKE $1with value'%abc%'instead ofLIKE %$1%with value'abc'
- Add support for array-based filter format with multiple filters per property:
- Filters now accept both simple format (single object) and complex format (array of objects)
- Simple format:
{name: {value: "John", matchMode: "contains"}}(backward compatible) - Complex format:
{name: [{value: "John", matchMode: "contains", operator: "or"}]}(new) - Support logical operators (AND/OR) to combine multiple filters on the same property
- Example:
{name: [{value: "John", operator: "or"}, {value: "Jane", operator: "or"}]}
- Fix
isFilterableproperty in declaration file
- Rename Property interface properties for better clarity and consistency:
typeCheck→isTypeChecked: Boolean flag to enable/disable type checkingfilter→isFilterable: Boolean flag to enable/disable filtering in SELECT operationsneed→requiredFor: Array of REST methods (POST, PUT, PATCH) that require this propertysend→isPrivate: Boolean flag inverted -send: truebecomesisPrivate: false
- Rename entity getter method:
unsafeProps→privateProps: Returns array of property names that are private
- Update dependencies:
- "@dwtechs/antity": "0.16.0"
- Fix TypeScript type definitions in antity-pgsql.d.ts:
- Remove DELETE from Operation type (now "SELECT" | "INSERT" | "UPDATE")
- Replace
anytypes with proper TypeScript types (Pool | PoolClient | null,unknown) - Add proper Property class declaration extending BaseProperty from @dwtechs/antity
- Improve import statements for better type safety
- add schema parameter to entity constructor to support multiple schemas in the same database
- Update Property interface to align with @dwtechs/antity 0.15.0
- Remove
methodsproperty (REST methods like GET, POST, PUT, DELETE) - Remove
requiredboolean property - Remove
safeboolean property - Remove
sanitizeboolean property - Remove
normalizeboolean property - Remove
validateboolean property - Add
needproperty: array of REST methods (POST, PUT, PATCH) that require this property in request body - Add
sendproperty: boolean to indicate if property should be sent in response
- Remove
- Add convenience express substack middlewares :
addArraySubstack: Returns [normalizeArray, validateArray, add] middleware chainaddOneSubstack: Returns [normalizeOne, validateOne, add] middleware chainupdateArraySubstack: Returns [normalizeArray, validateArray, update] middleware chainupdateOneSubstack: Returns [normalizeOne, validateOne, update] middleware chain
- change
queryArchivedfunction name toqueryByDateto better reflect its purpose of generating queries for deleting archived rows based on a date conditionqueryByDatefunction now generates a query that uses a hard_delete() function in postgreSQL in order to delete rows and their history in a single query
- Add history getter to entity that generates a query to retrieve the history of changes for a specific row based on its ID
- Update dependencies:
- "@dwtechs/antity": "0.15.0"
- Fix UPDATE query to include ELSE clauses in CASE statements
- Delete "paginate" property from query function
- The total row count is now automatically included when pagination parameters (first/rows) are provided
- Rename delete() method to deleteArchive() for deleting archived rows before a specific date
- Add new delete() method that deletes rows by their IDs using a single database request
- Add query.delete(ids: number[]) method that generates DELETE queries using PostgreSQL's ANY operator
- Add query.deleteArchive() method that generates DELETE queries for archived rows
- Fix INSERT RETURNING clause to properly apply quoting logic for property names with uppercase letters or reserved keywords
- Fix UPDATE query to properly apply quoting logic to fields that contain uppercase letters
- Update dependencies :
- "@dwtechs/antity": "0.14.0"
- Fix INSERT query bug where property values were null due to accessing row data with quoted property names instead of original names
- Make consumerId and consumerName optional parameters in INSERT and UPDATE operations
- Fix declaration file for query.select() function
- Add filter property to make a property filterable in SELECT operations
- Add Operations property to list SQL DML operations available for the property
- Enhance usability with automatic summary logging during entity creation with tree-structured entity summary output showing properties, operations, and CRUD mappings
- Update query.select() method to support filtering instead of creating filters externally.
- Update dependencies :
- "@dwtechs/antity": "0.13.0"
- "@dwtechs/winstan": "0.5.0"
- "@dwtechs/checkard": "3.6.0"
- Update dependencies :
- "@dwtechs/checkard": "3.5.1",
- "@dwtechs/antity": "0.11.2",
- "@dwtechs/sparray": "0.2.1",
- Improved error handling in entity operations
- Update Antity.js to version 0.11.1
- Upgrade @dwtechs/antity dependency to 0.10.0
- Upgrade @dwtechs/antity dependency to 0.9.2
- Enhance quote handling for reserved keywords
- Add proper quote handling for table names
- Add execute() method to the library
- Add quotes around property names with uppercases
- fix package.json file
- initial release