directus 9.7.1 → 9.9.1

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 (103) hide show
  1. package/dist/__mocks__/cache.d.ts +5 -0
  2. package/dist/__mocks__/cache.js +7 -0
  3. package/dist/auth/drivers/ldap.js +10 -11
  4. package/dist/auth/drivers/oauth2.js +9 -4
  5. package/dist/auth/drivers/openid.js +7 -4
  6. package/dist/cache.js +2 -2
  7. package/dist/cli/commands/schema/apply.js +9 -3
  8. package/dist/controllers/assets.js +5 -0
  9. package/dist/controllers/files.d.ts +2 -0
  10. package/dist/controllers/files.js +13 -5
  11. package/dist/database/helpers/date/dialects/default.d.ts +3 -0
  12. package/dist/database/helpers/date/dialects/default.js +7 -0
  13. package/dist/database/helpers/date/dialects/mssql.d.ts +1 -9
  14. package/dist/database/helpers/date/dialects/mssql.js +4 -23
  15. package/dist/database/helpers/date/dialects/mysql.d.ts +2 -9
  16. package/dist/database/helpers/date/dialects/mysql.js +7 -22
  17. package/dist/database/helpers/date/dialects/oracle.d.ts +1 -9
  18. package/dist/database/helpers/date/dialects/oracle.js +7 -23
  19. package/dist/database/helpers/date/dialects/sqlite.d.ts +1 -9
  20. package/dist/database/helpers/date/dialects/sqlite.js +8 -24
  21. package/dist/database/helpers/date/index.d.ts +4 -4
  22. package/dist/database/helpers/date/index.js +9 -9
  23. package/dist/database/helpers/date/types.d.ts +3 -9
  24. package/dist/database/helpers/date/types.js +10 -0
  25. package/dist/database/helpers/fn/dialects/mssql.d.ts +13 -0
  26. package/dist/database/helpers/fn/dialects/mssql.js +42 -0
  27. package/dist/database/helpers/{date/dialects/postgres.d.ts → fn/dialects/mysql.d.ts} +3 -2
  28. package/dist/database/helpers/fn/dialects/mysql.js +42 -0
  29. package/dist/database/helpers/fn/dialects/oracle.d.ts +13 -0
  30. package/dist/database/helpers/fn/dialects/oracle.js +42 -0
  31. package/dist/database/helpers/fn/dialects/postgres.d.ts +13 -0
  32. package/dist/database/helpers/{date → fn}/dialects/postgres.js +18 -3
  33. package/dist/database/helpers/fn/dialects/sqlite.d.ts +13 -0
  34. package/dist/database/helpers/fn/dialects/sqlite.js +42 -0
  35. package/dist/database/helpers/fn/index.d.ts +7 -0
  36. package/dist/database/helpers/fn/index.js +17 -0
  37. package/dist/database/helpers/fn/types.d.ts +18 -0
  38. package/dist/database/helpers/fn/types.js +27 -0
  39. package/dist/database/helpers/index.d.ts +4 -1
  40. package/dist/database/helpers/index.js +7 -1
  41. package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +3 -0
  42. package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.js +17 -0
  43. package/dist/database/migrations/20220322A-rename-field-typecast-flags.js +6 -2
  44. package/dist/database/migrations/20220323A-add-field-validation.d.ts +3 -0
  45. package/dist/database/migrations/20220323A-add-field-validation.js +17 -0
  46. package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +3 -0
  47. package/dist/database/migrations/20220325A-fix-typecast-flags.js +49 -0
  48. package/dist/database/migrations/20220325B-add-default-language.d.ts +3 -0
  49. package/dist/database/migrations/20220325B-add-default-language.js +28 -0
  50. package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +3 -0
  51. package/dist/database/migrations/20220402A-remove-default-value-panel-icon.js +22 -0
  52. package/dist/database/run-ast.js +7 -5
  53. package/dist/database/system-data/fields/activity.yaml +4 -4
  54. package/dist/database/system-data/fields/collections.yaml +1 -1
  55. package/dist/database/system-data/fields/fields.yaml +9 -0
  56. package/dist/database/system-data/fields/presets.yaml +14 -0
  57. package/dist/database/system-data/fields/settings.yaml +12 -1
  58. package/dist/database/system-data/fields/users.yaml +3 -0
  59. package/dist/env.js +5 -3
  60. package/dist/exceptions/index.d.ts +1 -0
  61. package/dist/exceptions/index.js +1 -0
  62. package/dist/exceptions/token-expired.d.ts +4 -0
  63. package/dist/exceptions/token-expired.js +10 -0
  64. package/dist/logger.js +2 -1
  65. package/dist/middleware/cache.js +10 -0
  66. package/dist/services/activity.js +4 -1
  67. package/dist/services/authorization.d.ts +1 -1
  68. package/dist/services/authorization.js +174 -48
  69. package/dist/services/collections.d.ts +2 -0
  70. package/dist/services/collections.js +232 -198
  71. package/dist/services/fields.js +210 -174
  72. package/dist/services/files.d.ts +5 -1
  73. package/dist/services/files.js +59 -40
  74. package/dist/services/graphql.d.ts +2 -3
  75. package/dist/services/graphql.js +53 -10
  76. package/dist/services/items.js +5 -3
  77. package/dist/services/payload.d.ts +2 -1
  78. package/dist/services/payload.js +28 -21
  79. package/dist/services/relations.js +93 -81
  80. package/dist/services/server.js +1 -0
  81. package/dist/services/shares.js +2 -1
  82. package/dist/services/specifications.js +1 -3
  83. package/dist/services/users.js +7 -2
  84. package/dist/types/files.d.ts +8 -0
  85. package/dist/utils/apply-query.js +38 -10
  86. package/dist/utils/apply-snapshot.d.ts +3 -1
  87. package/dist/utils/apply-snapshot.js +34 -5
  88. package/dist/utils/get-ast-from-query.js +15 -3
  89. package/dist/utils/get-column.d.ts +6 -5
  90. package/dist/utils/get-column.js +16 -8
  91. package/dist/utils/get-graphql-type.js +1 -0
  92. package/dist/utils/get-local-type.js +5 -0
  93. package/dist/utils/get-schema.d.ts +1 -1
  94. package/dist/utils/get-schema.js +18 -10
  95. package/dist/utils/jwt.js +1 -1
  96. package/dist/utils/reduce-schema.js +20 -12
  97. package/dist/utils/track.js +3 -2
  98. package/dist/utils/url.d.ts +1 -1
  99. package/dist/utils/url.js +1 -1
  100. package/dist/utils/validate-query.js +19 -15
  101. package/dist/utils/validate-storage.js +3 -1
  102. package/example.env +4 -0
  103. package/package.json +14 -13
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FnHelperMSSQL = void 0;
4
+ const types_1 = require("../types");
5
+ class FnHelperMSSQL extends types_1.FnHelper {
6
+ year(table, column) {
7
+ return this.knex.raw('DATEPART(year, ??.??)', [table, column]);
8
+ }
9
+ month(table, column) {
10
+ return this.knex.raw('DATEPART(month, ??.??)', [table, column]);
11
+ }
12
+ week(table, column) {
13
+ return this.knex.raw('DATEPART(week, ??.??)', [table, column]);
14
+ }
15
+ day(table, column) {
16
+ return this.knex.raw('DATEPART(day, ??.??)', [table, column]);
17
+ }
18
+ weekday(table, column) {
19
+ return this.knex.raw('DATEPART(weekday, ??.??)', [table, column]);
20
+ }
21
+ hour(table, column) {
22
+ return this.knex.raw('DATEPART(hour, ??.??)', [table, column]);
23
+ }
24
+ minute(table, column) {
25
+ return this.knex.raw('DATEPART(minute, ??.??)', [table, column]);
26
+ }
27
+ second(table, column) {
28
+ return this.knex.raw('DATEPART(second, ??.??)', [table, column]);
29
+ }
30
+ count(table, column) {
31
+ var _a, _b, _c, _d, _e;
32
+ const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[table]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
33
+ if (type === 'json') {
34
+ return this.knex.raw(`(SELECT COUNT(*) FROM OPENJSON(??.??, '$'))`, [table, column]);
35
+ }
36
+ if (type === 'alias') {
37
+ return this._relationalCount(table, column);
38
+ }
39
+ throw new Error(`Couldn't extract type from ${table}.${column}`);
40
+ }
41
+ }
42
+ exports.FnHelperMSSQL = FnHelperMSSQL;
@@ -1,6 +1,6 @@
1
- import { DateHelper } from '../types';
1
+ import { FnHelper } from '../types';
2
2
  import { Knex } from 'knex';
