@ditojs/server 2.32.4 → 2.33.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.32.4",
3
+ "version": "2.33.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",
@@ -25,10 +25,10 @@
25
25
  "node >= 18"
26
26
  ],
27
27
  "dependencies": {
28
- "@ditojs/admin": "^2.32.2",
29
- "@ditojs/build": "^2.32.2",
30
- "@ditojs/router": "^2.32.2",
31
- "@ditojs/utils": "^2.32.2",
28
+ "@ditojs/admin": "^2.33.0",
29
+ "@ditojs/build": "^2.33.0",
30
+ "@ditojs/router": "^2.33.0",
31
+ "@ditojs/utils": "^2.33.0",
32
32
  "@koa/cors": "^5.0.0",
33
33
  "@koa/multer": "^3.0.2",
34
34
  "@originjs/vite-plugin-commonjs": "^1.0.3",
@@ -93,5 +93,5 @@
93
93
  "typescript": "^5.6.2"
94
94
  },
95
95
  "types": "types",
96
- "gitHead": "03eb23669c49ac537812d8508ad8966d19855838"
96
+ "gitHead": "be8095460cbe9c035d10c994a1e1f89d9d5fbefe"
97
97
  }
@@ -96,13 +96,13 @@ export default class ControllerAction {
96
96
  }
97
97
 
98
98
  async callAction(ctx) {
99
- const params = await this.validateParameters(ctx)
99
+ const { params, wrapped } = await this.validateParameters(ctx)
100
100
  const { args, member } = await this.collectArguments(ctx, params)
101
101
  let filteredQuery = null
102
102
  Object.defineProperty(ctx, 'filteredQuery', {
103
103
  get: () => {
104
104
  filteredQuery ??=
105
- params && this.paramsName === 'query'
105
+ params && !wrapped && this.paramsName === 'query'
106
106
  ? this.filterParameters(params)
107
107
  : ctx.query
108
108
  return filteredQuery
@@ -129,13 +129,10 @@ export default class ControllerAction {
129
129
 
130
130
  async validateParameters(ctx) {
131
131
  if (!this.parameters.validate) {
132
- return null
132
+ return { params: null, wrapped: false }
133
133
  }
134
- // Since validation also performs coercion, create a shallow clone of the
135
- // params so that this doesn't modify the data on `ctx`.Actually used values
136
- // themselves are deep cloned below.
137
134
  // NOTE: The data can be either an object or an array.
138
- const data = { ...this.getParams(ctx) }
135
+ const data = this.getParams(ctx)
139
136
  let params = {}
140
137
  const { dataName } = this.parameters
141
138
  let unwrapRoot = false
@@ -143,12 +140,11 @@ export default class ControllerAction {
143
140
  for (const {
144
141
  name, // String: Property name to fetch from data. Overridable by `root`
145
142
  type, // String: What type should this validated against / coerced to.
146
- from, // String: Allow parameters to be 'borrowed' from other objects.
147
- root, // Boolean: Use full root object, instead of data at given property.
148
- member // Boolean: Fetch member instance instead of data from request.
143
+ from // String: Allow parameters to be 'borrowed' from other objects.
149
144
  } of this.parameters.list) {
150
145
  // Don't validate member parameters as they get resolved separately after.
151
- if (member) continue
146
+ if (from === 'member') continue
147
+ const root = from === 'root'
152
148
  let wrapRoot = root
153
149
  let paramName = name
154
150
  // If no name is provided, wrap the full root object as value and unwrap
@@ -158,22 +154,23 @@ export default class ControllerAction {
158
154
  wrapRoot = true
159
155
  unwrapRoot = true
160
156
  }
161
- if (wrapRoot) {
157
+ // Since validation also performs coercion, always create clones of the
158
+ // params so that this doesn't modify the data on `ctx`.
159
+ if (from && !root) {
160
+ // Allow parameters to be 'borrowed' from other objects.
161
+ const source = this.getParams(ctx, from)
162
+ // See above for an explanation of `clone()`:
163
+ params[paramName] = clone(wrapRoot ? source : source?.[paramName])
164
+ } else if (wrapRoot) {
162
165
  // If root is to be used, replace `params` with a new object on which
163
166
  // to set the root object to validate under `parameters.paramName`
164
167
  if (params === data) {
165
168
  params = {}
166
169
  }
167
- params[paramName] = data
170
+ params[paramName] = clone(data)
168
171
  } else {
169
172
  params[paramName] = clone(data[paramName])
170
173
  }
171
- if (from) {
172
- // Allow parameters to be 'borrowed' from other objects.
173
- const source = this.getParams(ctx, from)
174
- // See above for an explanation of `clone()`:
175
- params[paramName] = clone(wrapRoot ? source : source?.[paramName])
176
- }
177
174
  try {
178
175
  const value = params[paramName]
179
176
  // `parameters.validate(params)` coerces data in the query to the
@@ -203,7 +200,8 @@ export default class ControllerAction {
203
200
  const getData = () => (unwrapRoot ? params[dataName] : params)
204
201
  try {
205
202
  await this.parameters.validate(params)
206
- return getData()
203
+ const data = getData()
204
+ return { params: data, wrapped: data !== params }
207
205
  } catch (error) {
208
206
  if (error.errors) {
209
207
  errors.push(...error.errors)
@@ -264,10 +262,10 @@ export default class ControllerAction {
264
262
  // If we have parameters, add them to the arguments now,
265
263
  // while also keeping track of consumed parameters:
266
264
  for (const param of list) {
267
- const { name } = param
268
- // Handle `{ member: true }` parameters separately, by delegating to
265
+ const { name, from } = param
266
+ // Handle `{ from: 'member' }` parameters separately, by delegating to
269
267
  // `getMember()` to resolve to the given member.
270
- if (param.member) {
268
+ if (from === 'member') {
271
269
  member = await this.getMember(ctx, param)
272
270
  addArgument(name, member)
273
271
  } else {
@@ -12,14 +12,14 @@ export default class MemberAction extends ControllerAction {
12
12
  // member parameters can provide special query parameters as well,
13
13
  // and they can even control `forUpdate()` behavior:
14
14
  // {
15
- // member: true,
15
+ // from: 'member',
16
16
  // query: { ... },
17
17
  // forUpdate: true,
18
18
  // modify: query => query.debug()
19
19
  // }
20
20
  // These are passed on to and handled in `CollectionController#getMember()`.
21
- // For handling of `member: true` and calling of `MemberAction.getMember()`,
22
- // see `ControllerAction#collectArguments()`.
21
+ // For handling of `from: 'member'` and calling of
22
+ // `MemberAction.getMember()`, see `ControllerAction#collectArguments()`.
23
23
  // Pass on `this.handler` as `base` for `setupQuery()`,
24
24
  // to handle the setting of `handler.scope` & co. on the query.
25
25
  return this.controller.getMember(ctx, this.handler, param)
package/types/index.d.ts CHANGED
@@ -1010,7 +1010,7 @@ export type ModelControllerActionOptions<
1010
1010
  export type MemberActionParameter<$Model extends Model = Model> =
1011
1011
  | Schema
1012
1012
  | {
1013
- member: true
1013
+ from: 'member'
1014
1014
 
1015
1015
  /** Sets ctx.query. */
1016
1016
  query?: Record<string, any>