Repository navigation
v3.3.0
Security
- Escape keys in JSON field expressions. A
'in a key used inref(), a patch or update with field expression keys, or thewhereJson*methods broke out of the SQL string literal, allowing SQL injection when keys come from user input. #2077
What's new
withGraphFetched()/withGraphJoined()narrow the result types: fetched relations become required on the result. Generic helpers with an explicitQBreturn type needwithGraphFetched<string>(). ditojs#25- Add
withGraph()with algorithm-agnostic merging, andisJoinChildQuery()ditojs#63 - Add
patchById()andupdateById()#1415 insertGraph()/upsertGraph()resolve cyclic#refdependencies by deferringBelongsToOneforeign keys #1482- Add a
preserveJsonKeysoption tosnakeCaseMappers()to map only the column part of field expressions #1089 - Support empty keys in JSON field expressions, e.g.
col:[""]#2680 whereJson*methods acceptref(),val(),raw()and subqueries on the right side- Pass
returning()options, e.g.includeTriggerModifications, on to knex #2309
Fixes
- Group the user's where clauses when adding a relation's owner condition.
$relatedQuery(...).where(a).orWhere(b).delete()/patch()affected other owners' rows, and finds returned them. #2191, #1909 findByIds([])/whereInComposite()with an empty array and composite ids produced invalid SQL, and matched every row on SQLite #1914onConflict().ignore(): inserted rows were assigned to the wrong models,$setDatabaseJsoncould crash, andinsertAndFetch()fetched undefined ids #2320, #2597, #2661asFindQuery()in many-to-many update and delete hooks lost its filters #2266- Patch validation:
notschemas stay intact #1681, and nestedrequiredis stripped for nullable and untyped objects #1664 resultSize()andpage()count root models withwithGraphJoined()#2329, #2143- Keep aliased subquery and raw selections in
withGraphJoined()modifiers #2365 - Map column names in
whereJson*methods withknexSnakeCaseMappers - Match
table.*selections through knex identifier mapping #2288 - Use the keys of modified
graphExpressionObject()results #2793 - Track internally selected columns on the query builder, so
runAfter()hooks never see them ditojs#45 - Behaviour change: many-to-many
unrelate()/patch()only modify the join rows matching the filters, not all join rows of the matching related rows #1853. The generated SQL of these operations changes. On MySQL, the join table filter avoidsER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG#2127, andunrelate()returns0instead of[]when nothing matches. Ported from #2406. - Behaviour change:
asFindQuery()in hooks no longer applies therunAfter()callbacks of the original query, including those ofthrowIfNotFound()andtraverse(), and returns[]instead of[undefined]for afindById()that finds nothing #2093 - Behaviour change: field expression keys in patch objects, e.g.
'meta:a.b', are validated against the nested schema, so patches that passed before can fail validation #1666 - Behaviour change: the
joinOperationoption ofwithGraphJoined()applies per call, no longer to all relations of the query #2125 - Behaviour change:
withGraphJoined()throws when it can't identify rows, e.g. for a model without a primary key, instead of silently merging them #2748, #2737 insertGraph()/upsertGraph()warn whenonConflict(),ignore()ormerge()is used. The clause is ignored, and will throw in 4.0. #2156
Types
- Export the db-errors classes as types #2499
Docs
- The docs moved to VitePress and are hosted at ditojs.github.io/objection
- Document
relatedFindQueryMutates/relatedInsertQueryMutates#2356 - Document running code after a transaction commits #2582
Other
- Update knex to 3.3 in development, which fixes inverted bindings in
delete()withjoinRelated()#2799
Thanks to @falkenhawk and Marcin L for the many-to-many work in #2406, @kapouer for #2680 and @cesumilo for #2625, which led to preserveJsonKeys.