@radio-garden/ditojs-server 2.85.2-0.5067ad799
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/README.md +6 -0
- package/package.json +95 -0
- package/src/app/Application.js +1186 -0
- package/src/app/Validator.js +405 -0
- package/src/app/index.js +2 -0
- package/src/cli/console.js +152 -0
- package/src/cli/db/createMigration.js +241 -0
- package/src/cli/db/index.js +7 -0
- package/src/cli/db/listAssetConfig.js +10 -0
- package/src/cli/db/migrate.js +12 -0
- package/src/cli/db/reset.js +23 -0
- package/src/cli/db/rollback.js +12 -0
- package/src/cli/db/seed.js +80 -0
- package/src/cli/db/unlock.js +9 -0
- package/src/cli/index.js +72 -0
- package/src/controllers/AdminController.js +322 -0
- package/src/controllers/CollectionController.js +274 -0
- package/src/controllers/Controller.js +657 -0
- package/src/controllers/ControllerAction.js +370 -0
- package/src/controllers/MemberAction.js +27 -0
- package/src/controllers/ModelController.js +63 -0
- package/src/controllers/RelationController.js +93 -0
- package/src/controllers/UsersController.js +64 -0
- package/src/controllers/index.js +5 -0
- package/src/errors/AssetError.js +7 -0
- package/src/errors/AuthenticationError.js +7 -0
- package/src/errors/AuthorizationError.js +7 -0
- package/src/errors/ControllerError.js +14 -0
- package/src/errors/DatabaseError.js +37 -0
- package/src/errors/GraphError.js +7 -0
- package/src/errors/ModelError.js +12 -0
- package/src/errors/NotFoundError.js +7 -0
- package/src/errors/NotImplementedError.js +7 -0
- package/src/errors/QueryBuilderError.js +7 -0
- package/src/errors/RelationError.js +21 -0
- package/src/errors/ResponseError.js +56 -0
- package/src/errors/ValidationError.js +7 -0
- package/src/errors/index.js +13 -0
- package/src/graph/DitoGraphProcessor.js +213 -0
- package/src/graph/expression.js +53 -0
- package/src/graph/graph.js +258 -0
- package/src/graph/index.js +3 -0
- package/src/index.js +9 -0
- package/src/lib/EventEmitter.js +66 -0
- package/src/lib/KnexHelper.js +30 -0
- package/src/lib/index.js +2 -0
- package/src/middleware/attachLogger.js +8 -0
- package/src/middleware/createTransaction.js +33 -0
- package/src/middleware/extendContext.js +10 -0
- package/src/middleware/findRoute.js +20 -0
- package/src/middleware/handleConnectMiddleware.js +99 -0
- package/src/middleware/handleError.js +29 -0
- package/src/middleware/handleRoute.js +23 -0
- package/src/middleware/handleSession.js +77 -0
- package/src/middleware/handleUser.js +31 -0
- package/src/middleware/index.js +11 -0
- package/src/middleware/logRequests.js +125 -0
- package/src/middleware/setupRequestStorage.js +14 -0
- package/src/mixins/AssetMixin.js +78 -0
- package/src/mixins/SessionMixin.js +17 -0
- package/src/mixins/TimeStampedMixin.js +41 -0
- package/src/mixins/UserMixin.js +171 -0
- package/src/mixins/index.js +4 -0
- package/src/models/AssetModel.js +4 -0
- package/src/models/Model.js +1205 -0
- package/src/models/RelationAccessor.js +41 -0
- package/src/models/SessionModel.js +4 -0
- package/src/models/TimeStampedModel.js +4 -0
- package/src/models/UserModel.js +4 -0
- package/src/models/definitions/assets.js +5 -0
- package/src/models/definitions/filters.js +121 -0
- package/src/models/definitions/hooks.js +8 -0
- package/src/models/definitions/index.js +22 -0
- package/src/models/definitions/modifiers.js +5 -0
- package/src/models/definitions/options.js +5 -0
- package/src/models/definitions/properties.js +73 -0
- package/src/models/definitions/relations.js +5 -0
- package/src/models/definitions/schema.js +5 -0
- package/src/models/definitions/scopes.js +36 -0
- package/src/models/index.js +5 -0
- package/src/query/QueryBuilder.js +1077 -0
- package/src/query/QueryFilters.js +66 -0
- package/src/query/QueryParameters.js +79 -0
- package/src/query/Registry.js +29 -0
- package/src/query/index.js +3 -0
- package/src/schema/formats/_empty.js +4 -0
- package/src/schema/formats/_required.js +4 -0
- package/src/schema/formats/index.js +2 -0
- package/src/schema/index.js +5 -0
- package/src/schema/keywords/_computed.js +7 -0
- package/src/schema/keywords/_foreign.js +7 -0
- package/src/schema/keywords/_hidden.js +7 -0
- package/src/schema/keywords/_index.js +7 -0
- package/src/schema/keywords/_instanceof.js +45 -0
- package/src/schema/keywords/_primary.js +7 -0
- package/src/schema/keywords/_range.js +18 -0
- package/src/schema/keywords/_relate.js +13 -0
- package/src/schema/keywords/_specificType.js +7 -0
- package/src/schema/keywords/_unique.js +7 -0
- package/src/schema/keywords/_unsigned.js +7 -0
- package/src/schema/keywords/_validate.js +73 -0
- package/src/schema/keywords/index.js +12 -0
- package/src/schema/relations.js +324 -0
- package/src/schema/relations.test.js +177 -0
- package/src/schema/schema.js +289 -0
- package/src/schema/schema.test.js +720 -0
- package/src/schema/types/_asset.js +31 -0
- package/src/schema/types/_color.js +4 -0
- package/src/schema/types/index.js +2 -0
- package/src/services/Service.js +35 -0
- package/src/services/index.js +1 -0
- package/src/storage/AssetFile.js +81 -0
- package/src/storage/DiskStorage.js +114 -0
- package/src/storage/S3Storage.js +169 -0
- package/src/storage/Storage.js +231 -0
- package/src/storage/index.js +9 -0
- package/src/utils/duration.js +15 -0
- package/src/utils/emitter.js +8 -0
- package/src/utils/fs.js +10 -0
- package/src/utils/function.js +17 -0
- package/src/utils/function.test.js +77 -0
- package/src/utils/handler.js +17 -0
- package/src/utils/json.js +3 -0
- package/src/utils/model.js +35 -0
- package/src/utils/net.js +17 -0
- package/src/utils/object.js +82 -0
- package/src/utils/object.test.js +86 -0
- package/src/utils/scope.js +7 -0
- package/types/index.d.ts +3547 -0
- package/types/tests/application.test-d.ts +26 -0
- package/types/tests/controller.test-d.ts +113 -0
- package/types/tests/errors.test-d.ts +53 -0
- package/types/tests/fixtures.ts +19 -0
- package/types/tests/model.test-d.ts +193 -0
- package/types/tests/query-builder.test-d.ts +106 -0
- package/types/tests/relation.test-d.ts +83 -0
- package/types/tests/storage.test-d.ts +113 -0
package/src/utils/fs.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function describeFunction(func) {
|
|
2
|
+
// A helper that describes a method by turning it int a short version without
|
|
3
|
+
// printing its body.
|
|
4
|
+
const match = func.toString().match(
|
|
5
|
+
/^\s*(async\s*|)(?:function[^(]*\(([^)]*)\)|\(([^)]*)\)\s*=>|(\S*)\s*=>)\s*(.)/
|
|
6
|
+
)
|
|
7
|
+
if (match) {
|
|
8
|
+
const body = match[5] === '{' ? '{ ... }' : '...'
|
|
9
|
+
return match[2] !== undefined
|
|
10
|
+
? `${match[1]}function (${match[2]}) ${body}`
|
|
11
|
+
: match[3] !== undefined
|
|
12
|
+
? `${match[1]}(${match[3]}) => ${body}`
|
|
13
|
+
: match[4] !== undefined
|
|
14
|
+
? `${match[1]}${match[4]} => ${body}`
|
|
15
|
+
: ''
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describeFunction } from './function.js'
|
|
2
|
+
|
|
3
|
+
describe('describeFunction()', () => {
|
|
4
|
+
it('describes normal functions', () => {
|
|
5
|
+
expect(
|
|
6
|
+
describeFunction(function (a, b, c) {
|
|
7
|
+
return a + b + c
|
|
8
|
+
})
|
|
9
|
+
)
|
|
10
|
+
.toBe('function (a, b, c) { ... }')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('describes lambdas with one param and a body', () => {
|
|
14
|
+
expect(
|
|
15
|
+
describeFunction(a => {
|
|
16
|
+
return a
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
.toBe('a => { ... }')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('describes lambdas with one param and no body', () => {
|
|
23
|
+
expect(describeFunction(a => a))
|
|
24
|
+
.toBe('a => ...')
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('describes lambdas with multiple params and a body', () => {
|
|
28
|
+
expect(
|
|
29
|
+
describeFunction((a, b, c) => {
|
|
30
|
+
return a + b + c
|
|
31
|
+
})
|
|
32
|
+
)
|
|
33
|
+
.toBe('(a, b, c) => { ... }')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('describes lambdas with multiple params and no body', () => {
|
|
37
|
+
expect(describeFunction((a, b, c) => a + b + c))
|
|
38
|
+
.toBe('(a, b, c) => ...')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('describes async functions', () => {
|
|
42
|
+
expect(
|
|
43
|
+
describeFunction(async function (a, b, c) {
|
|
44
|
+
return a + b + c
|
|
45
|
+
})
|
|
46
|
+
)
|
|
47
|
+
.toBe('async function (a, b, c) { ... }')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('describes async lambdas with one param and a body', () => {
|
|
51
|
+
expect(
|
|
52
|
+
describeFunction(async a => {
|
|
53
|
+
return a
|
|
54
|
+
})
|
|
55
|
+
)
|
|
56
|
+
.toBe('async a => { ... }')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('describes async lambdas with one param and no body', () => {
|
|
60
|
+
expect(describeFunction(async a => a))
|
|
61
|
+
.toBe('async a => ...')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('describes async lambdas with multiple params and a body', () => {
|
|
65
|
+
expect(
|
|
66
|
+
describeFunction(async (a, b, c) => {
|
|
67
|
+
return a + b + c
|
|
68
|
+
})
|
|
69
|
+
)
|
|
70
|
+
.toBe('async (a, b, c) => { ... }')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('describes async lambdas with multiple params and no body', () => {
|
|
74
|
+
expect(describeFunction(async (a, b, c) => a + b + c))
|
|
75
|
+
.toBe('async (a, b, c) => ...')
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { asArray } from '@ditojs/utils'
|
|
2
|
+
|
|
3
|
+
export function processHandlerParameters(handler, name, value) {
|
|
4
|
+
if (value) {
|
|
5
|
+
const [schema, options] = asArray(value)
|
|
6
|
+
handler[name] = schema
|
|
7
|
+
|
|
8
|
+
// If validation options are provided, expose them through
|
|
9
|
+
// `handler.options[name]`, see `ControllerAction`.
|
|
10
|
+
if (options) {
|
|
11
|
+
handler.options = {
|
|
12
|
+
...handler.options,
|
|
13
|
+
[name]: options
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { isPlainObject, isPlainArray } from '@ditojs/utils'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts Models to their external representation by calling the `$toJson()`
|
|
5
|
+
* method. It does not create a JSON string, but a plain object. It is necessary
|
|
6
|
+
* to do this before the validation is performed, otherwise different properties
|
|
7
|
+
* might end up in the Json response. This is done recursively, so that nested
|
|
8
|
+
* models are also converted. Streams, Buffers and other non plain objects are
|
|
9
|
+
* left as-is, so this can directly be used on any results.
|
|
10
|
+
*/
|
|
11
|
+
export function convertModelsToJson(value) {
|
|
12
|
+
return value?.$isObjectionModel
|
|
13
|
+
? value.$toJson()
|
|
14
|
+
: isPlainObject(value)
|
|
15
|
+
? convertToJsonObject(value)
|
|
16
|
+
: isPlainArray(value)
|
|
17
|
+
? convertToJsonArray(value)
|
|
18
|
+
: value
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function convertToJsonObject(value) {
|
|
22
|
+
const object = {}
|
|
23
|
+
for (const key of Object.keys(value)) {
|
|
24
|
+
object[key] = convertModelsToJson(value[key])
|
|
25
|
+
}
|
|
26
|
+
return object
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function convertToJsonArray(value) {
|
|
30
|
+
const array = new Array(value.length)
|
|
31
|
+
for (let i = 0, l = value.length; i < l; ++i) {
|
|
32
|
+
array[i] = convertModelsToJson(value[i])
|
|
33
|
+
}
|
|
34
|
+
return array
|
|
35
|
+
}
|
package/src/utils/net.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import net from 'net'
|
|
2
|
+
|
|
3
|
+
export async function getRandomFreePort() {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const srv = net.createServer()
|
|
6
|
+
srv.listen(0, () => {
|
|
7
|
+
const { port } = srv.address()
|
|
8
|
+
srv.close(err => {
|
|
9
|
+
if (err) {
|
|
10
|
+
reject(err)
|
|
11
|
+
} else {
|
|
12
|
+
resolve(port)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { asArray } from '@ditojs/utils'
|
|
2
|
+
|
|
3
|
+
export const getOwnKeys = Object.keys
|
|
4
|
+
|
|
5
|
+
export function getAllKeys(object) {
|
|
6
|
+
// Unlike `getOwnKeys()`, this returns all enumerable keys not just own ones.
|
|
7
|
+
const keys = []
|
|
8
|
+
for (const key in object) {
|
|
9
|
+
keys.push(key)
|
|
10
|
+
}
|
|
11
|
+
return keys
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getOwnProperty(object, key) {
|
|
15
|
+
return object.hasOwnProperty(key) ? object[key] : undefined
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createLookup(keys) {
|
|
19
|
+
return asArray(keys).reduce((obj, key) => {
|
|
20
|
+
obj[key] = true
|
|
21
|
+
return obj
|
|
22
|
+
}, Object.create(null))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function mergeReversed(objects) {
|
|
26
|
+
return Object.assign({}, ...[...objects].reverse())
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function mergeReversedOrNull(objects) {
|
|
30
|
+
const merged = mergeReversed(objects)
|
|
31
|
+
return Object.keys(merged).length > 0 ? merged : null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function mergeAsReversedArrays(objects) {
|
|
35
|
+
const res = {}
|
|
36
|
+
for (const object of objects) {
|
|
37
|
+
for (const key in object) {
|
|
38
|
+
const value = object[key]
|
|
39
|
+
if (key in res) {
|
|
40
|
+
res[key].unshift(value)
|
|
41
|
+
} else {
|
|
42
|
+
res[key] = [value]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return res
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function getInheritanceChain(object) {
|
|
50
|
+
// Returns an array of objects from the inheritance chain of `object`,
|
|
51
|
+
// starting with the object itself and ending at `Object.prototype`.
|
|
52
|
+
const chain = []
|
|
53
|
+
let current = object
|
|
54
|
+
while (current && current !== Object.prototype) {
|
|
55
|
+
chain.push(current)
|
|
56
|
+
current = Object.getPrototypeOf(current)
|
|
57
|
+
}
|
|
58
|
+
return chain
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function setupPropertyInheritance(object, key, baseValue = null) {
|
|
62
|
+
// Loops through the inheritance chain of `object` and sets up a related
|
|
63
|
+
// inheritance chain for the given property `key`. The resulting value with
|
|
64
|
+
// proper inheritance is returned.
|
|
65
|
+
let [current, ...parents] = getInheritanceChain(object)
|
|
66
|
+
for (const parent of parents) {
|
|
67
|
+
if (current.hasOwnProperty(key)) {
|
|
68
|
+
const value = current[key]
|
|
69
|
+
const parentValue = parent[key] || baseValue
|
|
70
|
+
if (parentValue) {
|
|
71
|
+
Object.setPrototypeOf(value, parentValue)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
current = parent
|
|
75
|
+
}
|
|
76
|
+
if (baseValue && !(key in object)) {
|
|
77
|
+
// If there wasn't any override in the chain, and we have a baseValue,
|
|
78
|
+
// set up direct inheritance from that now.
|
|
79
|
+
object[key] = Object.setPrototypeOf({}, baseValue)
|
|
80
|
+
}
|
|
81
|
+
return object[key]
|
|
82
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAllKeys,
|
|
3
|
+
getOwnProperty,
|
|
4
|
+
createLookup,
|
|
5
|
+
mergeReversed,
|
|
6
|
+
mergeAsReversedArrays
|
|
7
|
+
} from './object.js'
|
|
8
|
+
|
|
9
|
+
const object = Object.create({ a: 1 })
|
|
10
|
+
object.b = 2
|
|
11
|
+
|
|
12
|
+
describe('getAllKeys()', () => {
|
|
13
|
+
it('returns all keys, not just own keys', () => {
|
|
14
|
+
expect(getAllKeys(object)).toEqual(['b', 'a'])
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe('getOwnProperty()', () => {
|
|
19
|
+
it('only returns own properties', () => {
|
|
20
|
+
expect(getOwnProperty(object, 'a')).toBeUndefined()
|
|
21
|
+
expect(getOwnProperty(object, 'b')).toBe(2)
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
describe('createLookup()', () => {
|
|
26
|
+
it('creates lookup objects out of arrays of strings', () => {
|
|
27
|
+
expect(createLookup(['a', 'b'])).toEqual({
|
|
28
|
+
a: true,
|
|
29
|
+
b: true
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('mergeReversed()', () => {
|
|
35
|
+
it('merges property values in reversed order', () => {
|
|
36
|
+
expect(
|
|
37
|
+
mergeReversed([
|
|
38
|
+
{
|
|
39
|
+
a: 3
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
a: 2,
|
|
43
|
+
b: 2
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
a: 1,
|
|
47
|
+
b: 1,
|
|
48
|
+
c: 1
|
|
49
|
+
}
|
|
50
|
+
])
|
|
51
|
+
).toEqual({
|
|
52
|
+
a: 3,
|
|
53
|
+
b: 2,
|
|
54
|
+
c: 1
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
describe('mergeAsReversedArrays()', () => {
|
|
60
|
+
it('merges property values into arrays', () => {
|
|
61
|
+
expect(
|
|
62
|
+
mergeAsReversedArrays([
|
|
63
|
+
{
|
|
64
|
+
a: 1,
|
|
65
|
+
b: 1,
|
|
66
|
+
c: 1
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
a: 2,
|
|
70
|
+
b: 2
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
a: 3
|
|
74
|
+
}
|
|
75
|
+
])
|
|
76
|
+
).toEqual({
|
|
77
|
+
a: [3, 2, 1],
|
|
78
|
+
b: [2, 1],
|
|
79
|
+
c: [1]
|
|
80
|
+
})
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
describe.skip('setupPropertyInheritance()', () => {
|
|
85
|
+
// TODO: Add unit tests for this!
|
|
86
|
+
})
|