@ditojs/server 2.16.0 → 2.17.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ditojs/server",
3
- "version": "2.16.0",
3
+ "version": "2.17.0",
4
4
  "type": "module",
5
5
  "description": "Dito.js Server – Dito.js is a declarative and modern web framework, based on Objection.js, Koa.js and Vue.js",
6
6
  "repository": "https://github.com/ditojs/dito/tree/master/packages/server",
@@ -22,10 +22,10 @@
22
22
  "node >= 18"
23
23
  ],
24
24
  "dependencies": {
25
- "@ditojs/admin": "^2.16.0",
26
- "@ditojs/build": "^2.16.0",
27
- "@ditojs/router": "^2.16.0",
28
- "@ditojs/utils": "^2.16.0",
25
+ "@ditojs/admin": "^2.17.0",
26
+ "@ditojs/build": "^2.17.0",
27
+ "@ditojs/router": "^2.17.0",
28
+ "@ditojs/utils": "^2.17.0",
29
29
  "@koa/cors": "^4.0.0",
30
30
  "@koa/multer": "^3.0.2",
31
31
  "@originjs/vite-plugin-commonjs": "^1.0.3",
@@ -66,7 +66,7 @@
66
66
  "repl": "^0.1.3",
67
67
  "type-fest": "^4.8.2",
68
68
  "uuid": "^9.0.1",
69
- "vite": "^5.0.2",
69
+ "vite": "^5.0.4",
70
70
  "vue": "^3.3.9"
71
71
  },
72
72
  "peerDependencies": {
@@ -82,13 +82,13 @@
82
82
  "@types/koa-session": "^6.4.5",
83
83
  "@types/koa-static": "^4.0.4",
84
84
  "@types/koa__cors": "^4.0.3",
85
- "@types/node": "^20.10.0",
85
+ "@types/node": "^20.10.1",
86
86
  "knex": "^3.0.1",
87
87
  "objection": "^3.1.3",
88
88
  "typescript": "^5.3.2"
89
89
  },
90
90
  "types": "types",
91
- "gitHead": "333d379f78a3d7469ca79993acd51b48e069ec9a",
91
+ "gitHead": "e0609d98891263c136320e65480c42ad7a289b4b",
92
92
  "scripts": {
93
93
  "types": "tsc --noEmit --esModuleInterop ./types/index.d.ts"
94
94
  },
@@ -8,6 +8,7 @@ import {
8
8
  mapKeys,
9
9
  getValueAtDataPath,
10
10
  setValueAtDataPath,
11
+ normalizeDataPath,
11
12
  parseDataPath,
12
13
  deprecate
13
14
  } from '@ditojs/utils'
@@ -686,7 +687,7 @@ export class QueryBuilder extends objection.QueryBuilder {
686
687
  if (options?.cyclic && method.startsWith('upsert')) {
687
688
  // `_upsertCyclicDitoGraphAndFetch()` needs to run asynchronously,
688
689
  // but we can't do so here and `runBefore()` executes too late,
689
- // so use `_executeFirst()` to work around it.
690
+ // so use `#executeFirst()` to work around it.
690
691
  this.#executeFirst = async () => {
691
692
  this.#executeFirst = null
692
693
  handleGraph(
@@ -727,11 +728,22 @@ export class QueryBuilder extends objection.QueryBuilder {
727
728
  // Now clone the data and delete all references from it, for the initial
728
729
  // upsert.
729
730
  const cloned = clone(data)
731
+ const sparseArrays = {}
730
732
  for (const path of Object.keys(references)) {
731
733
  const parts = parseDataPath(path)
732
734
  const key = parts.pop()
733
735
  const parent = getValueAtDataPath(cloned, parts)
734
736
  delete parent[key]
737
+ if (isArray(parent)) {
738
+ // For arrays, deleting the entry at `key` will leave 'holes' in the
739
+ // array and make it sparse. Collect it in order to compress it later.
740
+ sparseArrays[normalizeDataPath(parts)] = parent
741
+ }
742
+ }
743
+
744
+ // Now condense the sparse arrays to remove the empty entries again:
745
+ for (const [dataPath, array] of Object.entries(sparseArrays)) {
746
+ setValueAtDataPath(cloned, dataPath, Object.values(array))
735
747
  }
736
748
 
737
749
  // TODO: The model isn't necessarily fetched with data in the same order as