@ditojs/server 2.32.1 → 2.32.3
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.32.
|
|
3
|
+
"version": "2.32.3",
|
|
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",
|
|
@@ -25,22 +25,22 @@
|
|
|
25
25
|
"node >= 18"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@ditojs/admin": "^2.32.
|
|
29
|
-
"@ditojs/build": "^2.32.
|
|
30
|
-
"@ditojs/router": "^2.32.
|
|
31
|
-
"@ditojs/utils": "^2.32.
|
|
28
|
+
"@ditojs/admin": "^2.32.2",
|
|
29
|
+
"@ditojs/build": "^2.32.2",
|
|
30
|
+
"@ditojs/router": "^2.32.2",
|
|
31
|
+
"@ditojs/utils": "^2.32.2",
|
|
32
32
|
"@koa/cors": "^5.0.0",
|
|
33
33
|
"@koa/multer": "^3.0.2",
|
|
34
34
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
35
|
-
"@vitejs/plugin-vue": "^5.1.
|
|
36
|
-
"@vue/compiler-sfc": "3.5.
|
|
35
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
36
|
+
"@vue/compiler-sfc": "^3.5.6",
|
|
37
37
|
"ajv": "^8.17.1",
|
|
38
38
|
"ajv-formats": "^2.1.1",
|
|
39
39
|
"bcryptjs": "^2.4.3",
|
|
40
40
|
"bytes": "^3.1.2",
|
|
41
41
|
"data-uri-to-buffer": "^6.0.2",
|
|
42
42
|
"eventemitter2": "^6.4.9",
|
|
43
|
-
"file-type": "^19.
|
|
43
|
+
"file-type": "^19.5.0",
|
|
44
44
|
"koa": "^2.15.3",
|
|
45
45
|
"koa-bodyparser": "^4.4.1",
|
|
46
46
|
"koa-compose": "^4.1.0",
|
|
@@ -67,10 +67,10 @@
|
|
|
67
67
|
"pino-pretty": "^11.2.2",
|
|
68
68
|
"pluralize": "^8.0.0",
|
|
69
69
|
"repl": "^0.1.3",
|
|
70
|
-
"type-fest": "^4.26.
|
|
70
|
+
"type-fest": "^4.26.1",
|
|
71
71
|
"uuid": "^10.0.0",
|
|
72
|
-
"vite": "^5.4.
|
|
73
|
-
"vue": "^3.5.
|
|
72
|
+
"vite": "^5.4.6",
|
|
73
|
+
"vue": "^3.5.6"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"@aws-sdk/client-s3": "^3.0.0",
|
|
@@ -87,11 +87,11 @@
|
|
|
87
87
|
"@types/koa-session": "^6.4.5",
|
|
88
88
|
"@types/koa-static": "^4.0.4",
|
|
89
89
|
"@types/koa__cors": "^5.0.0",
|
|
90
|
-
"@types/node": "^22.5.
|
|
90
|
+
"@types/node": "^22.5.5",
|
|
91
91
|
"knex": "^3.1.0",
|
|
92
92
|
"objection": "^3.1.4",
|
|
93
|
-
"typescript": "^5.
|
|
93
|
+
"typescript": "^5.6.2"
|
|
94
94
|
},
|
|
95
95
|
"types": "types",
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "18442b45101f469e53efd91e93854ef954dfb785"
|
|
97
97
|
}
|
|
@@ -197,7 +197,9 @@ export class CollectionController extends Controller {
|
|
|
197
197
|
collection = this.convertToCoreActions({
|
|
198
198
|
async get(ctx, modify) {
|
|
199
199
|
const result = await this.execute(ctx, (query, trx) => {
|
|
200
|
-
query
|
|
200
|
+
query
|
|
201
|
+
.find(ctx.filteredQuery, this.allowParam)
|
|
202
|
+
.modify(getModify(modify, trx))
|
|
201
203
|
return this.isOneToOne ? query.first() : query
|
|
202
204
|
})
|
|
203
205
|
// This method doesn't always return an array:
|
|
@@ -210,7 +212,7 @@ export class CollectionController extends Controller {
|
|
|
210
212
|
const count = await this.execute(ctx, (query, trx) =>
|
|
211
213
|
query
|
|
212
214
|
.ignoreScope()
|
|
213
|
-
.find(ctx.
|
|
215
|
+
.find(ctx.filteredQuery, this.allowParam)
|
|
214
216
|
.modify(query => this.isOneToOne && query.throwIfNotFound())
|
|
215
217
|
.modify(getModify(modify, trx))
|
|
216
218
|
.modify(query => (this.unrelate ? query.unrelate() : query.delete()))
|
|
@@ -248,7 +250,7 @@ export class CollectionController extends Controller {
|
|
|
248
250
|
return this.execute(ctx, (query, trx) =>
|
|
249
251
|
query
|
|
250
252
|
.findById(ctx.memberId)
|
|
251
|
-
.find(ctx.
|
|
253
|
+
.find(ctx.filteredQuery, this.allowParam)
|
|
252
254
|
.throwIfNotFound()
|
|
253
255
|
.modify(getModify(modify, trx))
|
|
254
256
|
)
|
|
@@ -259,7 +261,7 @@ export class CollectionController extends Controller {
|
|
|
259
261
|
query
|
|
260
262
|
.ignoreScope()
|
|
261
263
|
.findById(ctx.memberId)
|
|
262
|
-
.find(ctx.
|
|
264
|
+
.find(ctx.filteredQuery, this.allowParam)
|
|
263
265
|
.throwIfNotFound()
|
|
264
266
|
.modify(getModify(modify, trx))
|
|
265
267
|
.modify(query => (this.unrelate ? query.unrelate() : query.delete()))
|
|
@@ -84,20 +84,35 @@ export default class ControllerAction {
|
|
|
84
84
|
// - 'query': Use `ctx.request.query`, regardless of the action's method.
|
|
85
85
|
// - 'body': Use `ctx.request.body`, regardless of the action's method.
|
|
86
86
|
getParams(ctx, from = this.paramsName) {
|
|
87
|
-
const
|
|
87
|
+
const params = from === 'path' ? ctx.params : ctx.request[from]
|
|
88
88
|
// koa-bodyparser always sets an object, even when there is no body.
|
|
89
89
|
// Detect this here and return null instead.
|
|
90
90
|
const isNull = (
|
|
91
91
|
from === 'body' &&
|
|
92
92
|
ctx.request.headers['content-length'] === '0' &&
|
|
93
|
-
Object.keys(
|
|
93
|
+
Object.keys(params).length === 0
|
|
94
94
|
)
|
|
95
|
-
return isNull ? null :
|
|
95
|
+
return isNull ? null : params
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
async callAction(ctx) {
|
|
99
99
|
const params = await this.validateParameters(ctx)
|
|
100
|
-
const { args, member } = await this.collectArguments(
|
|
100
|
+
const { args, member } = await this.collectArguments(
|
|
101
|
+
ctx,
|
|
102
|
+
params
|
|
103
|
+
)
|
|
104
|
+
let filteredQuery = null
|
|
105
|
+
Object.defineProperty(ctx, 'filteredQuery', {
|
|
106
|
+
get: () => {
|
|
107
|
+
filteredQuery ??=
|
|
108
|
+
params && this.paramsName === 'query'
|
|
109
|
+
? this.filterParameters(params)
|
|
110
|
+
: params
|
|
111
|
+
return filteredQuery
|
|
112
|
+
},
|
|
113
|
+
enumerable: false,
|
|
114
|
+
configurable: true
|
|
115
|
+
})
|
|
101
116
|
await this.controller.handleAuthorization(this.authorization, ctx, member)
|
|
102
117
|
const { identifier } = this
|
|
103
118
|
await this.controller.emitHook(`before:${identifier}`, false, ctx, ...args)
|
|
@@ -119,11 +134,12 @@ export default class ControllerAction {
|
|
|
119
134
|
if (!this.parameters.validate) {
|
|
120
135
|
return null
|
|
121
136
|
}
|
|
122
|
-
// Since validation also performs coercion, create a clone
|
|
123
|
-
// so that this doesn't modify the data on `ctx`.
|
|
137
|
+
// Since validation also performs coercion, create a shallow clone of the
|
|
138
|
+
// params so that this doesn't modify the data on `ctx`.Actually used values
|
|
139
|
+
// themselves are deep cloned below.
|
|
124
140
|
// NOTE: The data can be either an object or an array.
|
|
125
|
-
const data =
|
|
126
|
-
let params =
|
|
141
|
+
const data = { ...this.getParams(ctx) }
|
|
142
|
+
let params = {}
|
|
127
143
|
const { dataName } = this.parameters
|
|
128
144
|
let unwrapRoot = false
|
|
129
145
|
const errors = []
|
|
@@ -152,12 +168,14 @@ export default class ControllerAction {
|
|
|
152
168
|
params = {}
|
|
153
169
|
}
|
|
154
170
|
params[paramName] = data
|
|
171
|
+
} else {
|
|
172
|
+
params[paramName] = clone(data[paramName])
|
|
155
173
|
}
|
|
156
174
|
if (from) {
|
|
157
175
|
// Allow parameters to be 'borrowed' from other objects.
|
|
158
|
-
const
|
|
176
|
+
const source = this.getParams(ctx, from)
|
|
159
177
|
// See above for an explanation of `clone()`:
|
|
160
|
-
params[paramName] = clone(wrapRoot ?
|
|
178
|
+
params[paramName] = clone(wrapRoot ? source : source?.[paramName])
|
|
161
179
|
}
|
|
162
180
|
try {
|
|
163
181
|
const value = params[paramName]
|
|
@@ -263,6 +281,21 @@ export default class ControllerAction {
|
|
|
263
281
|
return { args, member }
|
|
264
282
|
}
|
|
265
283
|
|
|
284
|
+
filterParameters(params) {
|
|
285
|
+
const filtered = {}
|
|
286
|
+
const consumedNames = Object.fromEntries(
|
|
287
|
+
this.parameters.list
|
|
288
|
+
.filter(param => !!param.name)
|
|
289
|
+
.map(param => [param.name, true])
|
|
290
|
+
)
|
|
291
|
+
for (const [key, value] of Object.entries(params)) {
|
|
292
|
+
if (!consumedNames[key]) {
|
|
293
|
+
filtered[key] = value
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return filtered
|
|
297
|
+
}
|
|
298
|
+
|
|
266
299
|
coerceValue(type, value, modelOptions) {
|
|
267
300
|
// See if param needs additional coercion:
|
|
268
301
|
if (value && ['date', 'datetime', 'timestamp'].includes(type)) {
|