@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.
- package/package.json +25 -43
- package/src/app/Application.js +105 -111
- package/src/app/Validator.js +6 -3
- package/src/app/index.js +2 -2
- package/src/cli/db/createMigration.js +1 -1
- package/src/cli/db/index.js +7 -7
- package/src/cli/db/listAssetConfig.js +1 -1
- package/src/cli/db/reset.js +1 -1
- package/src/cli/index.js +14 -5
- package/src/controllers/AdminController.js +181 -158
- package/src/controllers/CollectionController.js +8 -29
- package/src/controllers/Controller.js +71 -76
- package/src/controllers/ControllerAction.js +39 -17
- package/src/controllers/MemberAction.js +2 -2
- package/src/controllers/ModelController.js +4 -4
- package/src/controllers/RelationController.js +3 -3
- package/src/controllers/{UserController.js → UsersController.js} +8 -13
- package/src/controllers/index.js +5 -5
- package/src/decorators/action.js +3 -3
- package/src/decorators/authorize.js +1 -1
- package/src/decorators/index.js +6 -6
- package/src/decorators/parameters.js +1 -1
- package/src/decorators/returns.js +1 -1
- package/src/decorators/scope.js +1 -1
- package/src/decorators/transacted.js +1 -1
- package/src/errors/AssetError.js +1 -1
- package/src/errors/AuthenticationError.js +1 -1
- package/src/errors/AuthorizationError.js +1 -1
- package/src/errors/ControllerError.js +1 -1
- package/src/errors/DatabaseError.js +12 -3
- package/src/errors/GraphError.js +1 -1
- package/src/errors/ModelError.js +1 -1
- package/src/errors/NotFoundError.js +1 -1
- package/src/errors/NotImplementedError.js +1 -1
- package/src/errors/QueryBuilderError.js +1 -1
- package/src/errors/RelationError.js +1 -1
- package/src/errors/ValidationError.js +1 -1
- package/src/errors/WrappedError.js +1 -1
- package/src/errors/index.js +14 -14
- package/src/graph/DitoGraphProcessor.js +2 -1
- package/src/graph/graph.js +1 -1
- package/src/graph/index.js +3 -3
- package/src/index.js +11 -9
- package/src/lib/index.js +2 -2
- package/src/middleware/createTransaction.js +1 -1
- package/src/middleware/findRoute.js +3 -2
- package/src/middleware/handleConnectMiddleware.js +88 -0
- package/src/middleware/handleError.js +1 -1
- package/src/middleware/handleRoute.js +3 -3
- package/src/middleware/index.js +8 -7
- package/src/mixins/AssetMixin.js +1 -1
- package/src/mixins/UserMixin.js +1 -1
- package/src/mixins/index.js +4 -4
- package/src/models/AssetModel.js +2 -2
- package/src/models/Model.js +16 -12
- package/src/models/RelationAccessor.js +1 -1
- package/src/models/SessionModel.js +2 -2
- package/src/models/TimeStampedModel.js +2 -2
- package/src/models/UserModel.js +2 -2
- package/src/models/definitions/assets.js +1 -1
- package/src/models/definitions/filters.js +57 -44
- package/src/models/definitions/hooks.js +1 -1
- package/src/models/definitions/index.js +9 -9
- package/src/models/definitions/modifiers.js +1 -1
- package/src/models/definitions/options.js +1 -1
- package/src/models/definitions/properties.js +2 -2
- package/src/models/definitions/relations.js +1 -1
- package/src/models/definitions/schema.js +1 -1
- package/src/models/definitions/scopes.js +2 -2
- package/src/models/index.js +5 -5
- package/src/query/QueryBuilder.js +5 -5
- package/src/query/QueryFilters.js +50 -50
- package/src/query/QueryParameters.js +2 -2
- package/src/query/index.js +3 -3
- package/src/schema/formats/index.js +2 -2
- package/src/schema/index.js +4 -4
- package/src/schema/keywords/_relate.js +1 -1
- package/src/schema/keywords/index.js +12 -12
- package/src/schema/properties.test.js +1 -1
- package/src/schema/relations.js +1 -1
- package/src/schema/relations.test.js +2 -2
- package/src/services/index.js +1 -1
- package/src/storage/DiskStorage.js +1 -1
- package/src/storage/S3Storage.js +4 -4
- package/src/storage/Storage.js +1 -1
- package/src/storage/index.js +4 -4
- package/src/utils/function.test.js +1 -1
- package/src/utils/handler.js +17 -0
- package/src/utils/index.js +8 -7
- package/src/utils/object.test.js +1 -1
- package/lib/app/Application.js +0 -961
- package/lib/app/SessionStore.js +0 -40
- package/lib/app/Validator.js +0 -355
- package/lib/app/index.js +0 -26
- package/lib/cli/console.js +0 -175
- package/lib/cli/db/createMigration.js +0 -237
- package/lib/cli/db/index.js +0 -66
- package/lib/cli/db/listAssetConfig.js +0 -16
- package/lib/cli/db/migrate.js +0 -15
- package/lib/cli/db/reset.js +0 -27
- package/lib/cli/db/rollback.js +0 -15
- package/lib/cli/db/seed.js +0 -104
- package/lib/cli/db/unlock.js +0 -15
- package/lib/cli/index.js +0 -90
- package/lib/controllers/AdminController.js +0 -258
- package/lib/controllers/CollectionController.js +0 -263
- package/lib/controllers/Controller.js +0 -462
- package/lib/controllers/ControllerAction.js +0 -276
- package/lib/controllers/MemberAction.js +0 -22
- package/lib/controllers/ModelController.js +0 -64
- package/lib/controllers/RelationController.js +0 -82
- package/lib/controllers/UserController.js +0 -98
- package/lib/controllers/index.js +0 -50
- package/lib/decorators/action.js +0 -14
- package/lib/decorators/authorize.js +0 -13
- package/lib/decorators/index.js +0 -58
- package/lib/decorators/parameters.js +0 -35
- package/lib/decorators/returns.js +0 -26
- package/lib/decorators/scope.js +0 -14
- package/lib/decorators/transacted.js +0 -12
- package/lib/errors/AssetError.js +0 -19
- package/lib/errors/AuthenticationError.js +0 -19
- package/lib/errors/AuthorizationError.js +0 -19
- package/lib/errors/ControllerError.js +0 -24
- package/lib/errors/DatabaseError.js +0 -27
- package/lib/errors/GraphError.js +0 -19
- package/lib/errors/ModelError.js +0 -24
- package/lib/errors/NotFoundError.js +0 -19
- package/lib/errors/NotImplementedError.js +0 -19
- package/lib/errors/QueryBuilderError.js +0 -19
- package/lib/errors/RelationError.js +0 -36
- package/lib/errors/ResponseError.js +0 -46
- package/lib/errors/ValidationError.js +0 -19
- package/lib/errors/WrappedError.js +0 -24
- package/lib/errors/index.js +0 -122
- package/lib/graph/DitoGraphProcessor.js +0 -185
- package/lib/graph/expression.js +0 -76
- package/lib/graph/graph.js +0 -300
- package/lib/graph/index.js +0 -34
- package/lib/index.js +0 -82
- package/lib/lib/EventEmitter.js +0 -76
- package/lib/lib/KnexHelper.js +0 -40
- package/lib/lib/index.js +0 -26
- package/lib/middleware/attachLogger.js +0 -16
- package/lib/middleware/createTransaction.js +0 -36
- package/lib/middleware/findRoute.js +0 -35
- package/lib/middleware/handleError.js +0 -26
- package/lib/middleware/handleRoute.js +0 -29
- package/lib/middleware/handleUser.js +0 -36
- package/lib/middleware/index.js +0 -66
- package/lib/middleware/logRequests.js +0 -122
- package/lib/mixins/AssetMixin.js +0 -81
- package/lib/mixins/SessionMixin.js +0 -22
- package/lib/mixins/TimeStampedMixin.js +0 -47
- package/lib/mixins/UserMixin.js +0 -151
- package/lib/mixins/index.js +0 -42
- package/lib/models/AssetModel.js +0 -12
- package/lib/models/Model.js +0 -953
- package/lib/models/RelationAccessor.js +0 -41
- package/lib/models/SessionModel.js +0 -12
- package/lib/models/TimeStampedModel.js +0 -12
- package/lib/models/UserModel.js +0 -12
- package/lib/models/definitions/assets.js +0 -11
- package/lib/models/definitions/filters.js +0 -101
- package/lib/models/definitions/hooks.js +0 -11
- package/lib/models/definitions/index.js +0 -38
- package/lib/models/definitions/modifiers.js +0 -11
- package/lib/models/definitions/options.js +0 -11
- package/lib/models/definitions/properties.js +0 -87
- package/lib/models/definitions/relations.js +0 -11
- package/lib/models/definitions/schema.js +0 -11
- package/lib/models/definitions/scopes.js +0 -51
- package/lib/models/index.js +0 -50
- package/lib/query/QueryBuilder.js +0 -745
- package/lib/query/QueryFilters.js +0 -82
- package/lib/query/QueryParameters.js +0 -77
- package/lib/query/Registry.js +0 -40
- package/lib/query/index.js +0 -34
- package/lib/schema/formats/_empty.js +0 -10
- package/lib/schema/formats/_required.js +0 -10
- package/lib/schema/formats/index.js +0 -26
- package/lib/schema/index.js +0 -49
- package/lib/schema/keywords/_computed.js +0 -11
- package/lib/schema/keywords/_foreign.js +0 -11
- package/lib/schema/keywords/_hidden.js +0 -11
- package/lib/schema/keywords/_index.js +0 -11
- package/lib/schema/keywords/_instanceof.js +0 -49
- package/lib/schema/keywords/_primary.js +0 -11
- package/lib/schema/keywords/_range.js +0 -26
- package/lib/schema/keywords/_relate.js +0 -19
- package/lib/schema/keywords/_specificType.js +0 -11
- package/lib/schema/keywords/_unique.js +0 -11
- package/lib/schema/keywords/_unsigned.js +0 -11
- package/lib/schema/keywords/_validate.js +0 -80
- package/lib/schema/keywords/index.js +0 -106
- package/lib/schema/properties.js +0 -227
- package/lib/schema/properties.test.js +0 -573
- package/lib/schema/relations.js +0 -274
- package/lib/schema/relations.test.js +0 -155
- package/lib/services/Service.js +0 -34
- package/lib/services/index.js +0 -18
- package/lib/storage/AssetFile.js +0 -97
- package/lib/storage/DiskStorage.js +0 -125
- package/lib/storage/S3Storage.js +0 -171
- package/lib/storage/Storage.js +0 -209
- package/lib/storage/index.js +0 -34
- package/lib/utils/decorator.js +0 -16
- package/lib/utils/deprecate.js +0 -46
- package/lib/utils/emitter.js +0 -13
- package/lib/utils/function.js +0 -14
- package/lib/utils/function.test.js +0 -49
- package/lib/utils/index.js +0 -66
- package/lib/utils/json.js +0 -9
- package/lib/utils/object.js +0 -92
- package/lib/utils/object.test.js +0 -65
- package/lib/utils/scope.js +0 -14
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import pico from 'picocolors'
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import MemberAction from './MemberAction'
|
|
2
|
+
import { EventEmitter } from '../lib/index.js'
|
|
3
|
+
import ControllerAction from './ControllerAction.js'
|
|
4
|
+
import MemberAction from './MemberAction.js'
|
|
6
5
|
import {
|
|
7
6
|
ResponseError, WrappedError, ControllerError, AuthorizationError
|
|
8
|
-
} from '
|
|
7
|
+
} from '../errors/index.js'
|
|
8
|
+
import {
|
|
9
|
+
getOwnProperty, getAllKeys, processHandlerParameters, describeFunction,
|
|
10
|
+
formatJson, deprecate
|
|
11
|
+
} from '../utils/index.js'
|
|
9
12
|
import {
|
|
10
13
|
isObject, isString, isArray, isBoolean, isFunction, asArray, equals,
|
|
11
14
|
parseDataPath, normalizeDataPath
|
|
@@ -73,10 +76,10 @@ export class Controller {
|
|
|
73
76
|
|
|
74
77
|
const addAction = key => {
|
|
75
78
|
const value = this[key]
|
|
76
|
-
// NOTE: Only add instance methods that have a @action() decorator,
|
|
77
|
-
//
|
|
78
|
-
// which
|
|
79
|
-
if (value?.
|
|
79
|
+
// NOTE: Only add instance methods that have a @action() decorator, which
|
|
80
|
+
// in turn sets the `method` property on the method, as well as action
|
|
81
|
+
// objects which provide the `method` property:
|
|
82
|
+
if (value?.method) {
|
|
80
83
|
controller[key] = value
|
|
81
84
|
}
|
|
82
85
|
}
|
|
@@ -89,10 +92,10 @@ export class Controller {
|
|
|
89
92
|
return controller
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
setupRoute(
|
|
95
|
+
setupRoute(method, url, transacted, authorize, action, middlewares) {
|
|
93
96
|
this.log(
|
|
94
97
|
`${
|
|
95
|
-
pico.magenta(
|
|
98
|
+
pico.magenta(method.toUpperCase())
|
|
96
99
|
} ${
|
|
97
100
|
pico.green(this.url)
|
|
98
101
|
}${
|
|
@@ -102,7 +105,7 @@ export class Controller {
|
|
|
102
105
|
}`,
|
|
103
106
|
this.level + 1
|
|
104
107
|
)
|
|
105
|
-
this.app.addRoute(
|
|
108
|
+
this.app.addRoute(method, url, transacted, middlewares, this, action)
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
setupActions(type) {
|
|
@@ -110,26 +113,25 @@ export class Controller {
|
|
|
110
113
|
values: actions,
|
|
111
114
|
authorize
|
|
112
115
|
} = this.processValues(this.inheritValues(type))
|
|
113
|
-
for (const [name,
|
|
114
|
-
|
|
116
|
+
for (const [name, action] of Object.entries(actions)) {
|
|
117
|
+
// Replace the action object with the converted action handler, so they
|
|
118
|
+
// too can benefit from prototypal inheritance:
|
|
119
|
+
actions[name] = this.setupAction(
|
|
120
|
+
type, actions, name, action, authorize[name]
|
|
121
|
+
)
|
|
115
122
|
}
|
|
116
123
|
return actions
|
|
117
124
|
}
|
|
118
125
|
|
|
119
|
-
setupAction(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// The default path for actions is the normalized name.
|
|
129
|
-
path = this.app.normalizePath(name)
|
|
130
|
-
) {
|
|
131
|
-
if (!isFunction(handler)) {
|
|
132
|
-
handler = setupHandlerFromObject(handler, actions)
|
|
126
|
+
setupAction(type, actions, name, action, authorize) {
|
|
127
|
+
const handler = isFunction(action) ? action
|
|
128
|
+
: isObject(action) ? convertActionObject(name, action, actions)
|
|
129
|
+
: null
|
|
130
|
+
// Action naming convention: `'<method> <path>'`, or just `'<method>'` for
|
|
131
|
+
// the default methods.
|
|
132
|
+
let [method, path = ''] = name.split(' ')
|
|
133
|
+
if (!isMethodAction(method)) {
|
|
134
|
+
path = name
|
|
133
135
|
}
|
|
134
136
|
// Custom member actions have their own class so they can fetch the members
|
|
135
137
|
// ahead of their call.
|
|
@@ -137,14 +139,15 @@ export class Controller {
|
|
|
137
139
|
this.setupActionRoute(
|
|
138
140
|
type,
|
|
139
141
|
// eslint-disable-next-line new-cap
|
|
140
|
-
new actionClass(this, handler, type, name,
|
|
142
|
+
new actionClass(this, handler, type, name, method, path, authorize)
|
|
141
143
|
)
|
|
144
|
+
return handler
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
setupActionRoute(type, action) {
|
|
145
148
|
const url = this.getUrl(type, action.path)
|
|
146
|
-
const {
|
|
147
|
-
this.setupRoute(
|
|
149
|
+
const { method, transacted, authorize } = action
|
|
150
|
+
this.setupRoute(method, url, transacted, authorize, action, [
|
|
148
151
|
async ctx => {
|
|
149
152
|
try {
|
|
150
153
|
const res = await action.callAction(ctx)
|
|
@@ -232,6 +235,7 @@ export class Controller {
|
|
|
232
235
|
])
|
|
233
236
|
}
|
|
234
237
|
|
|
238
|
+
// @return {Application|Function} [app or function]
|
|
235
239
|
compose() {
|
|
236
240
|
// To be overridden in sub-classes, if the controller needs to install
|
|
237
241
|
// middleware. For normal routes, use `this.app.addRoute()` instead.
|
|
@@ -250,11 +254,11 @@ export class Controller {
|
|
|
250
254
|
|
|
251
255
|
inheritValues(type) {
|
|
252
256
|
// Gets the controller class's instance field for a given action type, e.g.
|
|
253
|
-
// `controller` (Controller), `collection`, `member` (ModelController
|
|
254
|
-
// RelationController), `relation` (RelationController), and sets up an
|
|
257
|
+
// `controller` (`Controller`), `collection`, `member` (`ModelController`,
|
|
258
|
+
// `RelationController`), `relation` (`RelationController`), and sets up an
|
|
255
259
|
// inheritance chain for it that goes all the way up to it base class (e.g.
|
|
256
|
-
// CollectionController), so that the default definitions for all
|
|
257
|
-
// can be
|
|
260
|
+
// `CollectionController`), so that the default definitions for all HTTP
|
|
261
|
+
// methods can be inherited and overridden while using `super.<action>()`.
|
|
258
262
|
const parentClass = Object.getPrototypeOf(this.constructor)
|
|
259
263
|
// Create one instance of each controller class up the chain in order to
|
|
260
264
|
// get to their definitions of the inheritable values. Cache both instance
|
|
@@ -389,7 +393,7 @@ export class Controller {
|
|
|
389
393
|
return result
|
|
390
394
|
},
|
|
391
395
|
// Create a new object for the filtered `values` that keeps inheritance
|
|
392
|
-
// intact. This is required by `
|
|
396
|
+
// intact. This is required by `convertActionObject()`, to support
|
|
393
397
|
// `super` in handler functions.
|
|
394
398
|
Object.create(Object.getPrototypeOf(values))
|
|
395
399
|
),
|
|
@@ -400,14 +404,14 @@ export class Controller {
|
|
|
400
404
|
|
|
401
405
|
async emitHook(type, handleResult, ctx, ...args) {
|
|
402
406
|
let result = handleResult ? args.shift() : undefined
|
|
403
|
-
for (const
|
|
407
|
+
for (const listener of this.listeners(type)) {
|
|
404
408
|
if (handleResult) {
|
|
405
|
-
const res = await
|
|
409
|
+
const res = await listener.call(this, ctx, result, ...args)
|
|
406
410
|
if (res !== undefined) {
|
|
407
411
|
result = res
|
|
408
412
|
}
|
|
409
413
|
} else {
|
|
410
|
-
await
|
|
414
|
+
await listener.call(this, ctx, ...args)
|
|
411
415
|
}
|
|
412
416
|
}
|
|
413
417
|
return result
|
|
@@ -503,62 +507,53 @@ EventEmitter.mixin(Controller.prototype)
|
|
|
503
507
|
|
|
504
508
|
const inheritanceMap = new WeakMap()
|
|
505
509
|
|
|
506
|
-
function
|
|
510
|
+
function convertActionObject(name, object, actions) {
|
|
507
511
|
const {
|
|
508
512
|
handler,
|
|
509
513
|
action,
|
|
510
514
|
authorize,
|
|
515
|
+
transacted,
|
|
516
|
+
scope,
|
|
511
517
|
parameters,
|
|
512
518
|
returns,
|
|
513
|
-
|
|
514
|
-
transacted
|
|
519
|
+
...rest
|
|
515
520
|
} = object
|
|
516
521
|
|
|
517
522
|
// In order to suport `super` calls in the `handler` function in object
|
|
518
523
|
// notation, deploy this crazy JS sorcery:
|
|
519
524
|
Object.setPrototypeOf(object, Object.getPrototypeOf(actions))
|
|
520
525
|
|
|
521
|
-
handler.authorize = authorize
|
|
522
|
-
handler.transacted = transacted
|
|
523
|
-
|
|
524
526
|
if (action) {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
+
deprecate(`action.action is deprecated. Use action.method and action.path instead.`)
|
|
528
|
+
const [method, path] = asArray(action)
|
|
529
|
+
handler.method = method
|
|
527
530
|
handler.path = path
|
|
528
531
|
}
|
|
529
532
|
|
|
530
|
-
if (
|
|
531
|
-
|
|
532
|
-
const hasOptions = isArray(_parameters)
|
|
533
|
-
handler.parameters = hasOptions ? _parameters : parameters
|
|
534
|
-
|
|
535
|
-
// If validation options are provided, expose them through
|
|
536
|
-
// `handler.options.parameters`, see ControllerAction
|
|
537
|
-
if (hasOptions) {
|
|
538
|
-
handler.options = {
|
|
539
|
-
...handler.options,
|
|
540
|
-
parameters: options
|
|
541
|
-
}
|
|
542
|
-
}
|
|
533
|
+
if (!handler) {
|
|
534
|
+
throw new Error(`Missing handler in '${name}' action: ${formatJson(object)}`)
|
|
543
535
|
}
|
|
544
536
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
537
|
+
handler.authorize = authorize ?? null
|
|
538
|
+
handler.transacted = transacted ?? null
|
|
539
|
+
handler.scope = scope ? asArray(scope) : null
|
|
548
540
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (options) {
|
|
552
|
-
handler.options = {
|
|
553
|
-
...handler.options,
|
|
554
|
-
parameters: options
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
541
|
+
processHandlerParameters(handler, 'parameters', parameters)
|
|
542
|
+
processHandlerParameters(handler, 'returns', returns)
|
|
558
543
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
544
|
+
return Object.assign(handler, rest)
|
|
545
|
+
}
|
|
562
546
|
|
|
563
|
-
|
|
547
|
+
function isMethodAction(name) {
|
|
548
|
+
return {
|
|
549
|
+
get: true,
|
|
550
|
+
delete: true,
|
|
551
|
+
post: true,
|
|
552
|
+
put: true,
|
|
553
|
+
patch: true,
|
|
554
|
+
head: true,
|
|
555
|
+
options: true,
|
|
556
|
+
trace: true,
|
|
557
|
+
connect: true
|
|
558
|
+
}[name]
|
|
564
559
|
}
|
|
@@ -1,37 +1,56 @@
|
|
|
1
1
|
import { isString, isObject, asArray, clone } from '@ditojs/utils'
|
|
2
2
|
|
|
3
3
|
export default class ControllerAction {
|
|
4
|
-
constructor(controller, handler, type, name,
|
|
4
|
+
constructor(controller, handler, type, name, _method, _path, _authorize) {
|
|
5
|
+
const {
|
|
6
|
+
core = false,
|
|
7
|
+
// Allow decorators on actions to override the predetermined defaults for
|
|
8
|
+
// `method`, `path` and `authorize`:
|
|
9
|
+
// TODO: `handler.method` and `handler.path` were deprecated in March
|
|
10
|
+
// 2022, remove later and only set the valued passed to constructor then.
|
|
11
|
+
method = _method,
|
|
12
|
+
path = _path,
|
|
13
|
+
scope,
|
|
14
|
+
authorize,
|
|
15
|
+
transacted,
|
|
16
|
+
parameters,
|
|
17
|
+
returns,
|
|
18
|
+
options = {},
|
|
19
|
+
...additional
|
|
20
|
+
} = handler
|
|
21
|
+
|
|
5
22
|
this.controller = controller
|
|
6
23
|
this.handler = handler
|
|
7
24
|
this.type = type
|
|
8
25
|
this.name = name
|
|
9
26
|
this.identifier = `${type}:${name}`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
this.
|
|
13
|
-
|
|
14
|
-
this.path = handler.path ?? path
|
|
15
|
-
this.authorize = handler.authorize || authorize
|
|
27
|
+
this.method = method
|
|
28
|
+
this.path = path
|
|
29
|
+
this.scope = scope
|
|
30
|
+
this.authorize = authorize || _authorize
|
|
16
31
|
this.transacted = !!(
|
|
17
|
-
|
|
18
|
-
controller.transacted ||
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
32
|
+
transacted ||
|
|
33
|
+
controller.transacted || (
|
|
34
|
+
// Core graph and assets operations are always transacted, unless the
|
|
35
|
+
// method is 'get':
|
|
36
|
+
core && method !== 'get' && (
|
|
37
|
+
controller.graph ||
|
|
38
|
+
controller.assets
|
|
39
|
+
)
|
|
40
|
+
)
|
|
22
41
|
)
|
|
23
42
|
this.authorization = controller.processAuthorize(this.authorize)
|
|
24
43
|
this.app = controller.app
|
|
25
|
-
this.paramsName = ['post', 'put', 'patch'].includes(this.
|
|
44
|
+
this.paramsName = ['post', 'put', 'patch'].includes(this.method)
|
|
26
45
|
? 'body'
|
|
27
46
|
: 'query'
|
|
28
|
-
const { parameters, returns, options = {} } = this.handler
|
|
29
47
|
this.parameters = this.app.compileParametersValidator(parameters, {
|
|
30
48
|
async: true,
|
|
31
|
-
...options.parameters,
|
|
49
|
+
...options.parameters,
|
|
32
50
|
dataName: this.paramsName
|
|
33
51
|
})
|
|
34
52
|
this.returns = this.app.compileParametersValidator(
|
|
53
|
+
// TODO: Shouldn't we set `this.returns` to null instead?
|
|
35
54
|
returns ? [returns] : [],
|
|
36
55
|
{
|
|
37
56
|
async: true,
|
|
@@ -43,12 +62,15 @@ export default class ControllerAction {
|
|
|
43
62
|
dataName: 'returns'
|
|
44
63
|
}
|
|
45
64
|
)
|
|
65
|
+
// Copy over the additional properties, e.g. `cached` so application
|
|
66
|
+
// middleware can implement caching mechanisms:
|
|
67
|
+
Object.assign(this, additional)
|
|
46
68
|
}
|
|
47
69
|
|
|
48
70
|
// Possible values for `from` are:
|
|
49
71
|
// - 'path': Use `ctx.params` which is mapped to the route / path
|
|
50
|
-
// - 'query': Use `ctx.request.query`, regardless of the action's
|
|
51
|
-
// - 'body': Use `ctx.request.body`, regardless of the action's
|
|
72
|
+
// - 'query': Use `ctx.request.query`, regardless of the action's method.
|
|
73
|
+
// - 'body': Use `ctx.request.body`, regardless of the action's method.
|
|
52
74
|
getParams(ctx, from = this.paramsName) {
|
|
53
75
|
const value = from === 'path' ? ctx.params : ctx.request[from]
|
|
54
76
|
// koa-bodyparser always sets an object, even when there is no body.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ControllerAction from './ControllerAction'
|
|
1
|
+
import ControllerAction from './ControllerAction.js'
|
|
2
2
|
|
|
3
3
|
export default class MemberAction extends ControllerAction {
|
|
4
4
|
// @override
|
|
@@ -9,7 +9,7 @@ export default class MemberAction extends ControllerAction {
|
|
|
9
9
|
|
|
10
10
|
// @override
|
|
11
11
|
async getMember(ctx, param) {
|
|
12
|
-
// member
|
|
12
|
+
// member parameters can provide special query parameters as well,
|
|
13
13
|
// and they can even controll `forUpdate()` behavior:
|
|
14
14
|
// {
|
|
15
15
|
// member: true,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import pluralize from 'pluralize'
|
|
2
2
|
import { isObject, camelize } from '@ditojs/utils'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { setupPropertyInheritance } from '
|
|
3
|
+
import { CollectionController } from './CollectionController.js'
|
|
4
|
+
import { RelationController } from './RelationController.js'
|
|
5
|
+
import { ControllerError } from '../errors/index.js'
|
|
6
|
+
import { setupPropertyInheritance } from '../utils/index.js'
|
|
7
7
|
|
|
8
8
|
export class ModelController extends CollectionController {
|
|
9
9
|
setup() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import pico from 'picocolors'
|
|
2
|
-
import { ControllerError } from '@/errors'
|
|
3
|
-
import { CollectionController } from './CollectionController'
|
|
4
|
-
import { setupPropertyInheritance, getScope } from '@/utils'
|
|
5
2
|
import { asArray } from '@ditojs/utils'
|
|
3
|
+
import { CollectionController } from './CollectionController.js'
|
|
4
|
+
import { ControllerError } from '../errors/index.js'
|
|
5
|
+
import { setupPropertyInheritance, getScope } from '../utils/index.js'
|
|
6
6
|
|
|
7
7
|
export class RelationController extends CollectionController {
|
|
8
8
|
constructor(parent, object, relationInstance, relationDefinition) {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ModelController } from './ModelController'
|
|
1
|
+
import { ModelController } from './ModelController.js'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
export class UserController extends ModelController {
|
|
3
|
+
export class UsersController extends ModelController {
|
|
6
4
|
collection = {
|
|
7
|
-
|
|
8
|
-
async login(ctx) {
|
|
5
|
+
async 'post login'(ctx) {
|
|
9
6
|
let user
|
|
10
7
|
let error
|
|
11
8
|
try {
|
|
@@ -26,8 +23,7 @@ export class UserController extends ModelController {
|
|
|
26
23
|
}
|
|
27
24
|
},
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
async logout(ctx) {
|
|
26
|
+
async 'post logout'(ctx) {
|
|
31
27
|
let success = false
|
|
32
28
|
if (this.isAuthenticated(ctx)) {
|
|
33
29
|
await ctx.logout()
|
|
@@ -39,19 +35,18 @@ export class UserController extends ModelController {
|
|
|
39
35
|
}
|
|
40
36
|
},
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
session(ctx) {
|
|
38
|
+
'get session'(ctx) {
|
|
44
39
|
const authenticated = this.isAuthenticated(ctx)
|
|
45
40
|
return {
|
|
46
41
|
authenticated,
|
|
47
42
|
user: authenticated ? ctx.state.user : null
|
|
43
|
+
|
|
48
44
|
}
|
|
49
45
|
},
|
|
50
46
|
|
|
51
|
-
|
|
52
|
-
self(ctx) {
|
|
47
|
+
'get self'(ctx) {
|
|
53
48
|
return this.isAuthenticated(ctx)
|
|
54
|
-
? this.member.
|
|
49
|
+
? this.member.get.call(
|
|
55
50
|
this,
|
|
56
51
|
this.getContextWithMemberId(ctx, ctx.state.user.$id())
|
|
57
52
|
)
|
package/src/controllers/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './Controller'
|
|
2
|
-
export * from './ModelController'
|
|
3
|
-
export * from './RelationController'
|
|
4
|
-
export * from './AdminController'
|
|
5
|
-
export * from './
|
|
1
|
+
export * from './Controller.js'
|
|
2
|
+
export * from './ModelController.js'
|
|
3
|
+
export * from './RelationController.js'
|
|
4
|
+
export * from './AdminController.js'
|
|
5
|
+
export * from './UsersController.js'
|
package/src/decorators/action.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createDecorator } from '
|
|
1
|
+
import { createDecorator } from '../utils/index.js'
|
|
2
2
|
|
|
3
|
-
export function action(
|
|
3
|
+
export function action(method, path) {
|
|
4
4
|
return createDecorator(value => {
|
|
5
|
-
value.
|
|
5
|
+
value.method = method
|
|
6
6
|
value.path = path
|
|
7
7
|
})
|
|
8
8
|
}
|
package/src/decorators/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './action'
|
|
2
|
-
export * from './authorize'
|
|
3
|
-
export * from './parameters'
|
|
4
|
-
export * from './returns'
|
|
5
|
-
export * from './scope'
|
|
6
|
-
export * from './transacted'
|
|
1
|
+
export * from './action.js'
|
|
2
|
+
export * from './authorize.js'
|
|
3
|
+
export * from './parameters.js'
|
|
4
|
+
export * from './returns.js'
|
|
5
|
+
export * from './scope.js'
|
|
6
|
+
export * from './transacted.js'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isArray, isObject } from '@ditojs/utils'
|
|
2
|
-
import { createDecorator, deprecate, formatJson } from '
|
|
2
|
+
import { createDecorator, deprecate, formatJson } from '../utils/index.js'
|
|
3
3
|
|
|
4
4
|
export function parameters(parameters, options) {
|
|
5
5
|
if (isObject(parameters)) {
|
package/src/decorators/scope.js
CHANGED
package/src/errors/AssetError.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { WrappedError } from './WrappedError'
|
|
2
|
-
|
|
1
|
+
import { WrappedError } from './WrappedError.js'
|
|
2
|
+
// TODO: Import directly once we can move to Objection 3 and this is fixed:
|
|
3
|
+
// import {
|
|
4
|
+
// DBError,
|
|
5
|
+
// DataError,
|
|
6
|
+
// CheckViolationError,
|
|
7
|
+
// NotNullViolationError,
|
|
8
|
+
// ConstraintViolationError
|
|
9
|
+
// } from 'objection'
|
|
10
|
+
import objection from 'objection'
|
|
11
|
+
const {
|
|
3
12
|
DBError,
|
|
4
13
|
DataError,
|
|
5
14
|
CheckViolationError,
|
|
6
15
|
NotNullViolationError,
|
|
7
16
|
ConstraintViolationError
|
|
8
|
-
}
|
|
17
|
+
} = objection
|
|
9
18
|
|
|
10
19
|
export class DatabaseError extends WrappedError {
|
|
11
20
|
constructor(error, overrides) {
|
package/src/errors/GraphError.js
CHANGED
package/src/errors/ModelError.js
CHANGED