@ditojs/server 1.20.1 → 1.22.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.20.1",
3
+ "version": "1.22.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,23 +25,23 @@
25
25
  "node >= 18"
26
26
  ],
27
27
  "dependencies": {
28
- "@ditojs/admin": "^1.20.1",
29
- "@ditojs/build": "^1.20.0",
30
- "@ditojs/router": "^1.20.0",
31
- "@ditojs/utils": "^1.20.0",
28
+ "@ditojs/admin": "^1.22.0",
29
+ "@ditojs/build": "^1.22.0",
30
+ "@ditojs/router": "^1.22.0",
31
+ "@ditojs/utils": "^1.22.0",
32
32
  "@koa/cors": "^4.0.0",
33
33
  "@koa/multer": "^3.0.2",
34
34
  "@originjs/vite-plugin-commonjs": "^1.0.3",
35
- "ajv": "^8.11.2",
35
+ "ajv": "^8.12.0",
36
36
  "ajv-formats": "^2.1.1",
37
37
  "bcryptjs": "^2.4.3",
38
38
  "bytes": "^3.1.2",
39
- "data-uri-to-buffer": "^4.0.0",
39
+ "data-uri-to-buffer": "^4.0.1",
40
40
  "eventemitter2": "^6.4.9",
41
- "file-type": "^18.0.0",
41
+ "file-type": "^18.2.0",
42
42
  "image-size": "^1.0.2",
43
43
  "is-svg": "^4.3.2",
44
- "koa": "^2.14.0",
44
+ "koa": "^2.14.1",
45
45
  "koa-bodyparser": "^4.3.0",
46
46
  "koa-compose": "^4.1.0",
47
47
  "koa-compress": "^5.1.0",
@@ -62,13 +62,13 @@
62
62
  "passthrough-counter": "^1.0.0",
63
63
  "picocolors": "^1.0.0",
64
64
  "picomatch": "^2.3.1",
65
- "pino": "^8.7.0",
65
+ "pino": "^8.8.0",
66
66
  "pino-pretty": "^9.1.1",
67
67
  "pluralize": "^8.0.0",
68
68
  "repl": "^0.1.3",
69
69
  "uuid": "^9.0.0",
70
- "vite": "^3.2.5",
71
- "vite-plugin-vue2": "^2.0.2",
70
+ "vite": "^4.0.4",
71
+ "vite-plugin-vue2": "^2.0.3",
72
72
  "vue": "^2.7.14",
73
73
  "vue-template-compiler": "^2.7.14"
74
74
  },
@@ -78,7 +78,7 @@
78
78
  "objection": "^3.0.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@aws-sdk/client-s3": "^3.224.0",
81
+ "@aws-sdk/client-s3": "^3.258.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.11",
91
- "knex": "^2.3.0",
90
+ "@types/node": "^18.11.18",
91
+ "knex": "^2.4.2",
92
92
  "objection": "^3.0.1",
93
- "type-fest": "^3.3.0",
94
- "typescript": "^4.9.3"
93
+ "type-fest": "^3.5.3",
94
+ "typescript": "^4.9.4"
95
95
  },
96
96
  "types": "types",
97
- "gitHead": "66013b5bf5ba7c216f950f39f311f56851de2821"
97
+ "gitHead": "e1693edb8bf18e074606a842f2f2bacc1d2856cb"
98
98
  }
@@ -6,8 +6,8 @@ import {
6
6
  ResponseError, ControllerError, AuthorizationError
7
7
  } from '../errors/index.js'
8
8
  import {
9
- getOwnProperty, getOwnKeys, getAllKeys, processHandlerParameters,
10
- describeFunction, formatJson, deprecate
9
+ getOwnProperty, getOwnKeys, getAllKeys, getInheritanceChain,
10
+ processHandlerParameters, describeFunction, formatJson, deprecate
11
11
  } from '../utils/index.js'
