@ditojs/server 2.51.0 → 2.51.2

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.51.0",
3
+ "version": "2.51.2",
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",
@@ -26,10 +26,10 @@
26
26
  "node >= 18"
27
27
  ],
28
28
  "dependencies": {
29
- "@ditojs/admin": "^2.51.0",
30
- "@ditojs/build": "^2.51.0",
31
- "@ditojs/router": "^2.51.0",
32
- "@ditojs/utils": "^2.51.0",
29
+ "@ditojs/admin": "^2.51.2",
30
+ "@ditojs/build": "^2.51.2",
31
+ "@ditojs/router": "^2.51.2",
32
+ "@ditojs/utils": "^2.51.2",
33
33
  "@koa/cors": "^5.0.0",
34
34
  "@koa/multer": "^3.1.0",
35
35
  "@originjs/vite-plugin-commonjs": "^1.0.3",
@@ -90,5 +90,5 @@
90
90
  "objection": "^3.1.5",
91
91
  "typescript": "^5.8.3"
92
92
  },
93
- "gitHead": "0b8f114647510db71c50be9fdc331297b1e726ab"
93
+ "gitHead": "6df9c1bdbf04e6d4e58f53cab7ad2475fbb08161"
94
94
  }
@@ -788,6 +788,9 @@ export class Application extends Koa {
788
788
  if (this.config.log.errors?.stack === false) {
789
789
  delete copy.stack
790
790
  delete copy.cause
791
+ } else {
792
+ // Explicitly copy the stack trace, as clone() might not copy it.
793
+ copy.stack = error.stack
791
794
  }
792
795
  // Use `util.inspect()` instead of Pino's internal error logging for better
793
796
  // stack traces and logging of error data.
@@ -96,20 +96,18 @@ export class Validator extends objection.Validator {
96
96
  getAjv(options = {}) {
97
97
  // Cache Ajv instances by keys that represent their options. For improved
98
98
  // matching, convert options to a version with all default values missing:
99
- const opts = Object.entries(options).reduce((opts, [key, value]) => {
100
- if (key in validatorOptions && value !== validatorOptions[key]) {
101
- opts[key] = value
102
- }
103
- return opts
104
- }, {})
105
- const cacheKey = formatJson(opts, false)
106
- const { ajv } = (
107
- this.ajvCache[cacheKey] ||
108
- (this.ajvCache[cacheKey] = {
109
- ajv: this.createAjv(opts),
110
- options
111
- })
99
+ const filteredOptions = Object.fromEntries(
100
+ Object.entries(options).filter(
101
+ ([key, value]) => (
102
+ key in validatorOptions && value !== validatorOptions[key]
103
+ )
104
+ )
112
105
  )
106
+ const cacheKey = formatJson(filteredOptions, false)
107
+ const { ajv } = (this.ajvCache[cacheKey] ??= {
108
+ ajv: this.createAjv(filteredOptions),
109
+ options: filteredOptions
110
+ })
113
111
  return ajv
114
112
  }
115
113
 
@@ -205,6 +203,9 @@ export class Validator extends objection.Validator {
205
203
  })
206
204
  if (async) {
207
205
  schema.$async = true
206
+ for (const definition of Object.values(schema.definitions || {})) {
207
+ definition.$async = true
208
+ }
208
209
  }
209
210
  return schema
210
211
  }
@@ -1,11 +1,5 @@
1
- import {
2
- isString,
3
- isObject,
4
- asArray,
5
- clone,
6
- convertToJson,
7
- deprecate
8
- } from '@ditojs/utils'
1
+ import { isString, isObject, asArray, clone, deprecate } from '@ditojs/utils'
2
+ import { convertModelsToJson } from '../utils/model.js'
9
3
 
10
4
  export default class ControllerAction {
11
5
  constructor(
@@ -126,11 +120,11 @@ export default class ControllerAction {
126
120
  await this.controller.emitHook(`before:${identifier}`, false, ctx, ...args)
127
121
  const response = await this.callHandler(ctx, ...args)
128
122
  const result =
129
- // Don't convert response to JSON if it isn't being validated (e.g. useful
130
- // for streams or buffers), or if the response contains model references.
123
+ // Don't convert response to JSON if it isn't being validated, or if the
124
+ // response validation schema contains model references.
131
125
  !this.response.validate || this.response.hasModelRefs
132
126
  ? response
133
- : convertToJson(response)
127
+ : convertModelsToJson(response)
134
128
  return this.validateResponse(
135
129
  await this.controller.emitHook(`after:${identifier}`, true, ctx, result)
136
130
  )
@@ -0,0 +1,35 @@
1
+ import { isArray, isPlainObject } from '@ditojs/utils'
2
+
3
+ /**
4
+ * Converts Models to their external representation by calling the `$toJson()`
5
+ * method. It does not create a JSON string, but a plain object. It is necessary
6
+ * to do this before the validation is performed, otherwise different properties
7
+ * might end up in the Json response. This is done recursively, so that nested
8
+ * models are also converted. Streams, Buffers and other non plain objects are
9
+ * left as-is, so this can directly be used on any results.
10
+ */
11
+ export function convertModelsToJson(value) {
12
+ return value?.$isObjectionModel
13
+ ? value.$toJson()
14
+ : isPlainObject(value)
15
+ ? convertToJsonObject(value)
16
+ : isArray(value)
17
+ ? convertToJsonArray(value)
18
+ : value
19
+ }
20
+
21
+ function convertToJsonObject(value) {
22
+ const object = {}
23
+ for (const key of Object.keys(value)) {
24
+ object[key] = convertModelsToJson(value[key])
25
+ }
26
+ return object
27
+ }
28
+
29
+ function convertToJsonArray(value) {
30
+ const array = new Array(value.length)
31
+ for (let i = 0, l = value.length; i < l; ++i) {
32
+ array[i] = convertModelsToJson(value[i])
33
+ }
34
+ return array
35
+ }