3
- export declare class DateHelperPostgres extends DateHelper {
3
+ export declare class FnHelperMySQL extends FnHelper {
4
4
  year(table: string, column: string): Knex.Raw;
5
5
  month(table: string, column: string): Knex.Raw;
6
6
  week(table: string, column: string): Knex.Raw;
@@ -9,4 +9,5 @@ export declare class DateHelperPostgres extends DateHelper {
9
9
  hour(table: string, column: string): Knex.Raw;
10
10
  minute(table: string, column: string): Knex.Raw;
11
11
  second(table: string, column: string): Knex.Raw;
12
+ count(table: string, column: string): Knex.Raw;
12
13
  }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FnHelperMySQL = void 0;
4
+ const types_1 = require("../types");
5
+ class FnHelperMySQL extends types_1.FnHelper {
6
+ year(table, column) {
7
+ return this.knex.raw('YEAR(??.??)', [table, column]);
8
+ }
9
+ month(table, column) {
10
+ return this.knex.raw('MONTH(??.??)', [table, column]);
11
+ }
12
+ week(table, column) {
13
+ return this.knex.raw('WEEK(??.??)', [table, column]);
14
+ }
15
+ day(table, column) {
16
+ return this.knex.raw('DAYOFMONTH(??.??)', [table, column]);
17
+ }
18
+ weekday(table, column) {
19
+ return this.knex.raw('DAYOFWEEK(??.??)', [table, column]);
20
+ }
21
+ hour(table, column) {
22
+ return this.knex.raw('HOUR(??.??)', [table, column]);
23
+ }
24
+ minute(table, column) {
25
+ return this.knex.raw('MINUTE(??.??)', [table, column]);
26
+ }
27
+ second(table, column) {
28
+ return this.knex.raw('SECOND(??.??)', [table, column]);
29
+ }
30
+ count(table, column) {
31
+ var _a, _b, _c, _d, _e;
32
+ const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[table]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
33
+ if (type === 'json') {
34
+ return this.knex.raw('JSON_LENGTH(??.??)', [table, column]);
35
+ }
36
+ if (type === 'alias') {
37
+ return this._relationalCount(table, column);
38
+ }
39
+ throw new Error(`Couldn't extract type from ${table}.${column}`);
40
+ }
41
+ }
42
+ exports.FnHelperMySQL = FnHelperMySQL;
@@ -0,0 +1,13 @@
1
+ import { FnHelper } from '../types';
2
+ import { Knex } from 'knex';
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;
12
+ count(table: string, column: string): Knex.Raw<any>;
13
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FnHelperOracle = void 0;
4
+ const types_1 = require("../types");
5
+ class FnHelperOracle extends types_1.FnHelper {
6
+ year(table, column) {
7
+ return this.knex.raw("TO_CHAR(??.??, 'IYYY')", [table, column]);
8
+ }
9
+ month(table, column) {
10
+ return this.knex.raw("TO_CHAR(??.??, 'MM')", [table, column]);
11
+ }
12
+ week(table, column) {
13
+ return this.knex.raw("TO_CHAR(??.??, 'IW')", [table, column]);
14
+ }
15
+ day(table, column) {
16
+ return this.knex.raw("TO_CHAR(??.??, 'DD')", [table, column]);
17
+ }
18
+ weekday(table, column) {
19
+ return this.knex.raw("TO_CHAR(??.??, 'D')", [table, column]);
20
+ }
21
+ hour(table, column) {
22
+ return this.knex.raw("TO_CHAR(??.??, 'HH24')", [table, column]);
23
+ }
24
+ minute(table, column) {
25
+ return this.knex.raw("TO_CHAR(??.??, 'MI')", [table, column]);
26
+ }
27
+ second(table, column) {
28
+ return this.knex.raw("TO_CHAR(??.??, 'SS')", [table, column]);
29
+ }
30
+ count(table, column) {
31
+ var _a, _b, _c, _d, _e;
32
+ const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[table]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
33
+ if (type === 'json') {
34
+ return this.knex.raw("json_value(??.??, '$.size()')", [table, column]);
35
+ }
36
+ if (type === 'alias') {
37
+ return this._relationalCount(table, column);
38
+ }
39
+ throw new Error(`Couldn't extract type from ${table}.${column}`);
40
+ }
41
+ }
42
+ exports.FnHelperOracle = FnHelperOracle;
@@ -0,0 +1,13 @@
1
+ import { FnHelper } from '../types';
2
+ import { Knex } from 'knex';
3
+ export declare class FnHelperPostgres 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;
12
+ count(table: string, column: string): Knex.Raw;
13
+ }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DateHelperPostgres = void 0;
3
+ exports.FnHelperPostgres = void 0;
4
4
  const types_1 = require("../types");
5
- class DateHelperPostgres extends types_1.DateHelper {
5
+ class FnHelperPostgres extends types_1.FnHelper {
6
6
  year(table, column) {
7
7
  return this.knex.raw('EXTRACT(YEAR FROM ??.??)', [table, column]);
8
8
  }
@@ -27,5 +27,20 @@ class DateHelperPostgres extends types_1.DateHelper {
27
27
  second(table, column) {
28
28
  return this.knex.raw('EXTRACT(SECOND FROM ??.??)', [table, column]);
29
29
  }
30
+ count(table, column) {
31
+ var _a, _b, _c, _d, _e;
32
+ const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[table]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
33
+ if (type === 'json') {
34
+ const { dbType } = this.schema.collections[table].fields[column];
35
+ return this.knex.raw(dbType === 'jsonb' ? 'jsonb_array_length(??.??)' : 'json_array_length(??.??)', [
36
+ table,
37
+ column,
38
+ ]);
39
+ }
40
+ if (type === 'alias') {
41
+ return this._relationalCount(table, column);
42
+ }
43
+ throw new Error(`Couldn't extract type from ${table}.${column}`);
44
+ }
30
45
  }
31
- exports.DateHelperPostgres = DateHelperPostgres;
46
+ exports.FnHelperPostgres = FnHelperPostgres;
@@ -0,0 +1,13 @@
1
+ import { FnHelper } from '../types';
2
+ import { Knex } from 'knex';
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;
12
+ count(table: string, column: string): Knex.Raw<any>;
13
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FnHelperSQLite = void 0;
4
+ const types_1 = require("../types");
5
+ class FnHelperSQLite extends types_1.FnHelper {
6
+ year(table, column) {
7
+ return this.knex.raw("CAST(strftime('%Y', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
8
+ }
9
+ month(table, column) {
10
+ return this.knex.raw("CAST(strftime('%m', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
11
+ }
12
+ week(table, column) {
13
+ return this.knex.raw("CAST(strftime('%W', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
14
+ }
15
+ day(table, column) {
16
+ return this.knex.raw("CAST(strftime('%d', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
17
+ }
18
+ weekday(table, column) {
19
+ return this.knex.raw("CAST(strftime('%w', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
20
+ }
21
+ hour(table, column) {
22
+ return this.knex.raw("CAST(strftime('%H', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
23
+ }
24
+ minute(table, column) {
25
+ return this.knex.raw("CAST(strftime('%M', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
26
+ }
27
+ second(table, column) {
28
+ return this.knex.raw("CAST(strftime('%S', ??.?? / 1000, 'unixepoch') AS INTEGER)", [table, column]);
29
+ }
30
+ count(table, column) {
31
+ var _a, _b, _c, _d, _e;
32
+ const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[table]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
33
+ if (type === 'json') {
34
+ return this.knex.raw(`json_array_length(??.??, '$')`, [table, column]);
35
+ }
36
+ if (type === 'alias') {
37
+ return this._relationalCount(table, column);
38
+ }
39
+ throw new Error(`Couldn't extract type from ${table}.${column}`);
40
+ }
41
+ }
42
+ exports.FnHelperSQLite = FnHelperSQLite;
@@ -0,0 +1,7 @@
1
+ export { FnHelperPostgres as postgres } from './dialects/postgres';
2
+ export { FnHelperPostgres as redshift } from './dialects/postgres';
3
+ export { FnHelperPostgres as cockroachdb } from './dialects/postgres';
4
+ export { FnHelperOracle as oracle } from './dialects/oracle';
5
+ export { FnHelperSQLite as sqlite } from './dialects/sqlite';
6
+ export { FnHelperMySQL as mysql } from './dialects/mysql';
7
+ export { FnHelperMSSQL as mssql } from './dialects/mssql';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mssql = exports.mysql = exports.sqlite = exports.oracle = exports.cockroachdb = exports.redshift = exports.postgres = void 0;
4
+ var postgres_1 = require("./dialects/postgres");
5
+ Object.defineProperty(exports, "postgres", { enumerable: true, get: function () { return postgres_1.FnHelperPostgres; } });
6
+ var postgres_2 = require("./dialects/postgres");
7
+ Object.defineProperty(exports, "redshift", { enumerable: true, get: function () { return postgres_2.FnHelperPostgres; } });
8
+ var postgres_3 = require("./dialects/postgres");
9
+ Object.defineProperty(exports, "cockroachdb", { enumerable: true, get: function () { return postgres_3.FnHelperPostgres; } });
10
+ var oracle_1 = require("./dialects/oracle");
11
+ Object.defineProperty(exports, "oracle", { enumerable: true, get: function () { return oracle_1.FnHelperOracle; } });
12
+ var sqlite_1 = require("./dialects/sqlite");
13
+ Object.defineProperty(exports, "sqlite", { enumerable: true, get: function () { return sqlite_1.FnHelperSQLite; } });
14
+ var mysql_1 = require("./dialects/mysql");
15
+ Object.defineProperty(exports, "mysql", { enumerable: true, get: function () { return mysql_1.FnHelperMySQL; } });
16
+ var mssql_1 = require("./dialects/mssql");
17
+ Object.defineProperty(exports, "mssql", { enumerable: true, get: function () { return mssql_1.FnHelperMSSQL; } });
@@ -0,0 +1,18 @@
1
+ import { SchemaOverview } from '@directus/shared/types';
2
+ import { Knex } from 'knex';
3
+ import { DatabaseHelper } from '../types';
4
+ export declare abstract class FnHelper extends DatabaseHelper {
5
+ protected knex: Knex;
6
+ protected schema: SchemaOverview;
7
+ 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;
17
+ protected _relationalCount(table: string, column: string): Knex.Raw;
18
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FnHelper = void 0;
4
+ const types_1 = require("../types");
5
+ class FnHelper extends types_1.DatabaseHelper {
6
+ constructor(knex, schema) {
7
+ super(knex);
8
+ this.knex = knex;
9
+ this.schema = schema;
10
+ this.schema = schema;
11
+ }
12
+ _relationalCount(table, column) {
13
+ const relation = this.schema.relations.find((relation) => { var _a; return relation.related_collection === table && ((_a = relation === null || relation === void 0 ? void 0 : relation.meta) === null || _a === void 0 ? void 0 : _a.one_field) === column; });
14
+ const currentPrimary = this.schema.collections[table].primary;
15
+ if (!relation) {
16
+ throw new Error(`Field ${table}.${column} isn't a nested relational collection`);
17
+ }
18
+ return this.knex.raw('(' +
19
+ this.knex
20
+ .count('*')
21
+ .from(relation.collection)
22
+ .where(relation.field, '=', this.knex.raw(`??.??`, [table, currentPrimary]))
23
+ .toQuery() +
24
+ ')');
25
+ }
26
+ }
27
+ exports.FnHelper = FnHelper;
@@ -1,10 +1,13 @@
1
+ import { SchemaOverview } from '@directus/shared/types';
1
2
  import { Knex } from 'knex';
2
3
  import * as dateHelpers from './date';
4
+ import * as fnHelpers from './fn';
3
5
  import * as geometryHelpers from './geometry';
4
6
  import * as schemaHelpers from './schema';
5
7
  export declare function getHelpers(database: Knex): {
6
- date: dateHelpers.postgres | dateHelpers.oracle | dateHelpers.sqlite | dateHelpers.mysql | dateHelpers.mssql;
8
+ date: dateHelpers.postgres | dateHelpers.oracle | dateHelpers.mysql | dateHelpers.mssql | dateHelpers.sqlite;
7
9
  st: geometryHelpers.postgres | geometryHelpers.redshift | geometryHelpers.oracle | geometryHelpers.sqlite | geometryHelpers.mysql | geometryHelpers.mssql;
8
10
  schema: schemaHelpers.postgres | schemaHelpers.cockroachdb | schemaHelpers.oracle;
9
11
  };
12
+ export declare function getFunctions(database: Knex, schema: SchemaOverview): fnHelpers.postgres | fnHelpers.oracle | fnHelpers.sqlite | fnHelpers.mysql | fnHelpers.mssql;
10
13
  export declare type Helpers = ReturnType<typeof getHelpers>;
@@ -19,9 +19,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.getHelpers = void 0;
22
+ exports.getFunctions = exports.getHelpers = void 0;
23
23
  const __1 = require("..");
24
24
  const dateHelpers = __importStar(require("./date"));
25
+ const fnHelpers = __importStar(require("./fn"));
25
26
  const geometryHelpers = __importStar(require("./geometry"));
26
27
  const schemaHelpers = __importStar(require("./schema"));
27
28
  function getHelpers(database) {
@@ -33,3 +34,8 @@ function getHelpers(database) {
33
34
  };
34
35
  }
35
36
  exports.getHelpers = getHelpers;
37
+ function getFunctions(database, schema) {
38
+ const client = (0, __1.getDatabaseClient)(database);
39
+ return new fnHelpers[client](database, schema);
40
+ }
41
+ exports.getFunctions = getFunctions;
@@ -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,17 @@
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_presets', (table) => {
6
+ table.string('icon', 30).notNullable().defaultTo('bookmark_outline');
7
+ table.string('color').nullable();
8
+ });
9
+ }
10
+ exports.up = up;
11
+ async function down(knex) {
12
+ await knex.schema.alterTable('directus_presets', (table) => {
13
+ table.dropColumn('icon');
14
+ table.dropColumn('color');
15
+ });
16
+ }
17
+ exports.down = down;
@@ -31,7 +31,9 @@ async function up(knex) {
31
31
  }
32
32
  });
33
33
  if (updateRequired) {
34
- await knex('directus_fields').update({ special: parsedSpecial }).where({ id });
34
+ await knex('directus_fields')
35
+ .update({ special: parsedSpecial.join(',') })
36
+ .where({ id });
35
37
  }
36
38
  }
37
39
  }
@@ -65,7 +67,9 @@ async function down(knex) {
65
67
  }
66
68
  });
67
69
  if (updateRequired) {
68
- await knex('directus_fields').update({ special: parsedSpecial }).where({ id });
70
+ await knex('directus_fields')
71
+ .update({ special: parsedSpecial.join(',') })
72
+ .where({ id });
69
73
  }
70
74
  }
71
75
  }