12
12
  import {
13
13
  isObject, isString, isArray, isBoolean, isFunction, asArray, equals,
@@ -34,7 +34,17 @@ export class Controller {
34
34
  // which sets up the actions and routes, and the custom `async initialize()`.
35
35
  // @overridable
36
36
  configure() {
37
- this._configureEmitter(this.hooks, {
37
+ const hooks = this.inheritValues('hooks')
38
+ // Collect callbacks from the full inheritance chain of the hooks, so that
39
+ // the callbacks from base classes are also run. And reverse the chain so
40
+ // that the base class callbacks are run first.
41
+ const chain = getInheritanceChain(hooks).reverse()
42
+ const events = Object.fromEntries(
43
+ Object.keys(hooks || {}).map(
44
+ event => [event, chain.map(hooks => hooks[event]).filter(Boolean)]
45
+ )
46
+ )
47
+ this._configureEmitter(events, {
38
48
  // Support wildcard hooks only on controllers:
39
49
  wildcard: true
40
50
  })
@@ -50,15 +50,22 @@ QueryParameters.register({
50
50
  order(query, key, value) {
51
51
  if (value) {
52
52
  for (const entry of asArray(value)) {
53
- const [propertyName, direction] = entry.trim().split(/\s+/)
53
+ const [propertyName, direction, nulls] = entry.trim().split(/\s+/)
54
54
  if (direction && !['asc', 'desc'].includes(direction)) {
55
55
  throw new QueryBuilderError(
56
56
  `Invalid order direction: '${direction}'.`
57
57
  )
58
58
  }
59
+ if (nulls && !['first', 'last'].includes(nulls)) {
60
+ throw new QueryBuilderError(
61
+ `Invalid nulls order: '${null}'.`
62
+ )
63
+ }
59
64
  const tableRef = query.tableRefFor(query.modelClass())
60
65
  const columnName = `${tableRef}.${propertyName}`
61
- if (direction) {
66
+ if (nulls) {
67
+ query.orderBy(columnName, direction, nulls)
68
+ } else if (direction) {
62
69
  query.orderBy(columnName, direction)
63
70
  } else {
64
71
  query.orderBy(columnName)
@@ -46,13 +46,24 @@ export function mergeAsReversedArrays(objects) {
46
46
  return res
47
47
  }
48
48
 
49
- export function setupPropertyInheritance(object, key, baseValue = null) {
50
- // Loops up the inheritance chain of object until the base object is met,
51
- // and sets up a related inheritance chain for the given property `key`.
52
- // At the end, the resulting value with proper inheritance is returned.
49
+ export function getInheritanceChain(object) {
50
+ // Returns an array of objects from the inheritance chain of `object`,
51
+ // starting with the object itself and ending at `Object.prototype`.
52
+ const chain = []
53
53
  let current = object
54
- while (current !== Object.prototype) {
55
- const parent = Object.getPrototypeOf(current)
54
+ while (current && current !== Object.prototype) {
55
+ chain.push(current)
56
+ current = Object.getPrototypeOf(current)
57
+ }
58
+ return chain
59
+ }
60
+
61
+ export function setupPropertyInheritance(object, key, baseValue = null) {
62
+ // Loops through the inheritance chain of `object` and sets up a related
63
+ // inheritance chain for the given property `key`. The resulting value with
64
+ // proper inheritance is returned.
65
+ let [current, ...parents] = getInheritanceChain(object)
66
+ for (const parent of parents) {
56
67
  if (current.hasOwnProperty(key)) {
57
68
  const value = current[key]
58
69
  const parentValue = parent[key] || baseValue
package/types/index.d.ts CHANGED
@@ -23,6 +23,7 @@ import koaResponseTime from 'koa-response-time'
23
23
  import koaSession from 'koa-session'
24
24
  import * as objection from 'objection'
25
25
  import { KnexSnakeCaseMappersFactory } from 'objection'
26
+ import { Logger } from 'pino'
26
27
  import {
27
28
  Class,
28
29
  ConditionalExcept,
@@ -32,7 +33,6 @@ import {
32
33
  SetReturnType
33
34
  } from 'type-fest'
34
35
  import { UserConfig } from 'vite'
35
- import { Logger } from 'pino'
36
36
 
37
37
  export type Page<$Model extends Model = Model> = {
38
38
  total: number
@@ -870,9 +870,19 @@ export class Controller {
870
870
  authorize?: Authorize
871
871
  actions?: ControllerActions<this>
872
872
 
873
+ /**
874
+ * `configure()` is called right after the constructor, but before `setup()`
875
+ * which sets up the actions and routes, and the custom `async initialize()`.
876
+ * @overridable
877
+ */
873
878
  configure(): void
879
+ /* @overridable */
874
880
  setup(): void
875
- initialize(): void
881
+ /**
882
+ * To be overridden in sub-classes, if the controller needs to initialize.
883
+ * @overridable
884
+ */
885
+ initialize(): Promise<void>
876
886
  // TODO: type reflectActionsObject
877
887
  reflectActionsObject(): any
878
888
  setupRoute<$ControllerAction extends ControllerAction = ControllerAction>(
@@ -893,6 +903,11 @@ export class Controller {
893
903
  authorize: Authorize
894
904
  ): void
895
905
 
906
+ /**
907
+ * To be overridden in sub-classes, if the controller needs to install
908
+ * middleware.
909
+ * @overridable
910
+ */
896
911
  compose(): Parameters<typeof mount>[1]
897
912
  /** To be overridden by sub-classes. */
898
913
  getPath(type: string, path: string): string
@@ -1439,8 +1454,14 @@ export type QueryParameterOptionKey = keyof QueryParameterOptions
1439
1454
  export class Service {
1440
1455
  constructor(app: Application<Models>, name?: string)
1441
1456
  setup(config: any): void
1442
- initialize(): void
1457
+ /**
1458
+ * To be overridden in sub-classes, if the service needs to initialize.
1459
+ * @overridable
1460
+ */
1461
+ initialize(): Promise<void>
1462
+ /* @overridable */
1443
1463
  start(): Promise<void>
1464
+ /* @overridable */
1444
1465
  stop(): Promise<void>
1445
1466
  get logger(): Logger
1446
1467
  getLogger(ctx: KoaContext): Logger