@ditojs/server 1.25.1 → 1.27.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 +6 -6
- package/src/app/Application.js +23 -23
- package/src/app/Validator.js +1 -1
- package/src/cli/db/createMigration.js +5 -10
- package/src/controllers/AdminController.js +3 -1
- package/src/controllers/CollectionController.js +1 -0
- package/src/controllers/Controller.js +43 -22
- package/src/controllers/ModelController.js +1 -1
- package/src/controllers/RelationController.js +7 -1
- package/src/decorators/action.js +1 -1
- package/src/decorators/authorize.js +1 -1
- package/src/decorators/parameters.js +3 -1
- package/src/decorators/returns.js +2 -1
- package/src/decorators/scope.js +1 -1
- package/src/decorators/transacted.js +1 -1
- package/src/index.js +0 -1
- package/src/middleware/createTransaction.js +1 -1
- package/src/models/Model.js +1 -1
- package/src/models/definitions/assets.js +1 -1
- package/src/models/definitions/filters.js +2 -1
- package/src/models/definitions/hooks.js +1 -1
- package/src/models/definitions/modifiers.js +1 -1
- package/src/models/definitions/options.js +1 -1
- package/src/models/definitions/properties.js +1 -1
- package/src/models/definitions/relations.js +1 -1
- package/src/models/definitions/schema.js +1 -1
- package/src/models/definitions/scopes.js +1 -1
- package/src/query/QueryBuilder.js +3 -1
- package/src/services/Service.js +1 -1
- package/src/storage/DiskStorage.js +0 -1
- package/src/storage/S3Storage.js +4 -6
- package/src/storage/Storage.js +6 -4
- package/src/utils/fs.js +10 -0
- package/types/index.d.ts +46 -64
- package/src/utils/index.js +0 -10
- /package/src/utils/{date.js → duration.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ditojs/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.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",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"node >= 18"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@ditojs/admin": "^1.
|
|
25
|
+
"@ditojs/admin": "^1.27.0",
|
|
26
26
|
"@ditojs/build": "^1.25.0",
|
|
27
|
-
"@ditojs/router": "^1.
|
|
28
|
-
"@ditojs/utils": "^1.
|
|
27
|
+
"@ditojs/router": "^1.27.0",
|
|
28
|
+
"@ditojs/utils": "^1.27.0",
|
|
29
29
|
"@koa/cors": "^4.0.0",
|
|
30
30
|
"@koa/multer": "^3.0.2",
|
|
31
31
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"koa-static": "^5.0.0",
|
|
52
52
|
"mime-types": "^2.1.35",
|
|
53
53
|
"multer": "^1.4.5-lts.1",
|
|
54
|
-
"multer-s3": "
|
|
54
|
+
"multer-s3": "https://github.com/ditojs/multer-s3#dito",
|
|
55
55
|
"nanoid": "^4.0.1",
|
|
56
56
|
"parse-duration": "^1.0.3",
|
|
57
57
|
"passport-local": "^1.0.0",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"typescript": "^4.9.5"
|
|
91
91
|
},
|
|
92
92
|
"types": "types",
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "96b1437fc3950eb8259d40b93501e1a7e32ebb0e",
|
|
94
94
|
"scripts": {
|
|
95
95
|
"types": "tsc --noEmit ./src/index.d.ts"
|
|
96
96
|
},
|
package/src/app/Application.js
CHANGED
|
@@ -31,7 +31,8 @@ import { Controller, AdminController } from '../controllers/index.js'
|
|
|
31
31
|
import { Service } from '../services/index.js'
|
|
32
32
|
import { Storage } from '../storage/index.js'
|
|
33
33
|
import { convertSchema } from '../schema/index.js'
|
|
34
|
-
import { getDuration, subtractDuration
|
|
34
|
+
import { getDuration, subtractDuration } from '../utils/duration.js'
|
|
35
|
+
import { deprecate } from '../utils/deprecate.js'
|
|
35
36
|
import {
|
|
36
37
|
ResponseError,
|
|
37
38
|
ValidationError,
|
|
@@ -860,31 +861,30 @@ export class Application extends Koa {
|
|
|
860
861
|
const { url } = file
|
|
861
862
|
if (!storage.isImportSourceAllowed(url)) {
|
|
862
863
|
throw new AssetError(
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
864
|
+
`Unable to import asset from foreign source: '${
|
|
865
|
+
file.name
|
|
866
|
+
}' ('${
|
|
867
|
+
url
|
|
868
|
+
}'): The source needs to be explicitly allowed.`
|
|
868
869
|
)
|
|
869
870
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
pico.green(`'${storage.name}'`)
|
|
879
|
-
}...`
|
|
871
|
+
this.logger.info(
|
|
872
|
+
`Asset ${
|
|
873
|
+
pico.green(`'${file.name}'`)
|
|
874
|
+
} is from a foreign source, fetching from ${
|
|
875
|
+
pico.green(`'${url}'`)
|
|
876
|
+
} and adding to storage ${
|
|
877
|
+
pico.green(`'${storage.name}'`)
|
|
878
|
+
}...`
|
|
880
879
|
)
|
|
881
880
|
if (url.startsWith('file://')) {
|
|
882
881
|
const filepath = path.resolve(url.substring(7))
|
|
883
882
|
data = await fs.readFile(filepath)
|
|
884
883
|
} else {
|
|
885
884
|
const response = await fetch(url)
|
|
886
|
-
const
|
|
887
|
-
|
|
885
|
+
const arrayBuffer = await response.arrayBuffer()
|
|
886
|
+
// `fs.writeFile()` expects a Buffer, not an ArrayBuffer.
|
|
887
|
+
data = Buffer.from(arrayBuffer)
|
|
888
888
|
}
|
|
889
889
|
}
|
|
890
890
|
const importedFile = await storage.addFile(file, data)
|
|
@@ -896,11 +896,11 @@ export class Application extends Koa {
|
|
|
896
896
|
importedFiles.push(importedFile)
|
|
897
897
|
} else {
|
|
898
898
|
throw new AssetError(
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
899
|
+
`Unable to import asset from foreign source: '${
|
|
900
|
+
file.name
|
|
901
|
+
}' ('${
|
|
902
|
+
file.key
|
|
903
|
+
}')`
|
|
904
904
|
)
|
|
905
905
|
}
|
|
906
906
|
} else {
|
package/src/app/Validator.js
CHANGED
|
@@ -2,7 +2,7 @@ import objection from 'objection'
|
|
|
2
2
|
import Ajv from 'ajv/dist/2020.js'
|
|
3
3
|
import addFormats from 'ajv-formats'
|
|
4
4
|
import { isArray, isObject, clone, isAsync, isPromise } from '@ditojs/utils'
|
|
5
|
-
import { formatJson } from '../utils/
|
|
5
|
+
import { formatJson } from '../utils/json.js'
|
|
6
6
|
import * as schema from '../schema/index.js'
|
|
7
7
|
|
|
8
8
|
// Dito does not rely on objection.AjvValidator but instead implements its own
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs/promises'
|
|
3
3
|
import pico from 'picocolors'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getRelationClass,
|
|
6
|
+
isThroughRelationClass
|
|
7
|
+
} from '@ditojs/server'
|
|
5
8
|
import {
|
|
6
9
|
isObject, isArray, isString, deindent, capitalize
|
|
7
10
|
} from '@ditojs/utils'
|
|
11
|
+
import { exists } from '../../utils/fs.js'
|
|
8
12
|
|
|
9
13
|
const typeToKnex = {
|
|
10
14
|
number: 'double',
|
|
@@ -204,12 +208,3 @@ function getTimestamp() {
|
|
|
204
208
|
padDate(d.getMinutes()) +
|
|
205
209
|
padDate(d.getSeconds())
|
|
206
210
|
}
|
|
207
|
-
|
|
208
|
-
async function exists(path) {
|
|
209
|
-
try {
|
|
210
|
-
await fs.access(path)
|
|
211
|
-
return true
|
|
212
|
-
} catch {
|
|
213
|
-
return false
|
|
214
|
-
}
|
|
215
|
-
}
|
|
@@ -15,7 +15,9 @@ import { merge } from '@ditojs/utils'
|
|
|
15
15
|
import { Controller } from './Controller.js'
|
|
16
16
|
import { handleConnectMiddleware } from '../middleware/index.js'
|
|
17
17
|
import { ControllerError } from '../errors/index.js'
|
|
18
|
-
import {
|
|
18
|
+
import { getRandomFreePort } from '../utils/net.js'
|
|
19
|
+
import { formatJson } from '../utils/json.js'
|
|
20
|
+
import { deprecate } from '../utils/deprecate.js'
|
|
19
21
|
|
|
20
22
|
export class AdminController extends Controller {
|
|
21
23
|
// @override
|
|
@@ -24,6 +24,7 @@ export class CollectionController extends Controller {
|
|
|
24
24
|
|
|
25
25
|
// @override
|
|
26
26
|
setup() {
|
|
27
|
+
this.logController()
|
|
27
28
|
this.collection = this.setupActions('collection')
|
|
28
29
|
this.member = this.isOneToOne ? {} : this.setupActions('member')
|
|
29
30
|
this.assets = this.setupAssets()
|
|
@@ -6,9 +6,12 @@ import {
|
|
|
6
6
|
ResponseError, ControllerError, AuthorizationError
|
|
7
7
|
} from '../errors/index.js'
|
|
8
8
|
import {
|
|
9
|
-
getOwnProperty, getOwnKeys, getAllKeys, getInheritanceChain
|
|
10
|
-
|
|
11
|
-
} from '../utils/
|
|
9
|
+
getOwnProperty, getOwnKeys, getAllKeys, getInheritanceChain
|
|
10
|
+
} from '../utils/object.js'
|
|
11
|
+
import { processHandlerParameters } from '../utils/handler.js'
|
|
12
|
+
import { describeFunction } from '../utils/function.js'
|
|
13
|
+
import { formatJson } from '../utils/json.js'
|
|
14
|
+
import { deprecate } from '../utils/deprecate.js'
|
|
12
15
|
import {
|
|
13
16
|
isObject, isString, isArray, isBoolean, isFunction, asArray, equals,
|
|
14
17
|
parseDataPath, normalizeDataPath
|
|
@@ -26,7 +29,7 @@ export class Controller {
|
|
|
26
29
|
constructor(app, namespace) {
|
|
27
30
|
this.app = app
|
|
28
31
|
this.namespace = namespace
|
|
29
|
-
this.
|
|
32
|
+
this.logRoutes = this.app.config.log.routes
|
|
30
33
|
this.level = 0
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -60,21 +63,12 @@ export class Controller {
|
|
|
60
63
|
// mapped parameters or wildcards. Consider `path` / `route` instead?
|
|
61
64
|
const url = path ? `/${path}` : ''
|
|
62
65
|
this.url = namespace ? `/${namespace}${url}` : url
|
|
63
|
-
this.log(
|
|
64
|
-
`${
|
|
65
|
-
namespace ? pico.green(`/${namespace}/`) : ''
|
|
66
|
-
}${
|
|
67
|
-
pico.cyan(path)
|
|
68
|
-
}${
|
|
69
|
-
pico.white(':')
|
|
70
|
-
}`,
|
|
71
|
-
this.level
|
|
72
|
-
)
|
|
73
66
|
}
|
|
74
67
|
}
|
|
75
68
|
|
|
76
69
|
// @overridable
|
|
77
70
|
setup() {
|
|
71
|
+
this.logController()
|
|
78
72
|
this.actions ||= this.reflectActionsObject()
|
|
79
73
|
// Now that the instance fields are reflected in the `controller` object
|
|
80
74
|
// we can use the normal inheritance mechanism through `setupActions()`:
|
|
@@ -94,6 +88,40 @@ export class Controller {
|
|
|
94
88
|
// middleware. For normal routes, use `this.app.addRoute()` instead.
|
|
95
89
|
}
|
|
96
90
|
|
|
91
|
+
// @overridable
|
|
92
|
+
logController() {
|
|
93
|
+
const { path, namespace } = this
|
|
94
|
+
this.logRoute(
|
|
95
|
+
`${
|
|
96
|
+
namespace ? pico.green(`/${namespace}/`) : ''
|
|
97
|
+
}${
|
|
98
|
+
pico.cyan(path)
|
|
99
|
+
}${
|
|
100
|
+
pico.white(':')
|
|
101
|
+
}`,
|
|
102
|
+
this.level
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
logRoute(str, indent = 0) {
|
|
107
|
+
if (this.logRoutes) {
|
|
108
|
+
console.info(`${' '.repeat(indent)}${str}`)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Only use this method to get a logger instance that is bound to the context,
|
|
113
|
+
// otherwise use the cached getter.
|
|
114
|
+
getLogger(ctx) {
|
|
115
|
+
const logger = ctx?.logger ?? this.app.logger
|
|
116
|
+
return logger.child({ name: this.name })
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get logger() {
|
|
120
|
+
const value = this.getLogger()
|
|
121
|
+
Object.defineProperty(this, 'logger', { value })
|
|
122
|
+
return value
|
|
123
|
+
}
|
|
124
|
+
|
|
97
125
|
reflectActionsObject() {
|
|
98
126
|
// On base controllers, the actions can be defined directly in the class
|
|
99
127
|
// instead of inside an actions object, as is done with model and relation
|
|
@@ -122,7 +150,7 @@ export class Controller {
|
|
|
122
150
|
}
|
|
123
151
|
|
|
124
152
|
setupRoute(method, url, transacted, authorize, action, middlewares) {
|
|
125
|
-
this.
|
|
153
|
+
this.logRoute(
|
|
126
154
|
`${
|
|
127
155
|
pico.magenta(method.toUpperCase())
|
|
128
156
|
} ${
|
|
@@ -382,7 +410,6 @@ export class Controller {
|
|
|
382
410
|
// so add its own keys to the already allowed inherited keys so far.
|
|
383
411
|
Object.assign(allowMap, getFilteredMap(getOwnKeys(current)))
|
|
384
412
|
}
|
|
385
|
-
// console.log('allow', Object.keys(allowMap))
|
|
386
413
|
}
|
|
387
414
|
|
|
388
415
|
const handleAuthorize = authorize => {
|
|
@@ -538,12 +565,6 @@ export class Controller {
|
|
|
538
565
|
throw new AuthorizationError()
|
|
539
566
|
}
|
|
540
567
|
}
|
|
541
|
-
|
|
542
|
-
log(str, indent = 0) {
|
|
543
|
-
if (this.logging) {
|
|
544
|
-
console.info(`${' '.repeat(indent)}${str}`)
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
568
|
}
|
|
548
569
|
|
|
549
570
|
EventEmitter.mixin(Controller.prototype)
|
|
@@ -3,7 +3,7 @@ import { isObject, camelize } from '@ditojs/utils'
|
|
|
3
3
|
import { CollectionController } from './CollectionController.js'
|
|
4
4
|
import { RelationController } from './RelationController.js'
|
|
5
5
|
import { ControllerError } from '../errors/index.js'
|
|
6
|
-
import { setupPropertyInheritance } from '../utils/
|
|
6
|
+
import { setupPropertyInheritance } from '../utils/object.js'
|
|
7
7
|
|
|
8
8
|
export class ModelController extends CollectionController {
|
|
9
9
|
configure() {
|
|
@@ -2,7 +2,8 @@ import pico from 'picocolors'
|
|
|
2
2
|
import { asArray } from '@ditojs/utils'
|
|
3
3
|
import { CollectionController } from './CollectionController.js'
|
|
4
4
|
import { ControllerError } from '../errors/index.js'
|
|
5
|
-
import { setupPropertyInheritance
|
|
5
|
+
import { setupPropertyInheritance } from '../utils/object.js'
|
|
6
|
+
import { getScope } from '../utils/scope.js'
|
|
6
7
|
|
|
7
8
|
export class RelationController extends CollectionController {
|
|
8
9
|
constructor(parent, object, relationInstance, relationDefinition) {
|
|
@@ -48,6 +49,11 @@ export class RelationController extends CollectionController {
|
|
|
48
49
|
super.configure()
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
// @override
|
|
53
|
+
logController() {
|
|
54
|
+
// The parent controller logs itself already, that's enough.
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
// @override
|
|
52
58
|
inheritValues(type) {
|
|
53
59
|
// Since RelationController are mapped to nested `relations` objects in
|
package/src/decorators/action.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { isArray, isObject } from '@ditojs/utils'
|
|
2
|
-
import { createDecorator
|
|
2
|
+
import { createDecorator } from '../utils/decorator.js'
|
|
3
|
+
import { formatJson } from '../utils/json.js'
|
|
4
|
+
import { deprecate } from '../utils/deprecate.js'
|
|
3
5
|
|
|
4
6
|
export function parameters(parameters, options) {
|
|
5
7
|
if (isObject(parameters)) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isObject } from '@ditojs/utils'
|
|
2
|
-
import { createDecorator
|
|
2
|
+
import { createDecorator } from '../utils/decorator.js'
|
|
3
|
+
import { formatJson } from '../utils/json.js'
|
|
3
4
|
|
|
4
5
|
export function returns(returns, options) {
|
|
5
6
|
if (!isObject(returns)) {
|
package/src/decorators/scope.js
CHANGED
package/src/index.js
CHANGED
package/src/models/Model.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
convertRelations
|
|
13
13
|
} from '../schema/index.js'
|
|
14
14
|
import { populateGraph, filterGraph } from '../graph/index.js'
|
|
15
|
-
import { formatJson } from '../utils/
|
|
15
|
+
import { formatJson } from '../utils/json.js'
|
|
16
16
|
import {
|
|
17
17
|
ResponseError,
|
|
18
18
|
GraphError, ModelError,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isObject, isFunction } from '@ditojs/utils'
|
|
2
|
-
import {
|
|
2
|
+
import { processHandlerParameters } from '../../utils/handler.js'
|
|
3
|
+
import { mergeReversed } from '../../utils/object.js'
|
|
3
4
|
import { QueryFilters } from '../../query/index.js'
|
|
4
5
|
|
|
5
6
|
export default function filters(values) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isObject, isFunction } from '@ditojs/utils'
|
|
2
2
|
import { ModelError } from '../../errors/index.js'
|
|
3
|
-
import { mergeReversed } from '../../utils/
|
|
3
|
+
import { mergeReversed } from '../../utils/object.js'
|
|
4
4
|
|
|
5
5
|
export default function scopes(values) {
|
|
6
6
|
const scopes = {}
|
|
@@ -7,7 +7,9 @@ import { QueryParameters } from './QueryParameters.js'
|
|
|
7
7
|
import { KnexHelper } from '../lib/index.js'
|
|
8
8
|
import { DitoGraphProcessor, walkGraph } from '../graph/index.js'
|
|
9
9
|
import { QueryBuilderError, RelationError } from '../errors/index.js'
|
|
10
|
-
import { createLookup
|
|
10
|
+
import { createLookup } from '../utils/object.js'
|
|
11
|
+
import { getScope } from '../utils/scope.js'
|
|
12
|
+
import { deprecate } from '../utils/deprecate.js'
|
|
11
13
|
|
|
12
14
|
const SYMBOL_ALL = Symbol('all')
|
|
13
15
|
|
package/src/services/Service.js
CHANGED
|
@@ -32,7 +32,7 @@ export class Service {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// Only use this method to get a logger instance that is bound to the context,
|
|
35
|
-
// otherwise use the getter.
|
|
35
|
+
// otherwise use the cached getter.
|
|
36
36
|
getLogger(ctx) {
|
|
37
37
|
const logger = ctx?.logger ?? this.app.logger
|
|
38
38
|
return logger.child({ name: this.#loggerName })
|
package/src/storage/S3Storage.js
CHANGED
|
@@ -111,12 +111,10 @@ export class S3Storage extends Storage {
|
|
|
111
111
|
ContentType: file.type,
|
|
112
112
|
Body: data
|
|
113
113
|
})
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
location: result.Location
|
|
119
|
-
}
|
|
114
|
+
// In `Storage.addFile()` this will get overridden with the result of
|
|
115
|
+
// `_getUrl()` if it exists, but is used as a fallback otherwise,
|
|
116
|
+
// see `_getFileUrl()`.
|
|
117
|
+
file.url = result.Location
|
|
120
118
|
}
|
|
121
119
|
|
|
122
120
|
// @override
|
package/src/storage/Storage.js
CHANGED
|
@@ -18,7 +18,9 @@ export class Storage {
|
|
|
18
18
|
this.name = config.name
|
|
19
19
|
this.url = config.url
|
|
20
20
|
this.path = config.path
|
|
21
|
-
|
|
21
|
+
// Use a default concurrency of 8 for storage IO, e.g. the importing of
|
|
22
|
+
// foreign assets.
|
|
23
|
+
this.concurrency = config.concurrency ?? 8
|
|
22
24
|
// The actual multer storage object.
|
|
23
25
|
this.storage = null
|
|
24
26
|
}
|
|
@@ -96,10 +98,10 @@ export class Storage {
|
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
async addFile(file, data) {
|
|
99
|
-
|
|
101
|
+
await this._addFile(file, data)
|
|
100
102
|
file.size = Buffer.byteLength(data)
|
|
101
|
-
file.url = this._getFileUrl(
|
|
102
|
-
// TODO: Support `config.readImageSize`, but this can only be done
|
|
103
|
+
file.url = this._getFileUrl(file)
|
|
104
|
+
// TODO: Support `config.readImageSize`, but this can only be done once
|
|
103
105
|
// there are separate storage instances per model assets config!
|
|
104
106
|
return this.convertAssetFile(file)
|
|
105
107
|
}
|
package/src/utils/fs.js
ADDED
package/types/index.d.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
// Export the entire Dito namespace.
|
|
7
7
|
|
|
8
|
+
import { ObjectCannedACL, S3ClientConfig } from '@aws-sdk/client-s3'
|
|
8
9
|
import { DateFormat } from '@dito/utils'
|
|
9
10
|
import koaCors from '@koa/cors'
|
|
10
11
|
import * as Ajv from 'ajv/dist/2020.js'
|
|
11
|
-
import * as aws from 'aws-sdk'
|
|
12
12
|
import * as dbErrors from 'db-errors'
|
|
13
13
|
import * as EventEmitter2 from 'eventemitter2'
|
|
14
14
|
import helmet from 'helmet'
|
|
@@ -21,6 +21,7 @@ import mount from 'koa-mount'
|
|
|
21
21
|
import koaPinoLogger from 'koa-pino-logger'
|
|
22
22
|
import koaResponseTime from 'koa-response-time'
|
|
23
23
|
import koaSession from 'koa-session'
|
|
24
|
+
import multerS3 from 'multer-s3'
|
|
24
25
|
import * as objection from 'objection'
|
|
25
26
|
import { KnexSnakeCaseMappersFactory } from 'objection'
|
|
26
27
|
import { Logger } from 'pino'
|
|
@@ -212,61 +213,39 @@ export type MulterS3File = {
|
|
|
212
213
|
|
|
213
214
|
export type StorageConfigs = { [key: string]: StorageConfig }
|
|
214
215
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
| 'DEEP_ARCHIVE'
|
|
249
|
-
>
|
|
250
|
-
/**
|
|
251
|
-
* The server-side encryption algorithm used when storing this object in
|
|
252
|
-
* Amazon S3 (for example, AES256, aws:kms).
|
|
253
|
-
*/
|
|
254
|
-
serverSideEncryption?: aws.S3.ServerSideEncryption
|
|
255
|
-
/**
|
|
256
|
-
* If present, specifies the ID of the AWS Key Management Service (AWS
|
|
257
|
-
* KMS) symmetric customer managed customer master key (CMK)
|
|
258
|
-
*/
|
|
259
|
-
sseKmsKeyId?: aws.S3.SSEKMSKeyId
|
|
260
|
-
s3: aws.S3.ClientConfiguration
|
|
261
|
-
url?: string
|
|
262
|
-
}
|
|
263
|
-
| {
|
|
264
|
-
type: 'disk'
|
|
265
|
-
path: string
|
|
266
|
-
url?: string
|
|
267
|
-
mount?: string
|
|
268
|
-
allowedImports?: string[]
|
|
269
|
-
}
|
|
216
|
+
type CommonStorageConfig = {
|
|
217
|
+
/**
|
|
218
|
+
* The concurrency at which assets are added to storage.
|
|
219
|
+
*
|
|
220
|
+
* @default `8`
|
|
221
|
+
*/
|
|
222
|
+
concurrency?: number
|
|
223
|
+
/**
|
|
224
|
+
* The base URL at which assets are accessible.
|
|
225
|
+
*/
|
|
226
|
+
url?: string
|
|
227
|
+
allowedImports?: string[]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export type S3StorageConfig = CommonStorageConfig & {
|
|
231
|
+
type: 's3'
|
|
232
|
+
bucket: string
|
|
233
|
+
acl?: ObjectCannedACL | string
|
|
234
|
+
s3: S3ClientConfig
|
|
235
|
+
} & Omit<
|
|
236
|
+
Parameters<typeof multerS3>[0],
|
|
237
|
+
's3' | 'key' | 'contentType' | 'metadata'
|
|
238
|
+
>
|
|
239
|
+
|
|
240
|
+
export type DiskStorageConfig = CommonStorageConfig & {
|
|
241
|
+
type: 'disk'
|
|
242
|
+
/**
|
|
243
|
+
* The path to the directory where assets are stored on.
|
|
244
|
+
*/
|
|
245
|
+
path: string
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export type StorageConfig = S3StorageConfig | DiskStorageConfig
|
|
270
249
|
|
|
271
250
|
export interface AdminConfig {
|
|
272
251
|
api?: ApiConfig
|
|
@@ -784,8 +763,7 @@ export class Model extends objection.Model {
|
|
|
784
763
|
static whereJsonSubsetOf: StaticQueryBuilderMethod<'whereJsonSubsetOf'>
|
|
785
764
|
static whereJsonNotSubsetOf: StaticQueryBuilderMethod<'whereJsonNotSubsetOf'>
|
|
786
765
|
static whereJsonSupersetOf: StaticQueryBuilderMethod<'whereJsonSupersetOf'>
|
|
787
|
-
static whereJsonNotSupersetOf:
|
|
788
|
-
StaticQueryBuilderMethod<'whereJsonNotSupersetOf'>
|
|
766
|
+
static whereJsonNotSupersetOf: StaticQueryBuilderMethod<'whereJsonNotSupersetOf'>
|
|
789
767
|
|
|
790
768
|
static having: StaticQueryBuilderMethod<'having'>
|
|
791
769
|
static havingIn: StaticQueryBuilderMethod<'havingIn'>
|
|
@@ -885,6 +863,16 @@ export class Controller {
|
|
|
885
863
|
initialize(): Promise<void>
|
|
886
864
|
// TODO: type reflectActionsObject
|
|
887
865
|
reflectActionsObject(): any
|
|
866
|
+
/**
|
|
867
|
+
* @overridable
|
|
868
|
+
*/
|
|
869
|
+
logController(): void
|
|
870
|
+
/**
|
|
871
|
+
* @param str The string to log.
|
|
872
|
+
* @param [indent=0] The amount of levels to indent (in pairs of two spaces).
|
|
873
|
+
* Default is `0`
|
|
874
|
+
*/
|
|
875
|
+
logRoute(str: string, indent?: number): void
|
|
888
876
|
setupRoute<$ControllerAction extends ControllerAction = ControllerAction>(
|
|
889
877
|
method: HTTPMethod,
|
|
890
878
|
url: string,
|
|
@@ -930,12 +918,6 @@ export class Controller {
|
|
|
930
918
|
processAuthorize(authorize: any): any
|
|
931
919
|
describeAuthorize(authorize: any): string
|
|
932
920
|
handleAuthorization(): Promise<void>
|
|
933
|
-
/**
|
|
934
|
-
* @param str The string to log.
|
|
935
|
-
* @param [indent=0] The amount of levels to indent (in pairs of two spaces).
|
|
936
|
-
* Default is `0`
|
|
937
|
-
*/
|
|
938
|
-
log(str: string, indent?: number): void
|
|
939
921
|
}
|
|
940
922
|
|
|
941
923
|
export type ActionParameter = Schema & { name: string }
|
package/src/utils/index.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export * from './date.js'
|
|
2
|
-
export * from './decorator.js'
|
|
3
|
-
export * from './deprecate.js'
|
|
4
|
-
export * from './emitter.js'
|
|
5
|
-
export * from './function.js'
|
|
6
|
-
export * from './handler.js'
|
|
7
|
-
export * from './json.js'
|
|
8
|
-
export * from './net.js'
|
|
9
|
-
export * from './object.js'
|
|
10
|
-
export * from './scope.js'
|
|
File without changes
|