@ditojs/server 1.14.3 → 1.15.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": "1.14.3",
3
+ "version": "1.15.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": "^1.14.1",
28
+ "@ditojs/admin": "^1.15.0",
29
29
  "@ditojs/build": "^1.14.0",
30
- "@ditojs/router": "^1.14.0",
31
- "@ditojs/utils": "^1.14.0",
30
+ "@ditojs/router": "^1.15.0",
31
+ "@ditojs/utils": "^1.15.0",
32
32
  "@koa/cors": "^4.0.0",
33
33
  "@koa/multer": "^3.0.2",
34
34
  "@originjs/vite-plugin-commonjs": "^1.0.3",
@@ -78,7 +78,7 @@
78
78
  "objection": "^3.0.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@aws-sdk/client-s3": "^3.200.0",
81
+ "@aws-sdk/client-s3": "^3.223.0",
82
82
  "@types/koa-bodyparser": "^4.3.10",
83
83
  "@types/koa-compress": "^4.0.3",
84
84
  "@types/koa-logger": "^3.1.2",
@@ -87,12 +87,12 @@
87
87
  "@types/koa-session": "^5.10.6",
88
88
  "@types/koa-static": "^4.0.2",
89
89
  "@types/koa__cors": "^3.3.0",
90
- "@types/node": "^18.11.9",
90
+ "@types/node": "^18.11.10",
91
91
  "knex": "^2.3.0",
92
92
  "objection": "^3.0.1",
93
- "type-fest": "^3.2.0",
93
+ "type-fest": "^3.3.0",
94
94
  "typescript": "^4.9.3"
95
95
  },
96
96
  "types": "types",
97
- "gitHead": "cedf7eb2a28bb051ef194fc9b29205681e390ef9"
97
+ "gitHead": "848aed21b94e81ac68f089c4a6bd335b1a97073d"
98
98
  }
@@ -289,12 +289,11 @@ export class Application extends Koa {
289
289
  data.schema = modelClass.getJsonSchema()
290
290
  }
291
291
  if (shouldLog(log.relations)) {
292
- data.relations = clone(
293
- modelClass.getRelationMappings(),
294
- value => Model.isPrototypeOf(value)
292
+ data.relations = clone(modelClass.getRelationMappings(), {
293
+ processValue: value => Model.isPrototypeOf(value)
295
294
  ? `[Model: ${value.name}]`
296
295
  : value
297
- )
296
+ })
298
297
  }
