@ditojs/server 0.273.0 → 1.0.0-rc.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.
Files changed (222) hide show
  1. package/package.json +26 -44
  2. package/src/app/Application.js +121 -117
  3. package/src/app/Validator.js +6 -3
  4. package/src/app/index.js +2 -2
  5. package/src/cli/console.js +3 -3
  6. package/src/cli/db/createMigration.js +4 -4
  7. package/src/cli/db/index.js +7 -7
  8. package/src/cli/db/listAssetConfig.js +1 -1
  9. package/src/cli/db/migrate.js +4 -4
  10. package/src/cli/db/reset.js +5 -5
  11. package/src/cli/db/rollback.js +4 -4
  12. package/src/cli/db/seed.js +6 -6
  13. package/src/cli/db/unlock.js +2 -2
  14. package/src/cli/index.js +17 -8
  15. package/src/controllers/AdminController.js +164 -158
  16. package/src/controllers/CollectionController.js +8 -29
  17. package/src/controllers/Controller.js +78 -83
  18. package/src/controllers/ControllerAction.js +37 -18
  19. package/src/controllers/MemberAction.js +2 -2
  20. package/src/controllers/ModelController.js +4 -4
  21. package/src/controllers/RelationController.js +5 -5
  22. package/src/controllers/{UserController.js → UsersController.js} +8 -13
  23. package/src/controllers/index.js +5 -5
  24. package/src/decorators/action.js +3 -3
  25. package/src/decorators/authorize.js +1 -1
  26. package/src/decorators/index.js +6 -6
  27. package/src/decorators/parameters.js +1 -1
  28. package/src/decorators/returns.js +1 -1
  29. package/src/decorators/scope.js +1 -1
  30. package/src/decorators/transacted.js +1 -1
  31. package/src/errors/AssetError.js +1 -1
  32. package/src/errors/AuthenticationError.js +1 -1
  33. package/src/errors/AuthorizationError.js +1 -1
  34. package/src/errors/ControllerError.js +1 -1
  35. package/src/errors/DatabaseError.js +12 -3
  36. package/src/errors/GraphError.js +1 -1
  37. package/src/errors/ModelError.js +1 -1
  38. package/src/errors/NotFoundError.js +1 -1
  39. package/src/errors/NotImplementedError.js +1 -1
  40. package/src/errors/QueryBuilderError.js +1 -1
  41. package/src/errors/RelationError.js +1 -1
  42. package/src/errors/ValidationError.js +1 -1
  43. package/src/errors/WrappedError.js +1 -1
  44. package/src/errors/index.js +14 -14
  45. package/src/graph/DitoGraphProcessor.js +2 -1
  46. package/src/graph/graph.js +1 -1
  47. package/src/graph/index.js +3 -3
  48. package/src/index.js +11 -9
  49. package/src/lib/index.js +2 -2
  50. package/src/middleware/createTransaction.js +1 -1
  51. package/src/middleware/findRoute.js +3 -2
  52. package/src/middleware/handleConnectMiddleware.js +88 -0
  53. package/src/middleware/handleError.js +1 -1
  54. package/src/middleware/handleRoute.js +3 -3
  55. package/src/middleware/index.js +8 -7
  56. package/src/middleware/logRequests.js +9 -9
  57. package/src/mixins/AssetMixin.js +1 -1
  58. package/src/mixins/UserMixin.js +1 -1
  59. package/src/mixins/index.js +4 -4
  60. package/src/models/AssetModel.js +2 -2
  61. package/src/models/Model.js +16 -12
  62. package/src/models/RelationAccessor.js +1 -1
  63. package/src/models/SessionModel.js +2 -2
  64. package/src/models/TimeStampedModel.js +2 -2
  65. package/src/models/UserModel.js +2 -2
  66. package/src/models/definitions/assets.js +1 -1
  67. package/src/models/definitions/filters.js +57 -44
  68. package/src/models/definitions/hooks.js +1 -1
  69. package/src/models/definitions/index.js +9 -9
  70. package/src/models/definitions/modifiers.js +1 -1
  71. package/src/models/definitions/options.js +1 -1
  72. package/src/models/definitions/properties.js +2 -2
  73. package/src/models/definitions/relations.js +1 -1
  74. package/src/models/definitions/schema.js +1 -1
  75. package/src/models/definitions/scopes.js +2 -2
  76. package/src/models/index.js +5 -5
  77. package/src/query/QueryBuilder.js +5 -5
  78. package/src/query/QueryFilters.js +50 -50
  79. package/src/query/QueryParameters.js +2 -2
  80. package/src/query/index.js +3 -3
  81. package/src/schema/formats/index.js +2 -2
  82. package/src/schema/index.js +4 -4
  83. package/src/schema/keywords/_relate.js +1 -1
  84. package/src/schema/keywords/index.js +12 -12
  85. package/src/schema/properties.test.js +1 -1
  86. package/src/schema/relations.js +1 -1
  87. package/src/schema/relations.test.js +2 -2
  88. package/src/services/index.js +1 -1
  89. package/src/storage/DiskStorage.js +1 -1
  90. package/src/storage/S3Storage.js +4 -4
  91. package/src/storage/Storage.js +1 -1
  92. package/src/storage/index.js +4 -4
  93. package/src/utils/function.test.js +1 -1
  94. package/src/utils/handler.js +17 -0
  95. package/src/utils/index.js +8 -7
  96. package/src/utils/object.test.js +1 -1
  97. package/lib/app/Application.js +0 -955
  98. package/lib/app/SessionStore.js +0 -40
  99. package/lib/app/Validator.js +0 -355
  100. package/lib/app/index.js +0 -26
  101. package/lib/cli/console.js +0 -175
  102. package/lib/cli/db/createMigration.js +0 -237
  103. package/lib/cli/db/index.js +0 -66
  104. package/lib/cli/db/listAssetConfig.js +0 -16
  105. package/lib/cli/db/migrate.js +0 -15
  106. package/lib/cli/db/reset.js +0 -27
  107. package/lib/cli/db/rollback.js +0 -15
  108. package/lib/cli/db/seed.js +0 -104
  109. package/lib/cli/db/unlock.js +0 -15
  110. package/lib/cli/index.js +0 -90
  111. package/lib/controllers/AdminController.js +0 -258
  112. package/lib/controllers/CollectionController.js +0 -263
  113. package/lib/controllers/Controller.js +0 -462
  114. package/lib/controllers/ControllerAction.js +0 -276
  115. package/lib/controllers/MemberAction.js +0 -22
  116. package/lib/controllers/ModelController.js +0 -64
  117. package/lib/controllers/RelationController.js +0 -82
  118. package/lib/controllers/UserController.js +0 -98
  119. package/lib/controllers/index.js +0 -50
  120. package/lib/decorators/action.js +0 -14
  121. package/lib/decorators/authorize.js +0 -13
  122. package/lib/decorators/index.js +0 -58
  123. package/lib/decorators/parameters.js +0 -35
  124. package/lib/decorators/returns.js +0 -26
  125. package/lib/decorators/scope.js +0 -14
  126. package/lib/decorators/transacted.js +0 -12
  127. package/lib/errors/AssetError.js +0 -19
  128. package/lib/errors/AuthenticationError.js +0 -19
  129. package/lib/errors/AuthorizationError.js +0 -19
  130. package/lib/errors/ControllerError.js +0 -24
  131. package/lib/errors/DatabaseError.js +0 -27
  132. package/lib/errors/GraphError.js +0 -19
  133. package/lib/errors/ModelError.js +0 -24
  134. package/lib/errors/NotFoundError.js +0 -19
  135. package/lib/errors/NotImplementedError.js +0 -19
  136. package/lib/errors/QueryBuilderError.js +0 -19
  137. package/lib/errors/RelationError.js +0 -36
  138. package/lib/errors/ResponseError.js +0 -46
  139. package/lib/errors/ValidationError.js +0 -19
  140. package/lib/errors/WrappedError.js +0 -24
  141. package/lib/errors/index.js +0 -122
  142. package/lib/graph/DitoGraphProcessor.js +0 -185
  143. package/lib/graph/expression.js +0 -76
  144. package/lib/graph/graph.js +0 -300
  145. package/lib/graph/index.js +0 -34
  146. package/lib/index.js +0 -82
  147. package/lib/lib/EventEmitter.js +0 -76
  148. package/lib/lib/KnexHelper.js +0 -40
  149. package/lib/lib/index.js +0 -26
  150. package/lib/middleware/attachLogger.js +0 -16
  151. package/lib/middleware/createTransaction.js +0 -36
  152. package/lib/middleware/findRoute.js +0 -35
  153. package/lib/middleware/handleError.js +0 -26
  154. package/lib/middleware/handleRoute.js +0 -29
  155. package/lib/middleware/handleUser.js +0 -36
  156. package/lib/middleware/index.js +0 -66
  157. package/lib/middleware/logRequests.js +0 -122
  158. package/lib/mixins/AssetMixin.js +0 -81
  159. package/lib/mixins/SessionMixin.js +0 -22
  160. package/lib/mixins/TimeStampedMixin.js +0 -47
  161. package/lib/mixins/UserMixin.js +0 -151
  162. package/lib/mixins/index.js +0 -42
  163. package/lib/models/AssetModel.js +0 -12
  164. package/lib/models/Model.js +0 -953
  165. package/lib/models/RelationAccessor.js +0 -41
  166. package/lib/models/SessionModel.js +0 -12
  167. package/lib/models/TimeStampedModel.js +0 -12
  168. package/lib/models/UserModel.js +0 -12
  169. package/lib/models/definitions/assets.js +0 -11
  170. package/lib/models/definitions/filters.js +0 -101
  171. package/lib/models/definitions/hooks.js +0 -11
  172. package/lib/models/definitions/index.js +0 -38
  173. package/lib/models/definitions/modifiers.js +0 -11
  174. package/lib/models/definitions/options.js +0 -11
  175. package/lib/models/definitions/properties.js +0 -87
  176. package/lib/models/definitions/relations.js +0 -11
  177. package/lib/models/definitions/schema.js +0 -11
  178. package/lib/models/definitions/scopes.js +0 -51
  179. package/lib/models/index.js +0 -50
  180. package/lib/query/QueryBuilder.js +0 -745
  181. package/lib/query/QueryFilters.js +0 -82
  182. package/lib/query/QueryParameters.js +0 -77
  183. package/lib/query/Registry.js +0 -40
  184. package/lib/query/index.js +0 -34
  185. package/lib/schema/formats/_empty.js +0 -10
  186. package/lib/schema/formats/_required.js +0 -10
  187. package/lib/schema/formats/index.js +0 -26
  188. package/lib/schema/index.js +0 -49
  189. package/lib/schema/keywords/_computed.js +0 -11
  190. package/lib/schema/keywords/_foreign.js +0 -11
  191. package/lib/schema/keywords/_hidden.js +0 -11
  192. package/lib/schema/keywords/_index.js +0 -11
  193. package/lib/schema/keywords/_instanceof.js +0 -49
  194. package/lib/schema/keywords/_primary.js +0 -11
  195. package/lib/schema/keywords/_range.js +0 -26
  196. package/lib/schema/keywords/_relate.js +0 -19
  197. package/lib/schema/keywords/_specificType.js +0 -11
  198. package/lib/schema/keywords/_unique.js +0 -11
  199. package/lib/schema/keywords/_unsigned.js +0 -11
  200. package/lib/schema/keywords/_validate.js +0 -80
  201. package/lib/schema/keywords/index.js +0 -106
  202. package/lib/schema/properties.js +0 -227
  203. package/lib/schema/properties.test.js +0 -573
  204. package/lib/schema/relations.js +0 -274
  205. package/lib/schema/relations.test.js +0 -155
  206. package/lib/services/Service.js +0 -34
  207. package/lib/services/index.js +0 -18
  208. package/lib/storage/AssetFile.js +0 -97
  209. package/lib/storage/DiskStorage.js +0 -125
  210. package/lib/storage/S3Storage.js +0 -171
  211. package/lib/storage/Storage.js +0 -209
  212. package/lib/storage/index.js +0 -34
  213. package/lib/utils/decorator.js +0 -16
  214. package/lib/utils/deprecate.js +0 -46
  215. package/lib/utils/emitter.js +0 -13
  216. package/lib/utils/function.js +0 -14
  217. package/lib/utils/function.test.js +0 -49
  218. package/lib/utils/index.js +0 -66
  219. package/lib/utils/json.js +0 -9
  220. package/lib/utils/object.js +0 -92
  221. package/lib/utils/object.test.js +0 -65
  222. package/lib/utils/scope.js +0 -14