@@ -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,17 @@
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_fields', (table) => {
6
+ table.json('validation');
7
+ table.text('validation_message');
8
+ });
9
+ }
10
+ exports.up = up;
11
+ async function down(knex) {
12
+ await knex.schema.alterTable('directus_fields', (table) => {
13
+ table.dropColumn('validation');
14
+ table.dropColumn('validation_message');
15
+ });
16
+ }
17
+ 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,49 @@
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 lodash_1 = require("lodash");
6
+ async function up(knex) {
7
+ const fields = await knex
8
+ .select('id', 'special')
9
+ .from('directus_fields')
10
+ .whereNotNull('special')
11
+ .orWhere('special', '<>', '');
12
+ for (const { id, special } of fields) {
13
+ let parsedSpecial;
14
+ try {
15
+ if (special.includes('{')) {
16
+ // Fix invalid data in Postgres
17
+ parsedSpecial = (0, utils_1.toArray)(special.replace(/{/g, '').replace(/}/g, '').replace(/"/g, ''));
18
+ }
19
+ else {
20
+ parsedSpecial = (0, utils_1.toArray)(special);
21
+ }
22
+ }
23
+ catch {
24
+ continue;
25
+ }
26
+ if (parsedSpecial && (0, lodash_1.isArray)(parsedSpecial)) {
27
+ // Perform the update again in case it was not performed prior
28
+ parsedSpecial = parsedSpecial.map((special) => {
29
+ switch (special) {
30
+ case 'boolean':
31
+ case 'csv':
32
+ case 'json':
33
+ return 'cast-' + special;
34
+ default:
35
+ return special;
36
+ }
37
+ });
38
+ const parsedSpecialString = parsedSpecial.join(',');
39
+ if (parsedSpecialString !== special) {
40
+ await knex('directus_fields').update({ special: parsedSpecialString }).where({ id });
41
+ }
42
+ }
43
+ }
44
+ }
45
+ exports.up = up;
46
+ async function down(_knex) {
47
+ // Do nothing
48
+ }
49
+ 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,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ const helpers_1 = require("../helpers");
5
+ async function up(knex) {
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await knex.schema.alterTable('directus_settings', (table) => {
8
+ table.string('default_language').notNullable().defaultTo('en-US');
9
+ });
10
+ await helper.changeToString('directus_users', 'language', {
11
+ nullable: true,
12
+ default: null,
13
+ length: 255,
14
+ });
15
+ }
16
+ exports.up = up;
17
+ async function down(knex) {
18
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
19
+ await knex.schema.alterTable('directus_settings', (table) => {
20
+ table.dropColumn('default_language');
21
+ });
22
+ await helper.changeToString('directus_users', 'language', {
23
+ nullable: true,
24
+ default: 'en-US',
25
+ length: 255,
26
+ });
27
+ }
28
+ 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,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.down = exports.up = void 0;
4
+ const helpers_1 = require("../helpers");
5
+ async function up(knex) {
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await helper.changeToString('directus_panels', 'icon', {
8
+ nullable: true,
9
+ default: null,
10
+ length: 30,
11
+ });
12
+ }
13
+ exports.up = up;
14
+ async function down(knex) {
15
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
16
+ await helper.changeToString('directus_panels', 'icon', {
17
+ nullable: true,
18
+ default: 'insert_chart',
19
+ length: 30,
20
+ });
21
+ }
22
+ exports.down = down;
@@ -107,7 +107,7 @@ async function parseCurrentLevel(schema, collection, children, query) {
107
107
  if (!child.relation)
108
108
  continue;
109
109
  if (child.type === 'm2o') {
110
- columnsToSelectInternal.push(child.fieldKey);
110
+ columnsToSelectInternal.push(child.relation.field);
111
111
  }
112
112
  if (child.type === 'a2o') {
113
113
  columnsToSelectInternal.push(child.relation.field);
@@ -126,7 +126,7 @@ async function parseCurrentLevel(schema, collection, children, query) {
126
126
  const columnsToSelect = [...new Set(columnsToSelectInternal)];
127
127
  const fieldNodes = columnsToSelect.map((column) => {
128
128
  var _a;
129
- return (_a = children.find((childNode) => childNode.type === 'field' && childNode.fieldKey === column)) !== null && _a !== void 0 ? _a : {
129
+ return (_a = children.find((childNode) => childNode.type === 'field' && (childNode.fieldKey === column || childNode.name === column))) !== null && _a !== void 0 ? _a : {
130
130
  type: 'field',
131
131
  name: column,
132
132
  fieldKey: column,
@@ -151,7 +151,7 @@ function getColumnPreprocessor(knex, schema, table) {
151
151
  if (field.type.startsWith('geometry')) {
152
152
  return helpers.st.asText(table, field.field);
153
153
  }
154
- return (0, get_column_1.getColumn)(knex, table, fieldNode.name, alias);
154
+ return (0, get_column_1.getColumn)(knex, table, fieldNode.name, alias, schema);
155
155
  };
156
156
  }
157
157
  function getDBQuery(schema, knex, table, fieldNodes, query) {
@@ -221,7 +221,7 @@ function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
221
221
  for (const parentItem of parentItems) {
222
222
  const itemChild = nestedItems.find((nestedItem) => {
223
223
  return (nestedItem[schema.collections[nestedNode.relation.related_collection].primary] ==
224
- parentItem[nestedNode.fieldKey]);
224
+ parentItem[nestedNode.relation.field]);
225
225
  });
226
226
  parentItem[nestedNode.fieldKey] = itemChild || null;
227
227
  }
@@ -244,7 +244,9 @@ function mergeWithParentItems(schema, nestedItem, parentItem, nestedNode) {
244
244
  if (nestedNode.query.offset && nestedNode.query.offset >= 0) {
245
245
  parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(nestedNode.query.offset);
246
246
  }
247
- parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, (_a = nestedNode.query.limit) !== null && _a !== void 0 ? _a : 100);
247
+ if (nestedNode.query.limit !== -1) {
248
+ parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].slice(0, (_a = nestedNode.query.limit) !== null && _a !== void 0 ? _a : 100);
249
+ }
248
250
  parentItem[nestedNode.fieldKey] = parentItem[nestedNode.fieldKey].sort((a, b) => {
249
251
  // This is pre-filled in get-ast-from-query
250
252
  const sortField = nestedNode.query.sort[0];
@@ -46,19 +46,19 @@ fields:
46
46
  width: half
47
47
 
48
48
  - field: comment
49
- display: formatted-text
49
+ display: formatted-value
50
50
  display_options:
51
- subdued: true
51
+ color: 'var(--foreground-subdued)'
52
52
  width: half
53
53
 
54
54
  - field: user_agent
55
- display: formatted-text
55
+ display: formatted-value
56
56
  display_options:
57
57
  font: monospace
58
58
  width: half
59
59
 
60
60
  - field: ip
61
- display: formatted-text
61
+ display: formatted-value
62
62
  display_options:
63
63
  font: monospace
64
64
  width: half
@@ -193,7 +193,7 @@ fields:
193
193
 
194
194
  - field: item_duplication_fields
195
195
  special:
196
- - json
196
+ - cast-json
197
197
  interface: system-field-tree
198
198
  options:
199
199
  collectionField: collection