@ditojs/server 0.275.0 → 1.0.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 (216) hide show
  1. package/package.json +25 -43
  2. package/src/app/Application.js +105 -111
  3. package/src/app/Validator.js +6 -3
  4. package/src/app/index.js +2 -2
  5. package/src/cli/db/createMigration.js +1 -1
  6. package/src/cli/db/index.js +7 -7
  7. package/src/cli/db/listAssetConfig.js +1 -1
  8. package/src/cli/db/reset.js +1 -1
  9. package/src/cli/index.js +14 -5
  10. package/src/controllers/AdminController.js +181 -158
  11. package/src/controllers/CollectionController.js +8 -29
  12. package/src/controllers/Controller.js +71 -76
  13. package/src/controllers/ControllerAction.js +39 -17
  14. package/src/controllers/MemberAction.js +2 -2
  15. package/src/controllers/ModelController.js +4 -4
  16. package/src/controllers/RelationController.js +3 -3
  17. package/src/controllers/{UserController.js → UsersController.js} +8 -13
  18. package/src/controllers/index.js +5 -5
  19. package/src/decorators/action.js +3 -3
  20. package/src/decorators/authorize.js +1 -1
  21. package/src/decorators/index.js +6 -6
  22. package/src/decorators/parameters.js +1 -1
  23. package/src/decorators/returns.js +1 -1
  24. package/src/decorators/scope.js +1 -1
  25. package/src/decorators/transacted.js +1 -1
  26. package/src/errors/AssetError.js +1 -1
  27. package/src/errors/AuthenticationError.js +1 -1
  28. package/src/errors/AuthorizationError.js +1 -1
  29. package/src/errors/ControllerError.js +1 -1
  30. package/src/errors/DatabaseError.js +12 -3
  31. package/src/errors/GraphError.js +1 -1
  32. package/src/errors/ModelError.js +1 -1
  33. package/src/errors/NotFoundError.js +1 -1
  34. package/src/errors/NotImplementedError.js +1 -1
  35. package/src/errors/QueryBuilderError.js +1 -1
  36. package/src/errors/RelationError.js +1 -1
  37. package/src/errors/ValidationError.js +1 -1
  38. package/src/errors/WrappedError.js +1 -1
  39. package/src/errors/index.js +14 -14
  40. package/src/graph/DitoGraphProcessor.js +2 -1
  41. package/src/graph/graph.js +1 -1
  42. package/src/graph/index.js +3 -3
  43. package/src/index.js +11 -9
  44. package/src/lib/index.js +2 -2
  45. package/src/middleware/createTransaction.js +1 -1
  46. package/src/middleware/findRoute.js +3 -2
  47. package/src/middleware/handleConnectMiddleware.js +88 -0
  48. package/src/middleware/handleError.js +1 -1
  49. package/src/middleware/handleRoute.js +3 -3
  50. package/src/middleware/index.js +8 -7
  51. package/src/mixins/AssetMixin.js +1 -1
  52. package/src/mixins/UserMixin.js +1 -1
  53. package/src/mixins/index.js +4 -4
  54. package/src/models/AssetModel.js +2 -2
  55. package/src/models/Model.js +16 -12
  56. package/src/models/RelationAccessor.js +1 -1
  57. package/src/models/SessionModel.js +2 -2
  58. package/src/models/TimeStampedModel.js +2 -2
  59. package/src/models/UserModel.js +2 -2
  60. package/src/models/definitions/assets.js +1 -1
  61. package/src/models/definitions/filters.js +57 -44
  62. package/src/models/definitions/hooks.js +1 -1
  63. package/src/models/definitions/index.js +9 -9
  64. package/src/models/definitions/modifiers.js +1 -1
  65. package/src/models/definitions/options.js +1 -1
  66. package/src/models/definitions/properties.js +2 -2
  67. package/src/models/definitions/relations.js +1 -1
  68. package/src/models/definitions/schema.js +1 -1
  69. package/src/models/definitions/scopes.js +2 -2
  70. package/src/models/index.js +5 -5
  71. package/src/query/QueryBuilder.js +5 -5
  72. package/src/query/QueryFilters.js +50 -50
  73. package/src/query/QueryParameters.js +2 -2
  74. package/src/query/index.js +3 -3
  75. package/src/schema/formats/index.js +2 -2
  76. package/src/schema/index.js +4 -4
  77. package/src/schema/keywords/_relate.js +1 -1
  78. package/src/schema/keywords/index.js +12 -12
  79. package/src/schema/properties.test.js +1 -1
  80. package/src/schema/relations.js +1 -1
  81. package/src/schema/relations.test.js +2 -2
  82. package/src/services/index.js +1 -1
  83. package/src/storage/DiskStorage.js +1 -1
  84. package/src/storage/S3Storage.js +4 -4
  85. package/src/storage/Storage.js +1 -1
  86. package/src/storage/index.js +4 -4
  87. package/src/utils/function.test.js +1 -1
  88. package/src/utils/handler.js +17 -0
  89. package/src/utils/index.js +8 -7
  90. package/src/utils/object.test.js +1 -1
  91. package/lib/app/Application.js +0 -961
  92. package/lib/app/SessionStore.js +0 -40
  93. package/lib/app/Validator.js +0 -355
  94. package/lib/app/index.js +0 -26
  95. package/lib/cli/console.js +0 -175
  96. package/lib/cli/db/createMigration.js +0 -237
  97. package/lib/cli/db/index.js +0 -66
  98. package/lib/cli/db/listAssetConfig.js +0 -16
  99. package/lib/cli/db/migrate.js +0 -15
  100. package/lib/cli/db/reset.js +0 -27
  101. package/lib/cli/db/rollback.js +0 -15
  102. package/lib/cli/db/seed.js +0 -104
  103. package/lib/cli/db/unlock.js +0 -15
  104. package/lib/cli/index.js +0 -90
  105. package/lib/controllers/AdminController.js +0 -258
  106. package/lib/controllers/CollectionController.js +0 -263
  107. package/lib/controllers/Controller.js +0 -462
  108. package/lib/controllers/ControllerAction.js +0 -276
  109. package/lib/controllers/MemberAction.js +0 -22
  110. package/lib/controllers/ModelController.js +0 -64
  111. package/lib/controllers/RelationController.js +0 -82
  112. package/lib/controllers/UserController.js +0 -98
  113. package/lib/controllers/index.js +0 -50
  114. package/lib/decorators/action.js +0 -14
  115. package/lib/decorators/authorize.js +0 -13
  116. package/lib/decorators/index.js +0 -58
  117. package/lib/decorators/parameters.js +0 -35
  118. package/lib/decorators/returns.js +0 -26
  119. package/lib/decorators/scope.js +0 -14
  120. package/lib/decorators/transacted.js +0 -12
  121. package/lib/errors/AssetError.js +0 -19
  122. package/lib/errors/AuthenticationError.js +0 -19
  123. package/lib/errors/AuthorizationError.js +0 -19
  124. package/lib/errors/ControllerError.js +0 -24
  125. package/lib/errors/DatabaseError.js +0 -27
  126. package/lib/errors/GraphError.js +0 -19
  127. package/lib/errors/ModelError.js +0 -24
  128. package/lib/errors/NotFoundError.js +0 -19
  129. package/lib/errors/NotImplementedError.js +0 -19
  130. package/lib/errors/QueryBuilderError.js +0 -19
  131. package/lib/errors/RelationError.js +0 -36
  132. package/lib/errors/ResponseError.js +0 -46
  133. package/lib/errors/ValidationError.js +0 -19
  134. package/lib/errors/WrappedError.js +0 -24
  135. package/lib/errors/index.js +0 -122
  136. package/lib/graph/DitoGraphProcessor.js +0 -185
  137. package/lib/graph/expression.js +0 -76
  138. package/lib/graph/graph.js +0 -300
  139. package/lib/graph/index.js +0 -34
  140. package/lib/index.js +0 -82
  141. package/lib/lib/EventEmitter.js +0 -76
  142. package/lib/lib/KnexHelper.js +0 -40
  143. package/lib/lib/index.js +0 -26
  144. package/lib/middleware/attachLogger.js +0 -16
  145. package/lib/middleware/createTransaction.js +0 -36
  146. package/lib/middleware/findRoute.js +0 -35
  147. package/lib/middleware/handleError.js +0 -26
  148. package/lib/middleware/handleRoute.js +0 -29
  149. package/lib/middleware/handleUser.js +0 -36
  150. package/lib/middleware/index.js +0 -66
  151. package/lib/middleware/logRequests.js +0 -122
  152. package/lib/mixins/AssetMixin.js +0 -81
  153. package/lib/mixins/SessionMixin.js +0 -22
  154. package/lib/mixins/TimeStampedMixin.js +0 -47
  155. package/lib/mixins/UserMixin.js +0 -151
  156. package/lib/mixins/index.js +0 -42
  157. package/lib/models/AssetModel.js +0 -12
  158. package/lib/models/Model.js +0 -953
  159. package/lib/models/RelationAccessor.js +0 -41
  160. package/lib/models/SessionModel.js +0 -12
  161. package/lib/models/TimeStampedModel.js +0 -12
  162. package/lib/models/UserModel.js +0 -12
  163. package/lib/models/definitions/assets.js +0 -11
  164. package/lib/models/definitions/filters.js +0 -101
  165. package/lib/models/definitions/hooks.js +0 -11
  166. package/lib/models/definitions/index.js +0 -38
  167. package/lib/models/definitions/modifiers.js +0 -11
  168. package/lib/models/definitions/options.js +0 -11
  169. package/lib/models/definitions/properties.js +0 -87
  170. package/lib/models/definitions/relations.js +0 -11
  171. package/lib/models/definitions/schema.js +0 -11
  172. package/lib/models/definitions/scopes.js +0 -51
  173. package/lib/models/index.js +0 -50
  174. package/lib/query/QueryBuilder.js +0 -745
  175. package/lib/query/QueryFilters.js +0 -82
  176. package/lib/query/QueryParameters.js +0 -77
  177. package/lib/query/Registry.js +0 -40
  178. package/lib/query/index.js +0 -34
  179. package/lib/schema/formats/_empty.js +0 -10
  180. package/lib/schema/formats/_required.js +0 -10
  181. package/lib/schema/formats/index.js +0 -26
  182. package/lib/schema/index.js +0 -49
  183. package/lib/schema/keywords/_computed.js +0 -11
  184. package/lib/schema/keywords/_foreign.js +0 -11
  185. package/lib/schema/keywords/_hidden.js +0 -11
  186. package/lib/schema/keywords/_index.js +0 -11
  187. package/lib/schema/keywords/_instanceof.js +0 -49
  188. package/lib/schema/keywords/_primary.js +0 -11
  189. package/lib/schema/keywords/_range.js +0 -26
  190. package/lib/schema/keywords/_relate.js +0 -19
  191. package/lib/schema/keywords/_specificType.js +0 -11
  192. package/lib/schema/keywords/_unique.js +0 -11
  193. package/lib/schema/keywords/_unsigned.js +0 -11
  194. package/lib/schema/keywords/_validate.js +0 -80
  195. package/lib/schema/keywords/index.js +0 -106
  196. package/lib/schema/properties.js +0 -227
  197. package/lib/schema/properties.test.js +0 -573
  198. package/lib/schema/relations.js +0 -274
  199. package/lib/schema/relations.test.js +0 -155
  200. package/lib/services/Service.js +0 -34
  201. package/lib/services/index.js +0 -18
  202. package/lib/storage/AssetFile.js +0 -97
  203. package/lib/storage/DiskStorage.js +0 -125
  204. package/lib/storage/S3Storage.js +0 -171
  205. package/lib/storage/Storage.js +0 -209
  206. package/lib/storage/index.js +0 -34
  207. package/lib/utils/decorator.js +0 -16
  208. package/lib/utils/deprecate.js +0 -46
  209. package/lib/utils/emitter.js +0 -13
  210. package/lib/utils/function.js +0 -14
  211. package/lib/utils/function.test.js +0 -49
  212. package/lib/utils/index.js +0 -66
  213. package/lib/utils/json.js +0 -9
  214. package/lib/utils/object.js +0 -92
  215. package/lib/utils/object.test.js +0 -65
  216. package/lib/utils/scope.js +0 -14
@@ -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'
@@ -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'
@@ -1,13 +1,13 @@
1
1
  import objection from 'objection'
2
- import { KnexHelper } from '@/lib'
3
- import { QueryBuilderError, RelationError } from '@/errors'
4
- import { QueryParameters } from './QueryParameters'
5
- import { DitoGraphProcessor, walkGraph } from '@/graph'
6
2
  import {
7
3
  isObject, isPlainObject, isString, isArray, clone, mapKeys,
8
4
  getValueAtDataPath, setValueAtDataPath, parseDataPath
9
5
  } from '@ditojs/utils'
10
- import { createLookup, getScope, deprecate } from '@/utils'
6
+ import { QueryParameters } from './QueryParameters.js'
7
+ import { KnexHelper } from '../lib/index.js'
8
+ import { DitoGraphProcessor, walkGraph } from '../graph/index.js'
9
+ import { QueryBuilderError, RelationError } from '../errors/index.js'
10
+ import { createLookup, getScope, deprecate } from '../utils/index.js'
11
11
 
12
12
  const SYMBOL_ALL = Symbol('all')
13
13