directus 9.18.1 → 9.19.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 (47) hide show
  1. package/dist/cli/commands/roles/create.js +1 -1
  2. package/dist/cli/utils/create-env/env-stub.liquid +3 -2
  3. package/dist/controllers/collections.js +18 -0
  4. package/dist/database/run-ast.js +11 -4
  5. package/dist/database/system-data/fields/activity.yaml +2 -1
  6. package/dist/database/system-data/fields/collections.yaml +8 -4
  7. package/dist/database/system-data/fields/dashboards.yaml +6 -3
  8. package/dist/database/system-data/fields/fields.yaml +18 -9
  9. package/dist/database/system-data/fields/files.yaml +14 -7
  10. package/dist/database/system-data/fields/flows.yaml +10 -5
  11. package/dist/database/system-data/fields/folders.yaml +2 -1
  12. package/dist/database/system-data/fields/operations.yaml +8 -4
  13. package/dist/database/system-data/fields/panels.yaml +8 -4
  14. package/dist/database/system-data/fields/permissions.yaml +8 -4
  15. package/dist/database/system-data/fields/presets.yaml +10 -5
  16. package/dist/database/system-data/fields/relations.yaml +2 -1
  17. package/dist/database/system-data/fields/revisions.yaml +4 -2
  18. package/dist/database/system-data/fields/roles.yaml +12 -6
  19. package/dist/database/system-data/fields/settings.yaml +10 -5
  20. package/dist/database/system-data/fields/shares.yaml +7 -3
  21. package/dist/database/system-data/fields/users.yaml +15 -7
  22. package/dist/database/system-data/fields/webhooks.yaml +8 -4
  23. package/dist/env.js +4 -2
  24. package/dist/env.test.js +1 -0
  25. package/dist/logger.d.ts +2 -2
  26. package/dist/logger.js +10 -3
  27. package/dist/messenger.d.ts +3 -3
  28. package/dist/services/collections.d.ts +4 -0
  29. package/dist/services/collections.js +50 -5
  30. package/dist/services/graphql/index.js +80 -65
  31. package/dist/services/graphql/types/date.d.ts +1 -1
  32. package/dist/services/graphql/types/geojson.d.ts +1 -1
  33. package/dist/services/graphql/types/hash.d.ts +1 -1
  34. package/dist/services/graphql/types/string-or-float.d.ts +1 -1
  35. package/dist/services/graphql/types/void.d.ts +1 -1
  36. package/dist/services/mail/templates/base.liquid +0 -1
  37. package/dist/services/payload.js +2 -2
  38. package/dist/services/payload.test.js +102 -0
  39. package/dist/types/items.d.ts +4 -0
  40. package/dist/utils/apply-query.js +10 -2
  41. package/dist/utils/get-ast-from-query.js +1 -1
  42. package/dist/utils/get-auth-providers.d.ts +1 -0
  43. package/dist/utils/get-auth-providers.js +1 -0
  44. package/dist/utils/get-auth-providers.test.d.ts +1 -0
  45. package/dist/utils/get-auth-providers.test.js +72 -0
  46. package/dist/utils/get-relation-info.js +10 -4
  47. package/package.json +121 -122
