@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.
Files changed (137) hide show
  1. package/README.md +6 -0
  2. package/package.json +95 -0
  3. package/src/app/Application.js +1186 -0
  4. package/src/app/Validator.js +405 -0
  5. package/src/app/index.js +2 -0
  6. package/src/cli/console.js +152 -0
  7. package/src/cli/db/createMigration.js +241 -0
  8. package/src/cli/db/index.js +7 -0
  9. package/src/cli/db/listAssetConfig.js +10 -0
  10. package/src/cli/db/migrate.js +12 -0
  11. package/src/cli/db/reset.js +23 -0
  12. package/src/cli/db/rollback.js +12 -0
  13. package/src/cli/db/seed.js +80 -0
  14. package/src/cli/db/unlock.js +9 -0
  15. package/src/cli/index.js +72 -0
  16. package/src/controllers/AdminController.js +322 -0
  17. package/src/controllers/CollectionController.js +274 -0
  18. package/src/controllers/Controller.js +657 -0
  19. package/src/controllers/ControllerAction.js +370 -0
  20. package/src/controllers/MemberAction.js +27 -0
  21. package/src/controllers/ModelController.js +63 -0
  22. package/src/controllers/RelationController.js +93 -0
  23. package/src/controllers/UsersController.js +64 -0
  24. package/src/controllers/index.js +5 -0
  25. package/src/errors/AssetError.js +7 -0
  26. package/src/errors/AuthenticationError.js +7 -0
  27. package/src/errors/AuthorizationError.js +7 -0
  28. package/src/errors/ControllerError.js +14 -0
  29. package/src/errors/DatabaseError.js +37 -0
  30. package/src/errors/GraphError.js +7 -0
  31. package/src/errors/ModelError.js +12 -0
  32. package/src/errors/NotFoundError.js +7 -0
  33. package/src/errors/NotImplementedError.js +7 -0
  34. package/src/errors/QueryBuilderError.js +7 -0
  35. package/src/errors/RelationError.js +21 -0
  36. package/src/errors/ResponseError.js +56 -0
  37. package/src/errors/ValidationError.js +7 -0
  38. package/src/errors/index.js +13 -0
  39. package/src/graph/DitoGraphProcessor.js +213 -0
  40. package/src/graph/expression.js +53 -0
  41. package/src/graph/graph.js +258 -0
  42. package/src/graph/index.js +3 -0
  43. package/src/index.js +9 -0
  44. package/src/lib/EventEmitter.js +66 -0
  45. package/src/lib/KnexHelper.js +30 -0
  46. package/src/lib/index.js +2 -0
  47. package/src/middleware/attachLogger.js +8 -0
  48. package/src/middleware/createTransaction.js +33 -0
  49. package/src/middleware/extendContext.js +10 -0
  50. package/src/middleware/findRoute.js +20 -0
  51. package/src/middleware/handleConnectMiddleware.js +99 -0
  52. package/src/middleware/handleError.js +29 -0
  53. package/src/middleware/handleRoute.js +23 -0
  54. package/src/middleware/handleSession.js +77 -0
  55. package/src/middleware/handleUser.js +31 -0
  56. package/src/middleware/index.js +11 -0
  57. package/src/middleware/logRequests.js +125 -0
  58. package/src/middleware/setupRequestStorage.js +14 -0
  59. package/src/mixins/AssetMixin.js +78 -0
  60. package/src/mixins/SessionMixin.js +17 -0
  61. package/src/mixins/TimeStampedMixin.js +41 -0
  62. package/src/mixins/UserMixin.js +171 -0
  63. package/src/mixins/index.js +4 -0
  64. package/src/models/AssetModel.js +4 -0
  65. package/src/models/Model.js +1205 -0
  66. package/src/models/RelationAccessor.js +41 -0
  67. package/src/models/SessionModel.js +4 -0
  68. package/src/models/TimeStampedModel.js +4 -0
  69. package/src/models/UserModel.js +4 -0
  70. package/src/models/definitions/assets.js +5 -0
  71. package/src/models/definitions/filters.js +121 -0
  72. package/src/models/definitions/hooks.js +8 -0
  73. package/src/models/definitions/index.js +22 -0
  74. package/src/models/definitions/modifiers.js +5 -0
  75. package/src/models/definitions/options.js +5 -0
  76. package/src/models/definitions/properties.js +73 -0
  77. package/src/models/definitions/relations.js +5 -0
  78. package/src/models/definitions/schema.js +5 -0
  79. package/src/models/definitions/scopes.js +36 -0
  80. package/src/models/index.js +5 -0
  81. package/src/query/QueryBuilder.js +1077 -0
  82. package/src/query/QueryFilters.js +66 -0
  83. package/src/query/QueryParameters.js +79 -0
  84. package/src/query/Registry.js +29 -0
  85. package/src/query/index.js +3 -0
  86. package/src/schema/formats/_empty.js +4 -0
  87. package/src/schema/formats/_required.js +4 -0
  88. package/src/schema/formats/index.js +2 -0
  89. package/src/schema/index.js +5 -0
  90. package/src/schema/keywords/_computed.js +7 -0
  91. package/src/schema/keywords/_foreign.js +7 -0
  92. package/src/schema/keywords/_hidden.js +7 -0
  93. package/src/schema/keywords/_index.js +7 -0
  94. package/src/schema/keywords/_instanceof.js +45 -0
  95. package/src/schema/keywords/_primary.js +7 -0
  96. package/src/schema/keywords/_range.js +18 -0
  97. package/src/schema/keywords/_relate.js +13 -0
  98. package/src/schema/keywords/_specificType.js +7 -0
  99. package/src/schema/keywords/_unique.js +7 -0
  100. package/src/schema/keywords/_unsigned.js +7 -0
  101. package/src/schema/keywords/_validate.js +73 -0
  102. package/src/schema/keywords/index.js +12 -0
  103. package/src/schema/relations.js +324 -0
  104. package/src/schema/relations.test.js +177 -0
  105. package/src/schema/schema.js +289 -0
  106. package/src/schema/schema.test.js +720 -0
  107. package/src/schema/types/_asset.js +31 -0
  108. package/src/schema/types/_color.js +4 -0
  109. package/src/schema/types/index.js +2 -0
  110. package/src/services/Service.js +35 -0
  111. package/src/services/index.js +1 -0
  112. package/src/storage/AssetFile.js +81 -0
  113. package/src/storage/DiskStorage.js +114 -0
  114. package/src/storage/S3Storage.js +169 -0
  115. package/src/storage/Storage.js +231 -0
  116. package/src/storage/index.js +9 -0
  117. package/src/utils/duration.js +15 -0
  118. package/src/utils/emitter.js +8 -0
  119. package/src/utils/fs.js +10 -0
  120. package/src/utils/function.js +17 -0
  121. package/src/utils/function.test.js +77 -0
  122. package/src/utils/handler.js +17 -0
  123. package/src/utils/json.js +3 -0
  124. package/src/utils/model.js +35 -0
  125. package/src/utils/net.js +17 -0
  126. package/src/utils/object.js +82 -0
  127. package/src/utils/object.test.js +86 -0
  128. package/src/utils/scope.js +7 -0
  129. package/types/index.d.ts +3547 -0
  130. package/types/tests/application.test-d.ts +26 -0
  131. package/types/tests/controller.test-d.ts +113 -0
  132. package/types/tests/errors.test-d.ts +53 -0
  133. package/types/tests/fixtures.ts +19 -0
  134. package/types/tests/model.test-d.ts +193 -0
  135. package/types/tests/query-builder.test-d.ts +106 -0
  136. package/types/tests/relation.test-d.ts +83 -0
  137. package/types/tests/storage.test-d.ts +113 -0
@@ -0,0 +1,10 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function exists(path) {
4
+ try {
5
+ await fs.access(path)
6
+ return true
7
+ } catch {
8
+ return false
9
+ }
10
+ }
@@ -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,3 @@
1
+ export function formatJson(json, indented = true) {
2
+ return JSON.stringify(json, null, indented ? 2 : 0)
3
+ }
@@ -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
+ }
@@ -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
+ })
@@ -0,0 +1,7 @@
1
+ export function getScope(expr) {
2
+ // See if this an graph scope, and if so, remove the trailing ^ for
3
+ // internal handling.
4
+ const graph = expr?.[0] === '^'
5
+ const scope = graph ? expr.slice(1) : expr
6
+ return { scope, graph }
7
+ }