299
298
  if (Object.keys(data).length > 0) {
300
299
  console.info(
@@ -690,21 +689,13 @@ export class Application extends Koa {
690
689
  }
691
690
 
692
691
  formatError(error) {
693
- // Clone the error to be able to delete hidden properties.
694
- const copy = clone(error)
692
+ // Shallow-clone the error to be able to delete hidden properties.
693
+ const copy = clone(error, { shallow: true })
695
694
  // Remove headers added by the CORS middleware.
696
695
  delete copy.headers
697
696
  if (this.config.log.errors?.stack === false) {
698
697
  delete copy.stack
699
698
  delete copy.cause
700
- } else {
701
- // These aren't enumerable and thus couldn't be cloned above.
702
- if (error.stack !== undefined) {
703
- copy.stack = error.stack
704
- }
705
- if (error.cause !== undefined) {
706
- copy.cause = error.cause
707
- }
708
699
  }
709
700
  // Use `util.inspect()` instead of Pino's internal error logging for better
710
701
  // stack traces and logging of error data.
@@ -153,27 +153,29 @@ export class Validator extends objection.Validator {
153
153
 
154
154
  processSchema(jsonSchema, options = {}) {
155
155
  const { patch, async } = options
156
- const schema = clone(jsonSchema, value => {
157
- if (isObject(value)) {
158
- if (patch) {
159
- // Remove all required keywords and formats from schema for patch
160
- // validation.
161
- delete value.required
162
- if (value.format === 'required') {
163
- delete value.format
156
+ const schema = clone(jsonSchema, {
157
+ processValue: value => {
158
+ if (isObject(value)) {
159
+ if (patch) {
160
+ // Remove all required keywords and formats from schema for patch
161
+ // validation.
162
+ delete value.required
163
+ if (value.format === 'required') {
164
+ delete value.format
165
+ }
164
166
  }
165
- }
166
- // Convert async `validate()` keywords to `validateAsync()`:
167
- if (isAsync(value.validate)) {
168
- value.validateAsync = value.validate
169
- delete value.validate
170
- }
171
- if (!async) {
172
- // Remove all async keywords for synchronous validation.
173
- for (const key in value) {
174
- const keyword = this.getKeyword(key)
175
- if (keyword?.async) {
176
- delete value[key]
167
+ // Convert async `validate()` keywords to `validateAsync()`:
168
+ if (isAsync(value.validate)) {
169
+ value.validateAsync = value.validate
170
+ delete value.validate
171
+ }
172
+ if (!async) {
173
+ // Remove all async keywords for synchronous validation.
174
+ for (const key in value) {
175
+ const keyword = this.getKeyword(key)
176
+ if (keyword?.async) {
177
+ delete value[key]
178
+ }
177
179
  }
178
180
  }
179
181
  }
@@ -5,17 +5,17 @@ export class RelationError extends ResponseError {
5
5
  super(
6
6
  error,
7
7
  { message: 'Relation error', status: 400 },
8
- error instanceof Error ? getParsedOverrides(error) : null
8
+ error instanceof Error ? getFormattedOverrides(error) : null
9
9
  )
10
10
  }
11
11
  }
12
12
 
13
- function getParsedOverrides(error) {
13
+ function getFormattedOverrides(error) {
14
14
  // Adjust Objection.js error messages to point to the right property.
15
- const parse = str => str?.replace(/\brelationMappings\b/g, 'relations')
15
+ const format = str => str?.replace(/\brelationMappings\b/g, 'relations')
16
16
  const { message, stack } = error
17
17
  return {
18
- message: parse(message),
19
- stack: parse(stack)
18
+ message: format(message),
19
+ stack: format(stack)
20
20
  }
21
21
  }
@@ -21,6 +21,7 @@ export class ResponseError extends Error {
21
21
  super(message, cause ? { cause } : {})
22
22
  this.status = status
23
23
  this.data = data
24
+ // Allow `stack` overrides, e.g. for `RelationError`.
24
25
  if (stack != null) {
25
26
  this.stack = stack
26
27
  }
@@ -36,8 +37,11 @@ export class ResponseError extends Error {
36
37
  }
37
38
 
38
39
  function getErrorObject(error) {
39
- // For generic errors, explicitly copy message.
40
- const object = error.toJSON?.() ?? { message: error.message }
40
+ const object = {
41
+ // For generic errors, explicitly copy message.
42
+ message: error.message,
43
+ ...error.toJSON?.()
44
+ }
41
45
  // Additionally copy status and code if present.
42
46
  if (error.status != null) {
43
47
  object.status = error.status
@@ -45,8 +49,6 @@ function getErrorObject(error) {
45
49
  if (error.code != null) {
46
50
  object.code = error.code
47
51
  }
48
- // Preserve the cause if already set in the original error, and set it to the
49
- // error itself otherwise.
50
- object.cause = error.cause ?? error
52
+ object.cause = error
51
53
  return object
52
54
  }
@@ -180,7 +180,7 @@ export class Model extends objection.Model {
180
180
  const shallow = json.$isObjectionModel && !options.graph
181
181
  if (shallow) {
182
182
  // Strip away relations and other internal stuff.
183
- json = json.clone({ shallow: true })
183
+ json = json.$clone({ shallow: true })
184
184
  // We can mutate `json` now that we took a copy of it.
185
185
  options = { ...options, mutable: true }
186
186
  }