directus 9.11.1 → 9.12.2

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 (104) hide show
  1. package/dist/app.js +14 -1
  2. package/dist/cli/utils/create-env/env-stub.liquid +266 -9
  3. package/dist/constants.d.ts +1 -0
  4. package/dist/constants.js +5 -1
  5. package/dist/controllers/activity.js +1 -1
  6. package/dist/controllers/flows.d.ts +2 -0
  7. package/dist/controllers/flows.js +157 -0
  8. package/dist/controllers/folders.js +1 -1
  9. package/dist/controllers/notifications.js +1 -1
  10. package/dist/controllers/operations.d.ts +2 -0
  11. package/dist/controllers/operations.js +138 -0
  12. package/dist/database/helpers/fn/dialects/oracle.d.ts +9 -9
  13. package/dist/database/helpers/fn/dialects/oracle.js +22 -16
  14. package/dist/database/helpers/fn/dialects/sqlite.d.ts +9 -9
  15. package/dist/database/helpers/fn/dialects/sqlite.js +46 -16
  16. package/dist/database/helpers/fn/types.d.ts +12 -9
  17. package/dist/database/index.js +10 -19
  18. package/dist/database/migrations/20220429A-add-flows.d.ts +3 -0
  19. package/dist/database/migrations/20220429A-add-flows.js +83 -0
  20. package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +3 -0
  21. package/dist/database/migrations/20220429B-add-color-to-insights-icon.js +15 -0
  22. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +3 -0
  23. package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.js +15 -0
  24. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +3 -0
  25. package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.js +15 -0
  26. package/dist/database/seeds/05-activity.yaml +0 -1
  27. package/dist/database/system-data/collections/collections.yaml +4 -0
  28. package/dist/database/system-data/fields/flows.yaml +21 -0
  29. package/dist/database/system-data/fields/operations.yaml +19 -0
  30. package/dist/database/system-data/fields/users.yaml +2 -4
  31. package/dist/database/system-data/relations/relations.yaml +20 -0
  32. package/dist/env.d.ts +1 -1
  33. package/dist/env.js +6 -30
  34. package/dist/extensions.d.ts +5 -1
  35. package/dist/extensions.js +96 -39
  36. package/dist/flows.d.ts +22 -0
  37. package/dist/flows.js +332 -0
  38. package/dist/messenger.d.ts +24 -0
  39. package/dist/messenger.js +64 -0
  40. package/dist/operations/condition/index.d.ts +6 -0
  41. package/dist/operations/condition/index.js +15 -0
  42. package/dist/operations/item-create/index.d.ts +8 -0
  43. package/dist/operations/item-create/index.js +40 -0
  44. package/dist/operations/item-delete/index.d.ts +9 -0
  45. package/dist/operations/item-delete/index.js +45 -0
  46. package/dist/operations/item-read/index.d.ts +9 -0
  47. package/dist/operations/item-read/index.js +45 -0
  48. package/dist/operations/item-update/index.d.ts +10 -0
  49. package/dist/operations/item-update/index.js +50 -0
  50. package/dist/operations/log/index.d.ts +5 -0
  51. package/dist/operations/log/index.js +14 -0
  52. package/dist/operations/mail/index.d.ts +7 -0
  53. package/dist/operations/mail/index.js +16 -0
  54. package/dist/operations/notification/index.d.ts +8 -0
  55. package/dist/operations/notification/index.js +39 -0
  56. package/dist/operations/request/index.d.ts +12 -0
  57. package/dist/operations/request/index.js +18 -0
  58. package/dist/operations/sleep/index.d.ts +5 -0
  59. package/dist/operations/sleep/index.js +9 -0
  60. package/dist/operations/transform/index.d.ts +5 -0
  61. package/dist/operations/transform/index.js +10 -0
  62. package/dist/operations/trigger/index.d.ts +6 -0
  63. package/dist/operations/trigger/index.js +21 -0
  64. package/dist/services/activity.d.ts +1 -2
  65. package/dist/services/activity.js +10 -10
  66. package/dist/services/authentication.d.ts +2 -2
  67. package/dist/services/authentication.js +7 -7
  68. package/dist/services/authorization.js +12 -0
  69. package/dist/services/flows.d.ts +12 -0
  70. package/dist/services/flows.js +47 -0
  71. package/dist/services/graphql.js +13 -2
  72. package/dist/services/import-export.js +7 -3
  73. package/dist/services/index.d.ts +2 -0
  74. package/dist/services/index.js +2 -0
  75. package/dist/services/items.js +1 -1
  76. package/dist/services/mail/index.js +2 -1
  77. package/dist/services/notifications.d.ts +2 -1
  78. package/dist/services/notifications.js +4 -3
  79. package/dist/services/operations.d.ts +12 -0
  80. package/dist/services/operations.js +47 -0
  81. package/dist/services/users.js +5 -0
  82. package/dist/services/webhooks.d.ts +2 -0
  83. package/dist/services/webhooks.js +8 -7
  84. package/dist/types/events.d.ts +18 -0
  85. package/dist/types/events.js +2 -0
  86. package/dist/types/index.d.ts +1 -1
  87. package/dist/types/index.js +1 -1
  88. package/dist/utils/apply-snapshot.js +3 -0
  89. package/dist/utils/construct-flow-tree.d.ts +2 -0
  90. package/dist/utils/construct-flow-tree.js +31 -0
  91. package/dist/utils/get-accountability-for-role.d.ts +7 -0
  92. package/dist/utils/get-accountability-for-role.js +36 -0
  93. package/dist/utils/get-column.js +1 -1
  94. package/dist/utils/job-queue.d.ts +9 -0
  95. package/dist/utils/job-queue.js +24 -0
  96. package/dist/utils/operation-options.d.ts +3 -0
  97. package/dist/utils/operation-options.js +45 -0
  98. package/dist/utils/validate-query.js +1 -1
  99. package/dist/webhooks.d.ts +2 -0
  100. package/dist/webhooks.js +17 -2
  101. package/package.json +19 -15
  102. package/dist/types/activity.d.ts +0 -9
  103. package/dist/types/activity.js +0 -13
  104. package/example.env +0 -202
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_1 = __importDefault(require("express"));
7
+ const exceptions_1 = require("../exceptions");
8
+ const respond_1 = require("../middleware/respond");
9
+ const use_collection_1 = __importDefault(require("../middleware/use-collection"));
10
+ const validate_batch_1 = require("../middleware/validate-batch");
11
+ const services_1 = require("../services");
12
+ const async_handler_1 = __importDefault(require("../utils/async-handler"));
13
+ const router = express_1.default.Router();
14
+ router.use((0, use_collection_1.default)('directus_operations'));
15
+ router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
16
+ const service = new services_1.OperationsService({
17
+ accountability: req.accountability,
18
+ schema: req.schema,
19
+ });
20
+ const savedKeys = [];
21
+ if (Array.isArray(req.body)) {
22
+ const keys = await service.createMany(req.body);
23
+ savedKeys.push(...keys);
24
+ }
25
+ else {
26
+ const key = await service.createOne(req.body);
27
+ savedKeys.push(key);
28
+ }
29
+ try {
30
+ if (Array.isArray(req.body)) {
31
+ const items = await service.readMany(savedKeys, req.sanitizedQuery);
32
+ res.locals.payload = { data: items };
33
+ }
34
+ else {
35
+ const item = await service.readOne(savedKeys[0], req.sanitizedQuery);
36
+ res.locals.payload = { data: item };
37
+ }
38
+ }
39
+ catch (error) {
40
+ if (error instanceof exceptions_1.ForbiddenException) {
41
+ return next();
42
+ }
43
+ throw error;
44
+ }
45
+ return next();
46
+ }), respond_1.respond);
47
+ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
48
+ const service = new services_1.OperationsService({
49
+ accountability: req.accountability,
50
+ schema: req.schema,
51
+ });
52
+ const metaService = new services_1.MetaService({
53
+ accountability: req.accountability,
54
+ schema: req.schema,
55
+ });
56
+ const records = await service.readByQuery(req.sanitizedQuery);
57
+ const meta = await metaService.getMetaForQuery(req.collection, req.sanitizedQuery);
58
+ res.locals.payload = { data: records || null, meta };
59
+ return next();
60
+ });
61
+ router.get('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
62
+ router.search('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
63
+ router.get('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
64
+ const service = new services_1.OperationsService({
65
+ accountability: req.accountability,
66
+ schema: req.schema,
67
+ });
68
+ const record = await service.readOne(req.params.pk, req.sanitizedQuery);
69
+ res.locals.payload = { data: record || null };
70
+ return next();
71
+ }), respond_1.respond);
72
+ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handler_1.default)(async (req, res, next) => {
73
+ const service = new services_1.OperationsService({
74
+ accountability: req.accountability,
75
+ schema: req.schema,
76
+ });
77
+ let keys = [];
78
+ if (req.body.keys) {
79
+ keys = await service.updateMany(req.body.keys, req.body.data);
80
+ }
81
+ else {
82
+ keys = await service.updateByQuery(req.body.query, req.body.data);
83
+ }
84
+ try {
85
+ const result = await service.readMany(keys, req.sanitizedQuery);
86
+ res.locals.payload = { data: result };
87
+ }
88
+ catch (error) {
89
+ if (error instanceof exceptions_1.ForbiddenException) {
90
+ return next();
91
+ }
92
+ throw error;
93
+ }
94
+ return next();
95
+ }), respond_1.respond);
96
+ router.patch('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
97
+ const service = new services_1.OperationsService({
98
+ accountability: req.accountability,
99
+ schema: req.schema,
100
+ });
101
+ const primaryKey = await service.updateOne(req.params.pk, req.body);
102
+ try {
103
+ const item = await service.readOne(primaryKey, req.sanitizedQuery);
104
+ res.locals.payload = { data: item || null };
105
+ }
106
+ catch (error) {
107
+ if (error instanceof exceptions_1.ForbiddenException) {
108
+ return next();
109
+ }
110
+ throw error;
111
+ }
112
+ return next();
113
+ }), respond_1.respond);
114
+ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
115
+ const service = new services_1.OperationsService({
116
+ accountability: req.accountability,
117
+ schema: req.schema,
118
+ });
119
+ if (Array.isArray(req.body)) {
120
+ await service.deleteMany(req.body);
121
+ }
122
+ else if (req.body.keys) {
123
+ await service.deleteMany(req.body.keys);
124
+ }
125
+ else {
126
+ await service.deleteByQuery(req.body.query);
127
+ }
128
+ return next();
129
+ }), respond_1.respond);
130
+ router.delete('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
131
+ const service = new services_1.OperationsService({
132
+ accountability: req.accountability,
133
+ schema: req.schema,
134
+ });
135
+ await service.deleteOne(req.params.pk);
136
+ return next();
137
+ }), respond_1.respond);
138
+ exports.default = router;
@@ -1,13 +1,13 @@
1
- import { FnHelper } from '../types';
1
+ import { FnHelper, FnHelperOptions } from '../types';
2
2
  import { Knex } from 'knex';