@@ -1,4 +1,4 @@
1
- import { ResponseError } from './ResponseError'
1
+ import { ResponseError } from './ResponseError.js'
2
2
 
3
3
  export class WrappedError extends ResponseError {
4
4
  constructor(error, overrides, defaults = {
@@ -1,14 +1,14 @@
1
- export * from './AssetError'
2
- export * from './ResponseError'
3
- export * from './AuthenticationError'
4
- export * from './AuthorizationError'
5
- export * from './ControllerError'
6
- export * from './DatabaseError'
7
- export * from './GraphError'
8
- export * from './ModelError'
9
- export * from './NotFoundError'
10
- export * from './NotImplementedError'
11
- export * from './QueryBuilderError'
12
- export * from './RelationError'
13
- export * from './ValidationError'
14
- export * from './WrappedError'
1
+ export * from './AssetError.js'
2
+ export * from './ResponseError.js'
3
+ export * from './AuthenticationError.js'
4
+ export * from './AuthorizationError.js'
5
+ export * from './ControllerError.js'
6
+ export * from './DatabaseError.js'
7
+ export * from './GraphError.js'
8
+ export * from './ModelError.js'
9
+ export * from './NotFoundError.js'
10
+ export * from './NotImplementedError.js'
11
+ export * from './QueryBuilderError.js'
12
+ export * from './RelationError.js'
13
+ export * from './ValidationError.js'
14
+ export * from './WrappedError.js'
@@ -1,5 +1,6 @@
1
1
  import { isArray } from '@ditojs/utils'
2
- import { modelGraphToExpression, ensureModelArray } from '.'
2
+ import { ensureModelArray } from './graph.js'
3
+ import { modelGraphToExpression } from './expression.js'
3
4
 
4
5
  export class DitoGraphProcessor {
5
6
  constructor(rootModelClass, data, options = {}, settings = {}) {
@@ -1,5 +1,5 @@
1
1
  import { isObject, isArray, asArray } from '@ditojs/utils'
2
- import { QueryBuilder } from '@/query'
2
+ import { QueryBuilder } from '../query/index.js'
3
3
  import { collectExpressionPaths, expressionPathToString } from './expression.js'
4
4
 
5
5
  // Similar to Objection's private `modelClass.ensureModel(model)`:
@@ -1,3 +1,3 @@
1
- export * from './DitoGraphProcessor'
2
- export * from './graph'
3
- export * from './expression'
1
+ export * from './DitoGraphProcessor.js'
2
+ export * from './graph.js'
3
+ export * from './expression.js'
package/src/index.js CHANGED
@@ -1,9 +1,11 @@
1
- export * from './app'
2
- export * from './query'
3
- export * from './errors'
4
- export * from './mixins'
5
- export * from './models'
6
- export * from './controllers'
7
- export * from './services'
8
- export * from './decorators'
9
- export * from './storage'
1
+ export * from './app/index.js'
2
+ export * from './query/index.js'
3
+ export * from './schema/index.js'
4
+ export * from './errors/index.js'
5
+ export * from './mixins/index.js'
6
+ export * from './models/index.js'
7
+ export * from './controllers/index.js'
8
+ export * from './services/index.js'
9
+ export * from './decorators/index.js'
10
+ export * from './storage/index.js'
11
+ export * from './utils/index.js'
package/src/lib/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export * from './EventEmitter'
2
- export * from './KnexHelper'
1
+ export * from './EventEmitter.js'
2
+ export * from './KnexHelper.js'
@@ -1,5 +1,5 @@
1
1
  import { transaction } from 'objection'
2
- import { emitAsync } from '@/utils'
2
+ import { emitAsync } from '../utils/index.js'
3
3
 
4
4
  export function createTransaction() {
5
5
  return async (ctx, next) => {
@@ -1,8 +1,9 @@
1
1
  export function findRoute(router) {
2
2
  return (ctx, next) => {
3
3
  const result = router.find(ctx.method, ctx.path)
4
- // We use `result.handler` to store the route object for matched routes.
5
- // If none is found, set `ctx.route = result`, for `{ status, allowed }`.
4
+ // We use `result.handler` as returned from the router to store the route
5
+ // object for matched routes. If none is found, set `ctx.route = result`,
6
+ // for `{ status, allowed }`.
6
7
  const route = result.handler ? { ...result.handler } : result
7
8
  ctx.route = route
8
9
  // NOTE: The name for `ctx.params` was inherited from `koa-router`
@@ -0,0 +1,88 @@
1
+ import { PassThrough } from 'stream'
2
+ import { isString, isArray, isObject } from '@ditojs/utils'
3
+
4
+ export function handleConnectMiddleware(middleware, {
5
+ expandMountPath = false
6
+ }) {
7
+ return (ctx, next) => {
8
+ return new Promise(resolve => {
9
+ let body = null
10
+
11
+ const res = {
12
+ locals: ctx.state,
13
+
14
+ get statusCode() {
15
+ return ctx.status
16
+ },
17
+
18
+ set statusCode(status) {
19
+ ctx.status = status
20
+ },
21
+
22
+ getHeader(field) {
23
+ // console.log('getHeader', ...arguments)
24
+ return ctx.get(field)
25
+ },
26
+
27
+ setHeader(field, value) {
28
+ // console.log('setHeader', ...arguments)
29
+ ctx.set(field, value)
30
+ },
31
+
32
+ writeHead(status, message, headers) {
33
+ // console.log('writeHead', ...arguments)
34
+ ctx.status = status
35
+ if (isString(message)) {
36
+ ctx.body = message
37
+ } else {
38
+ headers = message
39
+ }
40
+ if (isArray(headers)) {
41
+ // Convert raw headers array to object.
42
+ headers = Object.fromEntries(headers.reduce(
43
+ // Translate raw array to [field, value] tuplets.
44
+ (entries, value, index) => {
45
+ if (index & 1) { // Odd: value
46
+ entries[entries.length - 1].push(value)
47
+ } else { // Even: field
48
+ entries.push([value])
49
+ }
50
+ return entries
51
+ }, []))
52
+ }
53
+ if (isObject(headers)) {
54
+ ctx.set(headers)
55
+ }
56
+ },
57
+
58
+ write(...args) {
59
+ // console.log('write', ...arguments)
60
+ if (!body) {
61
+ body = new PassThrough()
62
+ ctx.body = body
63
+ }
64
+ body.write(...args)
65
+ },
66
+
67
+ end(body) {
68
+ // console.log('end', body?.substring?.(0, 256))
69
+ if (body !== undefined) {
70
+ ctx.body = body
71
+ }
72
+ resolve()
73
+ }
74
+ }
75
+
76
+ if (expandMountPath && ctx.mountPath) {
77
+ // Create an inheriting `ctx` object with the expanded `ctx.path`,
78
+ // without actually modifying the original `ctx` object.
79
+ ctx = Object.create(ctx, {
80
+ path: {
81
+ value: ctx.mountPath + ctx.path
82
+ }
83
+ })
84
+ }
85
+ middleware(ctx.req, res, next)
86
+ })
87
+ }
88
+ }
@@ -1,4 +1,4 @@
1
- import { ResponseError } from '@/errors'
1
+ import { ResponseError } from '../errors/index.js'
2
2
 
3
3
  export function handleError() {
4
4
  return async (ctx, next) => {
@@ -1,8 +1,8 @@
1
1
  export function handleRoute() {
2
2
  return async (ctx, next) => {
3
- const { handler } = ctx.route
4
- if (handler) {
5
- await handler(ctx, next)
3
+ const { middleware } = ctx.route
4
+ if (middleware) {
5
+ await middleware(ctx, next)
6
6
  } else {
7
7
  // No route was found. See if the remaining middleware does something with
8
8
  // this request. If not, return the errors as received from the router:
@@ -1,7 +1,8 @@
1
- export * from './attachLogger'
2
- export * from './createTransaction'
3
- export * from './findRoute'
4
- export * from './handleError'
5
- export * from './handleRoute'
6
- export * from './handleUser'
7
- export * from './logRequests'
1
+ export * from './attachLogger.js'
2
+ export * from './createTransaction.js'
3
+ export * from './findRoute.js'
4
+ export * from './handleConnectMiddleware.js'
5
+ export * from './handleError.js'
6
+ export * from './handleRoute.js'
7
+ export * from './handleUser.js'
8
+ export * from './logRequests.js'
@@ -2,7 +2,7 @@
2
2
  * Middleware inspired by 'koa-logger'. Adapted and extended to our needs.
3
3
  */
4
4
  import bytes from 'bytes'
5
- import chalk from 'chalk'
5
+ import pico from 'picocolors'
6
6
  import Counter from 'passthrough-counter'
7
7
 
8
8
  export function logRequests({ ignoreUrls } = {}) {
@@ -58,11 +58,11 @@ function logRequest(ctx) {
58
58
  logger.trace(
59
59
  { req: ctx.req },
60
60
  `${
61
- chalk.gray('<--')
61
+ pico.gray('<--')
62
62
  } ${
63
- chalk.bold(ctx.method)
63
+ pico.bold(ctx.method)
64
64
  } ${
65
- chalk.gray(ctx.originalUrl)
65
+ pico.gray(ctx.originalUrl)
66
66
  }`
67
67
  )
68
68
  }
@@ -93,15 +93,15 @@ function logResponse({ ctx, start, length, err }) {
93
93
  logger[level](
94
94
  { req: ctx.req, res: ctx.res },
95
95
  `${
96
- chalk.bold(ctx.method)
96
+ pico.bold(ctx.method)
97
97
  } ${
98
- chalk.gray(ctx.originalUrl)
98
+ pico.gray(ctx.originalUrl)
99
99
  } ${
100
- chalk[statusColor](status)
100
+ pico[statusColor](status)
101
101
  } ${
102
- chalk.gray(formattedTime)
102
+ pico.gray(formattedTime)
103
103
  } ${
104
- chalk.gray(formattedLength)
104
+ pico.gray(formattedLength)
105
105
  }`
106
106
  )
107
107
  }
@@ -1,5 +1,5 @@
1
1
  import { mixin } from '@ditojs/utils'
2
- import { TimeStampedMixin } from './TimeStampedMixin'
2
+ import { TimeStampedMixin } from './TimeStampedMixin.js'
3
3
 
4
4
  // Asset models are always to be time-stamped:
5
5
  export const AssetMixin = mixin(Model => class extends TimeStampedMixin(Model) {
@@ -1,8 +1,8 @@
1
1
  import bcrypt from 'bcryptjs'
2
2
  import passport from 'koa-passport'
3
3
  import { Strategy as LocalStrategy } from 'passport-local'
4
- import { AuthenticationError } from '@/errors'
5
4
  import { mixin, asArray } from '@ditojs/utils'
5
+ import { AuthenticationError } from '../errors/index.js'
6
6
 
7
7
  export const UserMixin = mixin(Model => class extends Model {
8
8
  static options = {
@@ -1,4 +1,4 @@
1
- export * from './AssetMixin'
2
- export * from './SessionMixin'
3
- export * from './TimeStampedMixin'
4
- export * from './UserMixin'
1
+ export * from './AssetMixin.js'
2
+ export * from './SessionMixin.js'
3
+ export * from './TimeStampedMixin.js'
4
+ export * from './UserMixin.js'
@@ -1,4 +1,4 @@
1
- import { AssetMixin } from '@/mixins'
2
- import { Model } from './Model'
1
+ import { AssetMixin } from '../mixins/index.js'
2
+ import { Model } from './Model.js'
3
3
 
4
4
  export const AssetModel = AssetMixin(Model)
@@ -1,22 +1,26 @@
1
1
  import objection from 'objection'
2
- import { QueryBuilder } from '@/query'
3
- import { EventEmitter, KnexHelper } from '@/lib'
4
- import { convertSchema, addRelationSchemas, convertRelations } from '@/schema'
5
- import { populateGraph, filterGraph } from '@/graph'
6
- import { formatJson } from '@/utils'
2
+ import {
3
+ isString, isObject, isArray, isFunction, isPromise, asArray, merge, flatten,
4
+ parseDataPath, normalizeDataPath, getValueAtDataPath
5
+ } from '@ditojs/utils'
6
+ import { QueryBuilder } from '../query/index.js'
7
+ import { EventEmitter, KnexHelper } from '../lib/index.js'
8
+ import {
9
+ convertSchema,
10
+ addRelationSchemas,
11
+ convertRelations
12
+ } from '../schema/index.js'
13
+ import { populateGraph, filterGraph } from '../graph/index.js'
14
+ import { formatJson } from '../utils/index.js'
7
15
  import {
8
16
  ResponseError,
9
17
  GraphError, ModelError,
10
18
  NotFoundError,
11
19
  RelationError,
12
20
  WrappedError
13
- } from '@/errors'
14
- import {
15
- isString, isObject, isArray, isFunction, isPromise, asArray, merge, flatten,
16
- parseDataPath, normalizeDataPath, getValueAtDataPath
17
- } from '@ditojs/utils'
18
- import RelationAccessor from './RelationAccessor'
19
- import definitions from './definitions'
21
+ } from '../errors/index.js'
22
+ import RelationAccessor from './RelationAccessor.js'
23
+ import definitions from './definitions/index.js'
20
24
 
21
25
  export class Model extends objection.Model {
22
26
  // Define a default constructor to allow new Model(json) as a short-cut to
@@ -1,4 +1,4 @@
1
- import { QueryBuilder } from '@/query'
1
+ import { QueryBuilder } from '../query/index.js'
2
2
 
3
3
  export default class RelationAccessor {
4
4
  constructor(relation, modelClass, model) {
@@ -1,4 +1,4 @@
1
- import { SessionMixin } from '@/mixins'
2
- import { Model } from './Model'
1
+ import { SessionMixin } from '../mixins/index.js'
2
+ import { Model } from './Model.js'
3
3
 
4
4
  export const SessionModel = SessionMixin(Model)
@@ -1,4 +1,4 @@
1
- import { TimeStampedMixin } from '@/mixins'
2
- import { Model } from './Model'
1
+ import { TimeStampedMixin } from '../mixins/index.js'
2
+ import { Model } from './Model.js'
3
3
 
4
4
  export const TimeStampedModel = TimeStampedMixin(Model)
@@ -1,4 +1,4 @@
1
- import { UserMixin } from '@/mixins'
2
- import { Model } from './Model'
1
+ import { UserMixin } from '../mixins/index.js'
2
+ import { Model } from './Model.js'
3
3
 
4
4
  export const UserModel = UserMixin(Model)
@@ -1,4 +1,4 @@
1
- import { mergeReversedOrNull } from '@/utils'
1
+ import { mergeReversedOrNull } from '../../utils/index.js'
2
2
 
3
3
  export default function assets(values) {
4
4
  return mergeReversedOrNull(values)
@@ -1,6 +1,6 @@
1
1
  import { isObject, isFunction } from '@ditojs/utils'
2
- import { QueryFilters } from '@/query'
3
- import { mergeReversed } from '@/utils'
2
+ import { mergeReversed, processHandlerParameters } from '../../utils/index.js'
3
+ import { QueryFilters } from '../../query/index.js'
4
4
 
5
5
  export default function filters(values) {
6
6
  const filters = {}
@@ -8,7 +8,7 @@ export default function filters(values) {
8
8
  const filter = isFunction(definition)
9
9
  ? definition
10
10
  : isObject(definition)
11
- ? convertObjectFilter(definition, name)
11
+ ? convertFilterObject(name, definition)
12
12
  : null
13
13
  if (!filter) {
14
14
  throw new Error(
@@ -20,72 +20,85 @@ export default function filters(values) {
20
20
  return filters
21
21
  }
22
22
 
23
- function convertObjectFilter(definition, name) {
24
- const { filter, properties } = definition
25
- if (isFunction(filter)) {
26
- return addFunctionSettings(filter, definition)
27
- } else {
28
- // Convert QueryFilters to normal filter functions
23
+ function convertFilterObject(name, object) {
24
+ const addHandlerSettings = (handler, definition) => {
25
+ // Copy over parameters, returns and their validation options settings.
26
+ const { parameters, returns, ...rest } = definition
27
+ processHandlerParameters(handler, 'parameters', parameters)
28
+ processHandlerParameters(handler, 'returns', returns)
29
+ return Object.assign(handler, rest)
30
+ }
31
+
32
+ const { handler, filter, properties } = object
33
+ if (handler) {
34
+ return addHandlerSettings(handler, object)
35
+ } else if (filter) {
36
+ // Convert QueryFilter to normal filter function.
29
37
  const queryFilter = QueryFilters.get(filter)
30
38
  if (!queryFilter) {
31
39
  throw new Error(
32
40
  `Invalid filter '${name}': Unknown filter type '${filter}'.`
33
41
  )
34
42
  }
43
+ // Support both object and function definitions.
44
+ const queryHandler = isObject(queryFilter)
45
+ ? queryFilter.handler
46
+ : queryFilter
35
47
  const func = properties
36
48
  ? (query, ...args) => {
37
49
  // When the filter provides multiple properties, match them
38
50
  // all, but combine the expressions with OR.
39
51
  for (const property of properties) {
40
- query.orWhere(query => queryFilter(query, property, ...args))
52
+ query.orWhere(query => queryHandler(query, property, ...args))
41
53
  }
42
54
  }
43
55
  : (query, ...args) => {
44
- queryFilter(query, name, ...args)
56
+ queryHandler(query, name, ...args)
45
57
  }
46
- return addFunctionSettings(func, queryFilter)
58
+ return addHandlerSettings(func, queryFilter)
47
59
  }
48
60
  }
49
61
 
50
- function addFunctionSettings(filter, definition) {
51
- // Copy over @parameters() and @validate() settings
52
- filter.parameters = definition.parameters
53
- filter.validate = definition.validate
54
- return filter
55
- }
56
-
57
62
  function wrapWithValidation(filter, name, app) {
58
- // If parameters are defined, wrap the function in a closure that
59
- // performs parameter validation...
60
- const dataName = 'query'
61
- const validator = filter && app.compileParametersValidator(
62
- filter.parameters,
63
- { ...filter.validate, dataName }
64
- )
65
- if (validator?.validate) {
66
- return (query, ...args) => {
63
+ if (filter) {
64
+ // TODO: Implement `returns` validation for filters too.
65
+ // TODO: Share additional coercion handling with
66
+ // `ControllerAction#coerceValue()`
67
+ const { parameters, options = {} } = filter
68
+ // If parameters are defined, wrap the function in a closure that
69
+ // performs parameter validation...
70
+ const dataName = 'query'
71
+ const validator = app.compileParametersValidator(parameters, {
72
+ ...options.parameters,
73
+ dataName
74
+ })
75
+ if (validator?.validate) {
76
+ return (query, ...args) => {
67
77
  // Convert args to object for validation:
68
- const object = {}
69
- let index = 0
70
- for (const { name } of validator.list) {
78
+ const object = {}
79
+ let index = 0
80
+ for (const { name } of validator.list) {
71
81
  // Use dataName if no name is given, see:
72
82
  // Application.compileParametersValidator()
73
- object[name || dataName] = args[index++]
74
- }
75
- try {
76
- validator.validate(object)
77
- } catch (error) {
78
- throw app.createValidationError({
79
- type: 'FilterValidation',
80
- message:
83
+ object[name || dataName] = args[index++]
84
+ }
85
+ try {
86
+ validator.validate(object)
87
+ } catch (error) {
88
+ throw app.createValidationError({
89
+ type: 'FilterValidation',
90
+ message:
81
91
  `The provided data for query filter '${name}' is not valid`,
82
- errors: app.validator.prefixDataPaths(
83
- error.errors,
92
+ errors: app.validator.prefixDataPaths(
93
+ error.errors,
84
94
  `.${name}`
85
- )
86
- })
95
+ )
96
+ })
97
+ }
98
+ return validator.asObject
99
+ ? filter(query, object)
100
+ : filter(query, ...args)
87
101
  }
88
- return filter(query, ...args)
89
102
  }
90
103
  }
91
104
  // ...otherwise use the defined filter function unmodified.
@@ -1,4 +1,4 @@
1
- import { mergeAsReversedArrays } from '@/utils'
1
+ import { mergeAsReversedArrays } from '../../utils/index.js'
2
2
 
3
3
  export default function hooks(values) {
4
4
  // Use `mergeAsReversedArrays()` so that for each event there is an array
@@ -1,12 +1,12 @@
1
- import options from './options'
2
- import properties from './properties'
3
- import relations from './relations'
4
- import schema from './schema'
5
- import scopes from './scopes'
6
- import filters from './filters'
7
- import modifiers from './modifiers'
8
- import assets from './assets'
9
- import hooks from './hooks'
1
+ import options from './options.js'
2
+ import properties from './properties.js'
3
+ import relations from './relations.js'
4
+ import schema from './schema.js'
5
+ import scopes from './scopes.js'
6
+ import filters from './filters.js'
7
+ import modifiers from './modifiers.js'
8
+ import assets from './assets.js'
9
+ import hooks from './hooks.js'
10
10
 
11
11
  export default {
12
12
  // Export options first, as other definitions may rely on them, e.g. UserMixin
@@ -1,4 +1,4 @@
1
- import { mergeReversed } from '@/utils'
1
+ import { mergeReversed } from '../../utils/index.js'
2
2
 
3
3
  export default function modifiers(values) {
4
4
  return mergeReversed(values)
@@ -1,4 +1,4 @@
1
- import { mergeReversed } from '@/utils'
1
+ import { mergeReversed } from '../../utils/index.js'
2
2
 
3
3
  export default function hooks(values) {
4
4
  return mergeReversed(values)
@@ -1,5 +1,5 @@
1
- import { mergeReversed } from '@/utils'
2
- import { expandSchemaShorthand } from '@/schema'
1
+ import { mergeReversed } from '../../utils/index.js'
2
+ import { expandSchemaShorthand } from '../../schema/index.js'
3
3
 
4
4
  export default function properties(values) {
5
5
  const properties = mergeReversed(values)
@@ -1,4 +1,4 @@
1
- import { mergeReversed } from '@/utils'
1
+ import { mergeReversed } from '../../utils/index.js'
2
2
 
3
3
  export default function relations(values) {
4
4
  return mergeReversed(values)
@@ -1,4 +1,4 @@
1
- import { mergeReversed } from '@/utils'
1
+ import { mergeReversed } from '../../utils/index.js'
2
2
 
3
3
  export default function schema(values) {
4
4
  return mergeReversed(values)
@@ -1,6 +1,6 @@
1
1
  import { isObject, isFunction } from '@ditojs/utils'
2
- import { ModelError } from '@/errors'
3
- import { mergeReversed } from '@/utils'
2
+ import { ModelError } from '../../errors/index.js'
3
+ import { mergeReversed } from '../../utils/index.js'
4
4
 
5
5
  export default function scopes(values) {
6
6
  const scopes = {}
@@ -1,5 +1,5 @@
1
- export * from './Model'
2
- export * from './AssetModel'
3
- export * from './SessionModel'
4
- export * from './TimeStampedModel'
5
- export * from './UserModel'
1
+ export * from './Model.js'
2
+ export * from './AssetModel.js'
3
+ export * from './SessionModel.js'
4
+ export * from './TimeStampedModel.js'
5
+ export * from './UserModel.js'