@@ -16,7 +16,7 @@ async function rolesCreate({ role: name, admin }) {
16
16
  try {
17
17
  const schema = await (0, get_schema_1.getSchema)();
18
18
  const service = new services_1.RolesService({ schema: schema, knex: database });
19
- const id = await service.createOne({ name, admin_access: admin });
19
+ const id = await service.createOne(admin ? { name, admin_access: admin } : { name });
20
20
  process.stdout.write(`${String(id)}\n`);
21
21
  database.destroy();
22
22
  process.exit(0);
@@ -31,8 +31,8 @@ PUBLIC_URL="/"
31
31
  # "pretty", "raw"
32
32
  # LOG_STYLE="pretty"
33
33
 
34
- # Controls the maximum request body size. Accepts number of bytes, or human readable string ["100kb"]
35
- # MAX_PAYLOAD_SIZE="100kb"
34
+ # Controls the maximum request body size. Accepts number of bytes, or human readable string ["1mb"]
35
+ # MAX_PAYLOAD_SIZE="1mb"
36
36
 
37
37
  # Where to redirect to when navigating to /. Accepts a relative path, absolute URL, or false to disable ["./admin"]
38
38
  # ROOT_REDIRECT="./admin"
@@ -273,6 +273,7 @@ AUTH_PROVIDERS=""
273
273
  # AUTH_GITHUB_ALLOW_PUBLIC_REGISTRATION=true
274
274
  # AUTH_GITHUB_DEFAULT_ROLE_ID="82424427-c9d4-4289-8bc5-ed1bf8422c90"
275
275
  # AUTH_GITHUB_ICON="github"
276
+ # AUTH_GITHUB_LABEL="GitHub"
276
277
  # AUTH_GITHUB_EMAIL_KEY="email"
277
278
  # AUTH_GITHUB_IDENTIFIER_KEY="login"
278
279
 
@@ -58,6 +58,24 @@ router.get('/:collection', (0, async_handler_1.default)(async (req, res, next) =
58
58
  res.locals.payload = { data: collection || null };
59
59
  return next();
60
60
  }), respond_1.respond);
61
+ router.patch('/', (0, async_handler_1.default)(async (req, res, next) => {
62
+ const collectionsService = new services_1.CollectionsService({
63
+ accountability: req.accountability,
64
+ schema: req.schema,
65
+ });
66
+ const collectionKeys = await collectionsService.updateBatch(req.body);
67
+ try {
68
+ const collections = await collectionsService.readMany(collectionKeys);
69
+ res.locals.payload = { data: collections || null };
70
+ }
71
+ catch (error) {
72
+ if (error instanceof exceptions_1.ForbiddenException) {
73
+ return next();
74
+ }
75
+ throw error;
76
+ }
77
+ return next();
78
+ }), respond_1.respond);
61
79
  router.patch('/:collection', (0, async_handler_1.default)(async (req, res, next) => {
62
80
  const collectionsService = new services_1.CollectionsService({
63
81
  accountability: req.accountability,
@@ -51,7 +51,11 @@ async function runAST(originalAST, schema, options) {
51
51
  let batchCount = 0;
52
52
  while (hasMore) {
53
53
  const node = (0, lodash_1.merge)({}, nestedNode, {
54
- query: { limit: env_1.default.RELATIONAL_BATCH_SIZE, offset: batchCount * env_1.default.RELATIONAL_BATCH_SIZE },
54
+ query: {
55
+ limit: env_1.default.RELATIONAL_BATCH_SIZE,
56
+ offset: batchCount * env_1.default.RELATIONAL_BATCH_SIZE,
57
+ page: null,
58
+ },
55
59
  });
56
60
  nestedItems = (await runAST(node, schema, { knex, nested: true }));
57
61
  if (nestedItems) {
@@ -213,7 +217,7 @@ function applyParentFilters(schema, nestedCollectionNodes, parentItem) {
213
217
  return nestedCollectionNodes;
214
218
  }
215
219
  function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
216
- var _a, _b;
220
+ var _a, _b, _c;
217
221
  const nestedItems = (0, utils_1.toArray)(nestedItem);
218
222
  const parentItems = (0, lodash_1.clone)((0, utils_1.toArray)(parentItem));
219
223
  if (nestedNode.type === 'm2o') {
@@ -240,11 +244,14 @@ function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
240
244
  ((_a = nestedItem[nestedNode.relation.field]) === null || _a === void 0 ? void 0 : _a[schema.collections[nestedNode.relation.related_collection].primary]) == parentItem[schema.collections[nestedNode.relation.related_collection].primary]);
241
245
  });
242
246
  parentItem[nestedNode.fieldKey].push(...itemChildren);
247
+ if (nestedNode.query.page && nestedNode.query.page > 1) {
248
+ parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(((_a = nestedNode.query.limit) !== null && _a !== void 0 ? _a : 100) * (nestedNode.query.page - 1));
249
+ }
243
250
  if (nestedNode.query.offset && nestedNode.query.offset >= 0) {
244
251
  parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(nestedNode.query.offset);
245
252
  }
246
253
  if (nestedNode.query.limit !== -1) {
247
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, (_a = nestedNode.query.limit) !== null && _a !== void 0 ? _a : 100);
254
+ parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, (_b = nestedNode.query.limit) !== null && _b !== void 0 ? _b : 100);
248
255
  }
249
256
  parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].sort((a, b) => {
250
257
  // This is pre-filled in get-ast-from-query
@@ -272,7 +279,7 @@ function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
272
279
  }
273
280
  else if (nestedNode.type === 'a2o') {
274
281
  for (const parentItem of parentItems) {
275
- if (!((_b = nestedNode.relation.meta) === null || _b === void 0 ? void 0 : _b.one_collection_field)) {
282
+ if (!((_c = nestedNode.relation.meta) === null || _c === void 0 ? void 0 : _c.one_collection_field)) {
276
283
  parentItem[nestedNode.fieldKey] = null;
277
284
  continue;
278
285
  }
@@ -74,7 +74,8 @@ fields:
74
74
 
75
75
  - field: revisions
76
76
  interface: list-o2m
77
- special: o2m
77
+ special:
78
+ - o2m
78
79
  options:
79
80
  fields:
80
81
  - collection
@@ -42,21 +42,24 @@ fields:
42
42
  width: full
43
43
 
44
44
  - field: hidden
45
- special: cast-boolean
45
+ special:
46
+ - cast-boolean
46
47
  interface: boolean
47
48
  options:
48
49
  label: $t:field_options.directus_collections.hidden_label
49
50
  width: half
50
51
 
51
52
  - field: singleton
52
- special: cast-boolean
53
+ special:
54
+ - cast-boolean
53
55
  interface: boolean
54
56
  options:
55
57
  label: $t:singleton_label
56
58
  width: half
57
59
 
58
60
  - field: translations
59
- special: cast-json
61
+ special:
62
+ - cast-json
60
63
  interface: list
61
64
  options:
62
65
  template: '{{ translation }} ({{ language }})'
@@ -115,7 +118,8 @@ fields:
115
118
 
116
119
  - field: archive_app_filter
117
120
  interface: boolean
118
- special: cast-boolean
121
+ special:
122
+ - cast-boolean
119
123
  options:
120
124
  label: $t:field_options.directus_collections.archive_app_filter
121
125
  width: half
@@ -2,16 +2,19 @@ table: directus_dashboards
2
2
 
3
3
  fields:
4
4
  - field: id
5
- special: uuid
5
+ special:
6
+ - uuid
6
7
  - field: name
7
8
  - field: icon
8
9
  - field: panels
9
- special: o2m
10
+ special:
11
+ - o2m
10
12
  - field: date_created
11
13
  special:
12
14
  - date-created
13
15
  - cast-timestamp
14
16
  - field: user_created
15
- special: user-created
17
+ special:
18
+ - user-created
16
19
  - field: note
17
20
  - field: color
@@ -17,7 +17,8 @@ fields:
17
17
  - collection: directus_fields
18
18
  field: special
19
19
  hidden: true
20
- special: cast-csv
20
+ special:
21
+ - cast-csv
21
22
  width: half
22
23
 
23
24
  - collection: directus_fields
@@ -27,7 +28,8 @@ fields:
27
28
  - collection: directus_fields
28
29
  field: options
29
30
  hidden: true
30
- special: cast-json
31
+ special:
32
+ - cast-json
31
33
  width: half
32
34
 
33
35
  - collection: directus_fields
@@ -37,25 +39,29 @@ fields:
37
39
  - collection: directus_fields
38
40
  field: display_options
39
41
  hidden: true
40
- special: cast-json
42
+ special:
43
+ - cast-json
41
44
  width: half
42
45
 
43
46
  - collection: directus_fields
44
47
  field: readonly
45
48
  hidden: true
46
- special: cast-boolean
49
+ special:
50
+ - cast-boolean
47
51
  width: half
48
52
 
49
53
  - collection: directus_fields
50
54
  field: hidden
51
55
  hidden: true
52
- special: cast-boolean
56
+ special:
57
+ - cast-boolean
53
58
  width: half
54
59
 
55
60
  - collection: directus_fields
56
61
  field: required
57
62
  hidden: true
58
- special: cast-boolean
63
+ special:
64
+ - cast-boolean
59
65
  width: half
60
66
 
61
67
  - collection: directus_fields
@@ -73,7 +79,8 @@ fields:
73
79
  - collection: directus_fields
74
80
  field: translations
75
81
  hidden: true
76
- special: cast-json
82
+ special:
83
+ - cast-json
77
84
  width: half
78
85
 
79
86
  - collection: directus_fields
@@ -83,12 +90,14 @@ fields:
83
90
  - collection: directus_fields
84
91
  field: conditions
85
92
  hidden: true
86
- special: cast-json
93
+ special:
94
+ - cast-json
87
95
 
88
96
  - collection: directus_fields
89
97
  field: validation
90
98
  hidden: true
91
- special: cast-json
99
+ special:
100
+ - cast-json
92
101
 
93
102
  - collection: directus_fields
94
103
  field: validation_message
@@ -4,7 +4,8 @@ fields:
4
4
  - field: id
5
5
  hidden: true
6
6
  interface: input
7
- special: uuid
7
+ special:
8
+ - uuid
8
9
 
9
10
  - field: title
10
11
  interface: input
@@ -23,7 +24,8 @@ fields:
23
24
  interface: tags
24
25
  options:
25
26
  iconRight: local_offer
26
- special: cast-json
27
+ special:
28
+ - cast-json
27
29
  width: full
28
30
  display: labels
29
31
  display_options:
@@ -71,7 +73,8 @@ fields:
71
73
 
72
74
  - field: metadata
73
75
  hidden: true
74
- special: cast-json
76
+ special:
77
+ - cast-json
75
78
 
76
79
  - field: type
77
80
  display: mime-type
@@ -83,7 +86,8 @@ fields:
83
86
 
84
87
  - field: modified_by
85
88
  interface: select-dropdown-m2o
86
- special: user-updated
89
+ special:
90
+ - user-updated
87
91
  width: half
88
92
  display: user
89
93
  readonly: true
@@ -92,7 +96,8 @@ fields:
92
96
 
93
97
  - field: modified_on
94
98
  interface: datetime
95
- special: date-updated
99
+ special:
100
+ - date-updated
96
101
  width: half
97
102
  display: datetime
98
103
  readonly: true
@@ -105,7 +110,8 @@ fields:
105
110
  display: user
106
111
  width: half
107
112
  hidden: true
108
- special: user-created
113
+ special:
114
+ - user-created
109
115
 
110
116
  - field: uploaded_on
111
117
  display: datetime
@@ -115,7 +121,8 @@ fields:
115
121
  - field: folder
116
122
  width: half
117
123
  readonly: true
118
- special: m2o
124
+ special:
125
+ - m2o
119
126
  display: related-values
120
127
  display_options:
121
128
  template: '{{ name }}'
@@ -2,7 +2,8 @@ table: directus_flows
2
2
 
3
3
  fields:
4
4
  - field: id
5
- special: uuid
5
+ special:
6
+ - uuid
6
7
  - field: name
7
8
  - field: icon
8
9
  - field: color
@@ -11,11 +12,15 @@ fields:
11
12
  - field: trigger
12
13
  - field: accountability
13
14
  - field: options
14
- special: cast-json
15
+ special:
16
+ - cast-json
15
17
  - field: operation
16
18
  - field: operations
17
- special: o2m
19
+ special:
20
+ - o2m
18
21
  - field: date_created
19
- special: date-created
22
+ special:
23
+ - date-created
20
24
  - field: user_created
21
- special: user-created
25
+ special:
26
+ - user-created
@@ -3,7 +3,8 @@ table: directus_folders
3
3
  fields:
4
4
  - field: id
5
5
  interface: input
6
- special: uuid
6
+ special:
7
+ - uuid
7
8
  width: half
8
9
 
9
10
  - field: parent
@@ -2,18 +2,22 @@ table: directus_operations
2
2
 
3
3
  fields:
4
4
  - field: id
5
- special: uuid
5
+ special:
6
+ - uuid
6
7
  - field: name
7
8
  - field: key
8
9
  - field: type
9
10
  - field: position_x
10
11
  - field: position_y
11
12
  - field: options
12
- special: cast-json
13
+ special:
14
+ - cast-json
13
15
  - field: resolve
14
16
  - field: reject
15
17
  - field: flow
16
18
  - field: date_created
17
- special: date-created
19
+ special:
20
+ - date-created
18
21
  - field: user_created
19
- special: user-created
22
+ special:
23
+ - user-created
@@ -2,24 +2,28 @@ table: directus_panels
2
2
 
3
3
  fields:
4
4
  - field: id
5
- special: uuid
5
+ special:
6
+ - uuid
6
7
  - field: name
7
8
  - field: icon
8
9
  - field: color
9
10
  - field: note
10
11
  - field: type
11
12
  - field: show_header
12
- special: cast-boolean
13
+ special:
14
+ - cast-boolean
13
15
  - field: position_x
14
16
  - field: position_y
15
17
  - field: width
16
18
  - field: height
17
19
  - field: options
18
- special: cast-json
20
+ special:
21
+ - cast-json
19
22
  - field: date_created
20
23
  special:
21
24
  - date-created
22
25
  - cast-timestamp
23
26
  - field: user_created
24
- special: user-created
27
+ special:
28
+ - user-created
25
29
  - field: dashboard
@@ -4,12 +4,14 @@ table: directus_permissions
4
4
  fields:
5
5
  - field: permissions
6
6
  hidden: true
7
- special: cast-json
7
+ special:
8
+ - cast-json
8
9
  width: half
9
10
 
10
11
  - field: presets
11
12
  hidden: true
12
- special: cast-json
13
+ special:
14
+ - cast-json
13
15
  width: half
14
16
 
15
17
  - field: role
@@ -23,11 +25,13 @@ fields:
23
25
 
24
26
  - field: fields
25
27
  width: half
26
- special: cast-csv
28
+ special:
29
+ - cast-csv
27
30
 
28
31
  - field: action
29
32
  width: half
30
33
 
31
34
  - field: validation
32
35
  width: half
33
- special: cast-json
36
+ special:
37
+ - cast-json
@@ -3,26 +3,31 @@ table: directus_presets
3
3
  fields:
4
4
  - field: filter
5
5
  hidden: true
6
- special: cast-json
6
+ special:
7
+ - cast-json
7
8
 
8
9
  - field: layout_query
9
10
  hidden: true
10
- special: cast-json
11
+ special:
12
+ - cast-json
11
13
 
12
14
  - field: layout_options
13
15
  hidden: true
14
- special: cast-json
16
+ special:
17
+ - cast-json
15
18
 
16
19
  - field: role
17
20
  width: half
18
- special: m2o
21
+ special:
22
+ - m2o
19
23
  display: related-values
20
24
  display_options:
21
25
  template: '{{ name }}'
22
26
 
23
27
  - field: user
24
28
  width: half
25
- special: m2o
29
+ special:
30
+ - m2o
26
31
  display: related-values
27
32
  display_options:
28
33
  template: '{{ email }}'
@@ -20,7 +20,8 @@ fields:
20
20
  width: half
21
21
 
22
22
  - field: one_allowed_collections
23
- special: cast-csv
23
+ special:
24
+ - cast-csv
24
25
  width: half
25
26
 
26
27
  - field: junction_field
@@ -15,11 +15,13 @@ fields:
15
15
 
16
16
  - field: data
17
17
  hidden: true
18
- special: cast-json
18
+ special:
19
+ - cast-json
19
20
 
20
21
  - field: delta
21
22
  hidden: true
22
- special: cast-json
23
+ special:
24
+ - cast-json
23
25
 
24
26
  - field: parent
25
27
  width: half
@@ -4,7 +4,8 @@ fields:
4
4
  - field: id
5
5
  hidden: true
6
6
  interface: input
7
- special: uuid
7
+ special:
8
+ - uuid
8
9
 
9
10
  - field: name
10
11
  interface: input
@@ -25,29 +26,34 @@ fields:
25
26
 
26
27
  - field: app_access
27
28
  interface: boolean
28
- special: cast-boolean
29
+ special:
30
+ - cast-boolean
29
31
  width: half
30
32
 
31
33
  - field: admin_access
32
34
  interface: boolean
33
- special: cast-boolean
35
+ special:
36
+ - cast-boolean
34
37
  width: half
35
38
 
36
39
  - field: ip_access
37
40
  interface: tags
38
41
  options:
39
42
  placeholder: $t:field_options.directus_roles.ip_access
40
- special: cast-csv
43
+ special:
44
+ - cast-csv
41
45
  width: full
42
46
 
43
47
  - field: enforce_tfa
44
48
  interface: boolean
45
- special: cast-boolean
49
+ special:
50
+ - cast-boolean
46
51
  width: half
47
52
 
48
53
  - field: users
49
54
  interface: list-o2m
50
- special: o2m
55
+ special:
56
+ - o2m
51
57
  options:
52
58
  fields:
53
59
  - first_name
@@ -131,7 +131,8 @@ fields:
131
131
 
132
132
  - field: module_bar
133
133
  interface: system-modules
134
- special: cast-json
134
+ special:
135
+ - cast-json
135
136
 
136
137
  - field: security_divider
137
138
  interface: presentation-divider
@@ -307,7 +308,8 @@ fields:
307
308
  ]
308
309
  width: full
309
310
  template: '{{key}}'
310
- special: cast-json
311
+ special:
312
+ - cast-json
311
313
  width: full
312
314
 
313
315
  - field: map_divider
@@ -332,7 +334,8 @@ fields:
332
334
 
333
335
  - field: basemaps
334
336
  interface: list
335
- special: cast-json
337
+ special:
338
+ - cast-json
336
339
  options:
337
340
  template: '{{name}}'
338
341
  fields:
@@ -390,7 +393,8 @@ fields:
390
393
  placeholder: $t:fields.directus_settings.attribution_placeholder
391
394
 
392
395
  - field: translation_strings
393
- special: cast-json
396
+ special:
397
+ - cast-json
394
398
  hidden: true
395
399
 
396
400
  - field: image_editor
@@ -405,7 +409,8 @@ fields:
405
409
 
406
410
  - field: custom_aspect_ratios
407
411
  interface: list
408
- special: cast-json
412
+ special:
413
+ - cast-json
409
414
  options:
410
415
  template: '{{text}}'
411
416
  fields:
@@ -2,7 +2,8 @@ table: directus_shares
2
2
 
3
3
  fields:
4
4
  - field: id
5
- special: uuid
5
+ special:
6
+ - uuid
6
7
  readonly: true
7
8
  hidden: true
8
9
 
@@ -26,7 +27,9 @@ fields:
26
27
  _eq: false
27
28
 
28
29
  - field: password
29
- special: hash,conceal
30
+ special:
31
+ - hash
32
+ - conceal
30
33
  interface: input-hash
31
34
  options:
32
35
  iconRight: lock
@@ -64,7 +67,8 @@ fields:
64
67
  hidden: true
65
68
 
66
69
  - field: user_created
67
- special: user-created
70
+ special:
71
+ - user-created
68
72
  interface: select-dropdown-m2o
69
73
  width: half
70
74
  display: user