3
3
  export declare class FnHelperOracle extends FnHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
4
+ year(table: string, column: string, options: FnHelperOptions): Knex.Raw;
5
+ month(table: string, column: string, options: FnHelperOptions): Knex.Raw;
6
+ week(table: string, column: string, options: FnHelperOptions): Knex.Raw;
7
+ day(table: string, column: string, options: FnHelperOptions): Knex.Raw;
8
+ weekday(table: string, column: string, options: FnHelperOptions): Knex.Raw;
9
+ hour(table: string, column: string, options: FnHelperOptions): Knex.Raw;
10
+ minute(table: string, column: string, options: FnHelperOptions): Knex.Raw;
11
+ second(table: string, column: string, options: FnHelperOptions): Knex.Raw;
12
12
  count(table: string, column: string): Knex.Raw<any>;
13
13
  }
@@ -2,30 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FnHelperOracle = void 0;
4
4
  const types_1 = require("../types");
5
+ const parseLocaltime = (columnType) => {
6
+ if (columnType === 'timestamp') {
7
+ return ` AT TIME ZONE 'UTC'`;
8
+ }
9
+ return '';
10
+ };
5
11
  class FnHelperOracle extends types_1.FnHelper {
6
- year(table, column) {
7
- return this.knex.raw("TO_CHAR(??.??, 'IYYY')", [table, column]);
12
+ year(table, column, options) {
13
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'IYYY')`, [table, column]);
8
14
  }
9
- month(table, column) {
10
- return this.knex.raw("TO_CHAR(??.??, 'MM')", [table, column]);
15
+ month(table, column, options) {
16
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'MM')`, [table, column]);
11
17
  }
12
- week(table, column) {
13
- return this.knex.raw("TO_CHAR(??.??, 'IW')", [table, column]);
18
+ week(table, column, options) {
19
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'IW')`, [table, column]);
14
20
  }
15
- day(table, column) {
16
- return this.knex.raw("TO_CHAR(??.??, 'DD')", [table, column]);
21
+ day(table, column, options) {
22
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'DD')`, [table, column]);
17
23
  }
18
- weekday(table, column) {
19
- return this.knex.raw("TO_CHAR(??.??, 'D')", [table, column]);
24
+ weekday(table, column, options) {
25
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'D')`, [table, column]);
20
26
  }
21
- hour(table, column) {
22
- return this.knex.raw("TO_CHAR(??.??, 'HH24')", [table, column]);
27
+ hour(table, column, options) {
28
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'HH24')`, [table, column]);
23
29
  }
24
- minute(table, column) {
25
- return this.knex.raw("TO_CHAR(??.??, 'MI')", [table, column]);
30
+ minute(table, column, options) {
31
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'MI')`, [table, column]);
26
32
  }
27
- second(table, column) {
28
- return this.knex.raw("TO_CHAR(??.??, 'SS')", [table, column]);
33
+ second(table, column, options) {
34
+ return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}, 'SS')`, [table, column]);
29
35
  }
30
36
  count(table, column) {
31
37
  var _a, _b, _c, _d, _e;
@@ -1,13 +1,13 @@
1
- import { FnHelper } from '../types';
1
+ import { FnHelper, FnHelperOptions } from '../types';
2
2
  import { Knex } from 'knex';
3
3
  export declare class FnHelperSQLite extends FnHelper {
4
- year(table: string, column: string): Knex.Raw;
5
- month(table: string, column: string): Knex.Raw;
6
- week(table: string, column: string): Knex.Raw;
7
- day(table: string, column: string): Knex.Raw;
8
- weekday(table: string, column: string): Knex.Raw;
9
- hour(table: string, column: string): Knex.Raw;
10
- minute(table: string, column: string): Knex.Raw;
11
- second(table: string, column: string): Knex.Raw;
4
+ year(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
5
+ month(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
6
+ week(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
7
+ day(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
8
+ weekday(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
9
+ hour(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
10
+ minute(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
11
+ second(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
12
12
  count(table: string, column: string): Knex.Raw<any>;
13
13
  }
@@ -2,30 +2,60 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FnHelperSQLite = void 0;
4
4
  const types_1 = require("../types");
5
+ const parseLocaltime = (columnType) => {
6
+ if (columnType === 'timestamp') {
7
+ return '';
8
+ }
9
+ return `, 'localtime'`;
10
+ };
5
11
  class FnHelperSQLite extends types_1.FnHelper {
6
- year(table, column) {
7
- return this.knex.raw("CAST(strftime('%Y', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
12
+ year(table, column, options) {
13
+ return this.knex.raw(`CAST(strftime('%Y', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
14
+ table,
15
+ column,
16
+ ]);
8
17
  }
9
- month(table, column) {
10
- return this.knex.raw("CAST(strftime('%m', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
18
+ month(table, column, options) {
19
+ return this.knex.raw(`CAST(strftime('%m', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
20
+ table,
21
+ column,
22
+ ]);
11
23
  }
12
- week(table, column) {
13
- return this.knex.raw("CAST(strftime('%W', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
24
+ week(table, column, options) {
25
+ return this.knex.raw(`CAST(strftime('%W', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
26
+ table,
27
+ column,
28
+ ]);
14
29
  }
15
- day(table, column) {
16
- return this.knex.raw("CAST(strftime('%d', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
30
+ day(table, column, options) {
31
+ return this.knex.raw(`CAST(strftime('%d', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
32
+ table,
33
+ column,
34
+ ]);
17
35
  }
18
- weekday(table, column) {
19
- return this.knex.raw("CAST(strftime('%w', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
36
+ weekday(table, column, options) {
37
+ return this.knex.raw(`CAST(strftime('%w', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
38
+ table,
39
+ column,
40
+ ]);
20
41
  }
21
- hour(table, column) {
22
- return this.knex.raw("CAST(strftime('%H', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
42
+ hour(table, column, options) {
43
+ return this.knex.raw(`CAST(strftime('%H', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
44
+ table,
45
+ column,
46
+ ]);
23
47
  }
24
- minute(table, column) {
25
- return this.knex.raw("CAST(strftime('%M', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
48
+ minute(table, column, options) {
49
+ return this.knex.raw(`CAST(strftime('%M', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
50
+ table,
51
+ column,
52
+ ]);
26
53
  }
27
- second(table, column) {
28
- return this.knex.raw("CAST(strftime('%S', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
54
+ second(table, column, options) {
55
+ return this.knex.raw(`CAST(strftime('%S', ??.?? / 1000, 'unixepoch'${parseLocaltime(options === null || options === void 0 ? void 0 : options.type)}) AS INTEGER)`, [
56
+ table,
57
+ column,
58
+ ]);
29
59
  }
30
60
  count(table, column) {
31
61
  var _a, _b, _c, _d, _e;
@@ -1,18 +1,21 @@
1
1
  import { SchemaOverview } from '@directus/shared/types';
2
2
  import { Knex } from 'knex';
3
3
  import { DatabaseHelper } from '../types';
4
+ export declare type FnHelperOptions = {
5
+ type?: string;
6
+ };
4
7
  export declare abstract class FnHelper extends DatabaseHelper {
5
8
  protected knex: Knex;
6
9
  protected schema: SchemaOverview;
7
10
  constructor(knex: Knex, schema: SchemaOverview);
8
- abstract year(table: string, column: string): Knex.Raw;
9
- abstract month(table: string, column: string): Knex.Raw;
10
- abstract week(table: string, column: string): Knex.Raw;
11
- abstract day(table: string, column: string): Knex.Raw;
12
- abstract weekday(table: string, column: string): Knex.Raw;
13
- abstract hour(table: string, column: string): Knex.Raw;
14
- abstract minute(table: string, column: string): Knex.Raw;
15
- abstract second(table: string, column: string): Knex.Raw;
16
- abstract count(table: string, column: string): Knex.Raw;
11
+ abstract year(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
12
+ abstract month(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
13
+ abstract week(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
14
+ abstract day(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
15
+ abstract weekday(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
16
+ abstract hour(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
17
+ abstract minute(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
18
+ abstract second(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
19
+ abstract count(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
17
20
  protected _relationalCount(table: string, column: string): Knex.Raw;
18
21
  }
@@ -22,18 +22,9 @@ function getDatabase() {
22
22
  if (database) {
23
23
  return database;
24
24
  }
25
- const connectionConfig = (0, get_config_from_env_1.getConfigFromEnv)('DB_', [
26
- 'DB_CLIENT',
27
- 'DB_VERSION',
28
- 'DB_SEARCH_PATH',
29
- 'DB_CONNECTION_STRING',
30
- 'DB_POOL',
31
- 'DB_EXCLUDE_TABLES',
32
- 'DB_VERSION',
33
- ]);
34
- const poolConfig = (0, get_config_from_env_1.getConfigFromEnv)('DB_POOL');
25
+ const { client, version, searchPath, connectionString, pool: poolConfig = {}, ...connectionConfig } = (0, get_config_from_env_1.getConfigFromEnv)('DB_', ['DB_EXCLUDE_TABLES']);
35
26
  const requiredEnvVars = ['DB_CLIENT'];
36
- switch (env_1.default.DB_CLIENT) {
27
+ switch (client) {
37
28
  case 'sqlite3':
38
29
  requiredEnvVars.push('DB_FILENAME');
39
30
  break;
@@ -47,7 +38,7 @@ function getDatabase() {
47
38
  break;
48
39
  case 'cockroachdb':
49
40
  case 'pg':
50
- if (!env_1.default.DB_CONNECTION_STRING) {
41
+ if (!connectionString) {
51
42
  requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER');
52
43
  }
53
44
  else {
@@ -64,10 +55,10 @@ function getDatabase() {
64
55
  }
65
56
  (0, validate_env_1.validateEnv)(requiredEnvVars);
66
57
  const knexConfig = {
67
- client: env_1.default.DB_CLIENT,
68
- version: env_1.default.DB_VERSION,
69
- searchPath: env_1.default.DB_SEARCH_PATH,
70
- connection: env_1.default.DB_CONNECTION_STRING || connectionConfig,
58
+ client,
59
+ version,
60
+ searchPath,
61
+ connection: connectionString || connectionConfig,
71
62
  log: {
72
63
  warn: (msg) => {
73
64
  // Ignore warnings about returning not being supported in some DBs
@@ -84,7 +75,7 @@ function getDatabase() {
84
75
  },
85
76
  pool: poolConfig,
86
77
  };
87
- if (env_1.default.DB_CLIENT === 'sqlite3') {
78
+ if (client === 'sqlite3') {
88
79
  knexConfig.useNullAsDefault = true;
89
80
  poolConfig.afterCreate = async (conn, callback) => {
90
81
  logger_1.default.trace('Enabling SQLite Foreign Keys support...');
@@ -93,7 +84,7 @@ function getDatabase() {
93
84
  callback(null, conn);
94
85
  };
95
86
  }
96
- if (env_1.default.DB_CLIENT === 'cockroachdb') {
87
+ if (client === 'cockroachdb') {
97
88
  poolConfig.afterCreate = async (conn, callback) => {
98
89
  logger_1.default.trace('Setting CRDB serial_normalization and default_int_size');
99
90
  const run = (0, util_1.promisify)(conn.query.bind(conn));
@@ -102,7 +93,7 @@ function getDatabase() {
102
93
  callback(null, conn);
103
94
  };
104
95
  }
105
- if (env_1.default.DB_CLIENT === 'mssql') {
96
+ if (client === 'mssql') {
106
97
  // This brings MS SQL in line with the other DB vendors. We shouldn't do any automatic
107
98
  // timezone conversion on the database level, especially not when other database vendors don't
108
99
  // act the same
@@ -0,0 +1,3 @@
1
+ import { Knex } from 'knex';
2
+ export declare function up(knex: Knex): Promise<void>;
3
+ export declare function down(knex: Knex): Promise<void>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ const utils_1 = require("@directus/shared/utils");
5
+ const uuid_1 = require("uuid");
6
+ const parse_json_1 = require("../../utils/parse-json");
7
+ async function up(knex) {
8
+ await knex.schema.createTable('directus_flows', (table) => {
9
+ table.uuid('id').primary().notNullable();
10
+ table.string('name').notNullable();
11
+ table.string('icon', 30);
12
+ table.string('color').nullable();
13
+ table.text('description');
14
+ table.string('status').notNullable().defaultTo('active');
15
+ table.string('trigger');
16
+ table.string('accountability').defaultTo('all');
17
+ table.json('options');
18
+ table.uuid('operation').unique();
19
+ table.timestamp('date_created').defaultTo(knex.fn.now());
20
+ table.uuid('user_created').references('id').inTable('directus_users').onDelete('SET NULL');
21
+ });
22
+ await knex.schema.createTable('directus_operations', (table) => {
23
+ table.uuid('id').primary().notNullable();
24
+ table.string('name');
25
+ table.string('key').notNullable();
26
+ table.string('type').notNullable();
27
+ table.integer('position_x').notNullable();
28
+ table.integer('position_y').notNullable();
29
+ table.json('options');
30
+ table.uuid('resolve').unique().references('id').inTable('directus_operations');
31
+ table.uuid('reject').unique().references('id').inTable('directus_operations');
32
+ table.uuid('flow').notNullable().references('id').inTable('directus_flows').onDelete('CASCADE');
33
+ table.timestamp('date_created').defaultTo(knex.fn.now());
34
+ table.uuid('user_created').references('id').inTable('directus_users').onDelete('SET NULL');
35
+ });
36
+ const webhooks = await knex.select('*').from('directus_webhooks');
37
+ const flows = [];
38
+ const operations = [];
39
+ for (const webhook of webhooks) {
40
+ const flowID = (0, uuid_1.v4)();
41
+ flows.push({
42
+ id: flowID,
43
+ name: webhook.name,
44
+ status: 'inactive',
45
+ trigger: 'hook',
46
+ options: JSON.stringify({
47
+ name: webhook.name,
48
+ type: 'action',
49
+ scope: (0, utils_1.toArray)(webhook.actions).map((scope) => `items.${scope}`),
50
+ collections: (0, utils_1.toArray)(webhook.collections),
51
+ }),
52
+ });
53
+ operations.push({
54
+ id: (0, uuid_1.v4)(),
55
+ name: 'Request',
56
+ key: 'request',
57
+ type: 'request',
58
+ position_x: 21,
59
+ position_y: 1,
60
+ options: JSON.stringify({
61
+ url: webhook.url,
62
+ headers: typeof webhook.headers === 'string' ? (0, parse_json_1.parseJSON)(webhook.headers) : webhook.headers,
63
+ data: webhook.data ? '{{$trigger}}' : null,
64
+ method: webhook.method,
65
+ }),
66
+ date_created: new Date(),
67
+ flow: flowID,
68
+ });
69
+ }
70
+ if (flows.length && operations.length) {
71
+ await knex.insert(flows).into('directus_flows');
72
+ await knex.insert(operations).into('directus_operations');
73
+ for (const operation of operations) {
74
+ await knex('directus_flows').update({ operation: operation.id }).where({ id: operation.flow });
75
+ }
76
+ }
77
+ }
78
+ exports.up = up;
79
+ async function down(knex) {
80
+ await knex.schema.dropTable('directus_operations');
81
+ await knex.schema.dropTable('directus_flows');
82
+ }
83
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { Knex } from 'knex';
2
+ export declare function up(knex: Knex): Promise<void>;
3
+ export declare function down(knex: Knex): Promise<void>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ async function up(knex) {
5
+ await knex.schema.alterTable('directus_dashboards', (table) => {
6
+ table.string('color').nullable();
7
+ });
8
+ }
9
+ exports.up = up;
10
+ async function down(knex) {
11
+ await knex.schema.alterTable('directus_dashboards', (table) => {
12
+ table.dropColumn('color');
13
+ });
14
+ }
15
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { Knex } from 'knex';
2
+ export declare function up(knex: Knex): Promise<void>;
3
+ export declare function down(knex: Knex): Promise<void>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ async function up(knex) {
5
+ await knex.schema.alterTable('directus_activity', (table) => {
6
+ table.setNullable('ip');
7
+ });
8
+ }
9
+ exports.up = up;
10
+ async function down(knex) {
11
+ await knex.schema.alterTable('directus_activity', (table) => {
12
+ table.dropNullable('ip');
13
+ });
14
+ }
15
+ exports.down = down;
@@ -0,0 +1,3 @@
1
+ import { Knex } from 'knex';
2
+ export declare function up(knex: Knex): Promise<void>;
3
+ export declare function down(knex: Knex): Promise<void>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ async function up(knex) {
5
+ await knex.schema.alterTable('directus_notifications', (table) => {
6
+ table.setNullable('sender');
7
+ });
8
+ }
9
+ exports.up = up;
10
+ async function down(knex) {
11
+ await knex.schema.alterTable('directus_notifications', (table) => {
12
+ table.dropNullable('sender');
13
+ });
14
+ }
15
+ exports.down = down;
@@ -20,7 +20,6 @@ columns:
20
20
  user_agent:
21
21
  type: string
22
22
  length: 255
23
- nullabel: false
24
23
  collection:
25
24
  type: string
26
25
  length: 64
@@ -68,3 +68,7 @@ data:
68
68
  - collection: directus_shares
69
69
  icon: share
70
70
  note: $t:directus_collection.directus_shares
71
+ - collection: directus_flows
72
+ note: $t:directus_collection.directus_flows
73
+ - collection: directus_operations
74
+ note: $t:directus_collection.directus_operations
@@ -0,0 +1,21 @@
1
+ table: directus_flows
2
+
3
+ fields:
4
+ - field: id
5
+ special: uuid
6
+ - field: name
7
+ - field: icon
8
+ - field: color
9
+ - field: description
10
+ - field: status
11
+ - field: trigger
12
+ - field: accountability
13
+ - field: options
14
+ special: cast-json
15
+ - field: operation
16
+ - field: operations
17
+ special: o2m
18
+ - field: date_created
19
+ special: date-created
20
+ - field: user_created
21
+ special: user-created
@@ -0,0 +1,19 @@
1
+ table: directus_operations
2
+
3
+ fields:
4
+ - field: id
5
+ special: uuid
6
+ - field: name
7
+ - field: key
8
+ - field: type
9
+ - field: position_x
10
+ - field: position_y
11
+ - field: options
12
+ special: cast-json
13
+ - field: resolve
14
+ - field: reject
15
+ - field: flow
16
+ - field: date_created
17
+ special: date-created
18
+ - field: user_created
19
+ special: user-created
@@ -135,10 +135,8 @@ fields:
135
135
  template: '{{ name }}'
136
136
 
137
137
  - field: token
138
- interface: token
139
- options:
140
- iconRight: vpn_key
141
- placeholder: $t:fields.directus_users.token_placeholder
138
+ interface: system-token
139
+ special: conceal
142
140
  width: full
143
141
 
144
142
  - field: id