directus 9.4.2 → 9.5.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 (124) hide show
  1. package/README.md +1 -1
  2. package/dist/app.js +9 -0
  3. package/dist/auth/auth.d.ts +2 -1
  4. package/dist/auth/drivers/oauth2.js +10 -20
  5. package/dist/auth/drivers/openid.js +18 -8
  6. package/dist/cli/commands/init/index.js +8 -0
  7. package/dist/cli/commands/init/questions.d.ts +3 -0
  8. package/dist/cli/commands/init/questions.js +2 -0
  9. package/dist/cli/index.js +1 -1
  10. package/dist/cli/utils/create-db-connection.d.ts +1 -1
  11. package/dist/cli/utils/create-db-connection.js +11 -1
  12. package/dist/cli/utils/drivers.d.ts +1 -0
  13. package/dist/cli/utils/drivers.js +2 -1
  14. package/dist/controllers/extensions.js +1 -1
  15. package/dist/controllers/files.js +3 -0
  16. package/dist/controllers/utils.js +2 -0
  17. package/dist/database/helpers/date/index.d.ts +1 -0
  18. package/dist/database/helpers/date/index.js +3 -1
  19. package/dist/database/helpers/geometry/index.d.ts +1 -0
  20. package/dist/database/helpers/geometry/index.js +3 -1
  21. package/dist/database/helpers/index.d.ts +2 -0
  22. package/dist/database/helpers/index.js +2 -0
  23. package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +16 -0
  24. package/dist/database/helpers/schema/dialects/cockroachdb.js +16 -0
  25. package/dist/database/helpers/schema/dialects/default.d.ts +3 -0
  26. package/dist/database/helpers/schema/dialects/default.js +7 -0
  27. package/dist/database/helpers/schema/dialects/oracle.d.ts +12 -0
  28. package/dist/database/helpers/schema/dialects/oracle.js +13 -0
  29. package/dist/database/helpers/schema/index.d.ts +7 -0
  30. package/dist/database/helpers/schema/index.js +17 -0
  31. package/dist/database/helpers/schema/types.d.ts +25 -0
  32. package/dist/database/helpers/schema/types.js +89 -0
  33. package/dist/database/index.d.ts +1 -1
  34. package/dist/database/index.js +66 -20
  35. package/dist/database/migrations/20201105B-change-webhook-url-type.js +6 -25
  36. package/dist/database/migrations/20210312A-webhooks-collections-text.js +6 -25
  37. package/dist/database/migrations/20210415A-make-filesize-nullable.js +9 -4
  38. package/dist/database/migrations/20210506A-rename-interfaces.js +1 -1
  39. package/dist/database/migrations/20210510A-restructure-relations.js +12 -4
  40. package/dist/database/migrations/20210525A-add-insights.js +2 -2
  41. package/dist/database/migrations/20210626A-change-filesize-bigint.js +5 -7
  42. package/dist/database/migrations/20210903A-add-auth-provider.js +11 -2
  43. package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +6 -20
  44. package/dist/database/migrations/20210920A-webhooks-url-not-null.js +10 -14
  45. package/dist/database/migrations/20211211A-add-shares.js +2 -2
  46. package/dist/database/migrations/run.js +1 -1
  47. package/dist/database/run-ast.d.ts +1 -1
  48. package/dist/database/seeds/01-collections.yaml +1 -0
  49. package/dist/database/seeds/02-roles.yaml +1 -0
  50. package/dist/database/seeds/03-users.yaml +1 -0
  51. package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +8 -2
  52. package/dist/database/system-data/fields/collections.yaml +2 -0
  53. package/dist/database/system-data/relations/index.d.ts +1 -1
  54. package/dist/emitter.d.ts +3 -4
  55. package/dist/emitter.js +2 -8
  56. package/dist/env.js +1 -0
  57. package/dist/exceptions/database/translate.js +1 -0
  58. package/dist/exceptions/index.d.ts +1 -0
  59. package/dist/exceptions/index.js +1 -0
  60. package/dist/exceptions/unsupported-media-type.d.ts +4 -0
  61. package/dist/exceptions/unsupported-media-type.js +10 -0
  62. package/dist/extensions.d.ts +14 -8
  63. package/dist/extensions.js +136 -69
  64. package/dist/logger.js +22 -1
  65. package/dist/middleware/extract-token.js +1 -1
  66. package/dist/services/assets.js +3 -3
  67. package/dist/services/authentication.d.ts +2 -2
  68. package/dist/services/authentication.js +7 -2
  69. package/dist/services/authorization.d.ts +2 -3
  70. package/dist/services/collections.d.ts +2 -2
  71. package/dist/services/collections.js +20 -18
  72. package/dist/services/fields.d.ts +2 -3
  73. package/dist/services/fields.js +14 -10
  74. package/dist/services/graphql.d.ts +2 -1
  75. package/dist/services/graphql.js +4 -4
  76. package/dist/services/import.d.ts +2 -2
  77. package/dist/services/import.js +2 -1
  78. package/dist/services/items.d.ts +2 -2
  79. package/dist/services/items.js +22 -18
  80. package/dist/services/mail/index.d.ts +2 -2
  81. package/dist/services/meta.d.ts +2 -2
  82. package/dist/services/payload.d.ts +2 -2
  83. package/dist/services/payload.js +7 -3
  84. package/dist/services/relations.d.ts +2 -2
  85. package/dist/services/relations.js +4 -0
  86. package/dist/services/server.d.ts +2 -2
  87. package/dist/services/specifications.d.ts +2 -2
  88. package/dist/services/users.d.ts +2 -3
  89. package/dist/services/utils.d.ts +2 -2
  90. package/dist/types/ast.d.ts +1 -2
  91. package/dist/types/auth.d.ts +1 -3
  92. package/dist/types/index.d.ts +0 -3
  93. package/dist/types/index.js +0 -3
  94. package/dist/types/services.d.ts +1 -3
  95. package/dist/types/snapshot.d.ts +1 -2
  96. package/dist/utils/apply-query.d.ts +1 -2
  97. package/dist/utils/apply-query.js +1 -1
  98. package/dist/utils/apply-snapshot.d.ts +2 -1
  99. package/dist/utils/get-ast-from-query.d.ts +2 -3
  100. package/dist/utils/get-local-type.js +1 -1
  101. package/dist/utils/get-permissions.d.ts +1 -2
  102. package/dist/utils/get-permissions.js +1 -1
  103. package/dist/utils/get-relation-type.d.ts +1 -1
  104. package/dist/utils/get-schema.d.ts +1 -2
  105. package/dist/utils/get-snapshot.d.ts +2 -1
  106. package/dist/utils/md.js +1 -1
  107. package/dist/utils/merge-permissions-for-share.d.ts +1 -2
  108. package/dist/utils/reduce-schema.d.ts +1 -2
  109. package/example.env +8 -0
  110. package/package.json +23 -17
  111. package/dist/cli/index.test.d.ts +0 -1
  112. package/dist/cli/index.test.js +0 -58
  113. package/dist/middleware/cache.test.d.ts +0 -1
  114. package/dist/middleware/cache.test.js +0 -62
  115. package/dist/tests/database/migrations/run.test.d.ts +0 -1
  116. package/dist/tests/database/migrations/run.test.js +0 -29
  117. package/dist/types/extensions.d.ts +0 -43
  118. package/dist/types/extensions.js +0 -2
  119. package/dist/types/relation.d.ts +0 -21
  120. package/dist/types/relation.js +0 -2
  121. package/dist/types/schema.d.ts +0 -32
  122. package/dist/types/schema.js +0 -2
  123. package/dist/utils/get-cache-key.test.d.ts +0 -1
  124. package/dist/utils/get-cache-key.test.js +0 -53
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SchemaHelper = void 0;
4
+ const index_1 = require("../../index");
5
+ const types_1 = require("../types");
6
+ class SchemaHelper extends types_1.DatabaseHelper {
7
+ isOneOfClients(clients) {
8
+ return clients.includes((0, index_1.getDatabaseClient)(this.knex));
9
+ }
10
+ async changeNullable(table, column, nullable) {
11
+ await this.knex.schema.alterTable(table, (builder) => {
12
+ if (nullable) {
13
+ builder.setNullable(column);
14
+ }
15
+ else {
16
+ builder.dropNullable(column);
17
+ }
18
+ });
19
+ }
20
+ async changeToText(table, column, options = {}) {
21
+ await this.knex.schema.alterTable(table, (builder) => {
22
+ const b = builder.string(column);
23
+ if (options.nullable === true) {
24
+ b.nullable();
25
+ }
26
+ if (options.nullable === false) {
27
+ b.notNullable();
28
+ }
29
+ if (options.default !== undefined) {
30
+ b.defaultTo(options.default);
31
+ }
32
+ b.alter();
33
+ });
34
+ }
35
+ async changeToInteger(table, column, options = {}) {
36
+ await this.knex.schema.alterTable(table, (builder) => {
37
+ const b = builder.integer(column);
38
+ if (options.nullable === true) {
39
+ b.nullable();
40
+ }
41
+ if (options.nullable === false) {
42
+ b.notNullable();
43
+ }
44
+ if (options.default !== undefined) {
45
+ b.defaultTo(options.default);
46
+ }
47
+ b.alter();
48
+ });
49
+ }
50
+ async changeToString(table, column, options = {}) {
51
+ await this.knex.schema.alterTable(table, (builder) => {
52
+ const b = builder.string(column, options.length);
53
+ if (options.nullable === true) {
54
+ b.nullable();
55
+ }
56
+ if (options.nullable === false) {
57
+ b.notNullable();
58
+ }
59
+ if (options.default !== undefined) {
60
+ b.defaultTo(options.default);
61
+ }
62
+ b.alter();
63
+ });
64
+ }
65
+ async changeToTypeByCopy(table, column, options, cb) {
66
+ await this.knex.schema.alterTable(table, (builder) => {
67
+ const col = cb(builder, `${column}__temp`, options);
68
+ if (options.default !== undefined) {
69
+ col.defaultTo(options.default);
70
+ }
71
+ // Force new temporary column to be nullable (required, as there will already be rows in
72
+ // the table)
73
+ col.nullable();
74
+ });
75
+ await this.knex(table).update(`${column}__temp`, this.knex.ref(column));
76
+ await this.knex.schema.alterTable(table, (builder) => {
77
+ builder.dropColumn(column);
78
+ });
79
+ await this.knex.schema.alterTable(table, (builder) => {
80
+ builder.renameColumn(`${column}__temp`, column);
81
+ });
82
+ // We're altering the temporary column here. That starts nullable, so we only want to set it
83
+ // to NOT NULL when applicable
84
+ if (options.nullable === false) {
85
+ await this.changeNullable(table, column, options.nullable);
86
+ }
87
+ }
88
+ }
89
+ exports.SchemaHelper = SchemaHelper;
@@ -4,7 +4,7 @@ export default function getDatabase(): Knex;
4
4
  export declare function getSchemaInspector(): ReturnType<typeof SchemaInspector>;
5
5
  export declare function hasDatabaseConnection(database?: Knex): Promise<boolean>;
6
6
  export declare function validateDatabaseConnection(database?: Knex): Promise<void>;
7
- export declare function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'sqlite' | 'oracle' | 'mssql' | 'redshift';
7
+ export declare function getDatabaseClient(database?: Knex): 'mysql' | 'postgres' | 'cockroachdb' | 'sqlite' | 'oracle' | 'mssql' | 'redshift';
8
8
  export declare function isInstalled(): Promise<boolean>;
9
9
  export declare function validateMigrations(): Promise<boolean>;
10
10
  /**
@@ -24,37 +24,43 @@ function getDatabase() {
24
24
  }
25
25
  const connectionConfig = (0, get_config_from_env_1.getConfigFromEnv)('DB_', [
26
26
  'DB_CLIENT',
27
+ 'DB_VERSION',
27
28
  'DB_SEARCH_PATH',
28
29
  'DB_CONNECTION_STRING',
29
30
  'DB_POOL',
30
31
  'DB_EXCLUDE_TABLES',
32
+ 'DB_VERSION',
31
33
  ]);
32
34
  const poolConfig = (0, get_config_from_env_1.getConfigFromEnv)('DB_POOL');
33
35
  const requiredEnvVars = ['DB_CLIENT'];
34
- if (env_1.default.DB_CLIENT && env_1.default.DB_CLIENT === 'sqlite3') {
35
- requiredEnvVars.push('DB_FILENAME');
36
- }
37
- else if (env_1.default.DB_CLIENT && env_1.default.DB_CLIENT === 'oracledb') {
38
- if (!env_1.default.DB_CONNECT_STRING) {
39
- requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD');
40
- }
41
- else {
42
- requiredEnvVars.push('DB_USER', 'DB_PASSWORD', 'DB_CONNECT_STRING');
43
- }
44
- }
45
- else {
46
- if (env_1.default.DB_CLIENT === 'pg') {
36
+ switch (env_1.default.DB_CLIENT) {
37
+ case 'sqlite3':
38
+ requiredEnvVars.push('DB_FILENAME');
39
+ break;
40
+ case 'oracledb':
41
+ if (!env_1.default.DB_CONNECT_STRING) {
42
+ requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD');
43
+ }
44
+ else {
45
+ requiredEnvVars.push('DB_USER', 'DB_PASSWORD', 'DB_CONNECT_STRING');
46
+ }
47
+ break;
48
+ case 'cockroachdb':
49
+ case 'pg':
47
50
  if (!env_1.default.DB_CONNECTION_STRING) {
48
51
  requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER');
49
52
  }
50
- }
51
- else {
53
+ else {
54
+ requiredEnvVars.push('DB_CONNECTION_STRING');
55
+ }
56
+ break;
57
+ default:
52
58
  requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD');
53
- }
54
59
  }
55
60
  (0, validate_env_1.validateEnv)(requiredEnvVars);
56
61
  const knexConfig = {
57
62
  client: env_1.default.DB_CLIENT,
63
+ version: env_1.default.DB_VERSION,
58
64
  searchPath: env_1.default.DB_SEARCH_PATH,
59
65
  connection: env_1.default.DB_CONNECTION_STRING || connectionConfig,
60
66
  log: {
@@ -82,22 +88,29 @@ function getDatabase() {
82
88
  callback(null, conn);
83
89
  };
84
90
  }
91
+ if (env_1.default.DB_CLIENT === 'cockroachdb') {
92
+ poolConfig.afterCreate = async (conn, callback) => {
93
+ logger_1.default.trace('Setting CRDB serial_normalization and default_int_size');
94
+ const run = (0, util_1.promisify)(conn.query.bind(conn));
95
+ await run('SET serial_normalization = "sql_sequence"');
96
+ await run('SET default_int_size = 4');
97
+ callback(null, conn);
98
+ };
99
+ }
85
100
  if (env_1.default.DB_CLIENT === 'mssql') {
86
101
  // This brings MS SQL in line with the other DB vendors. We shouldn't do any automatic
87
102
  // timezone conversion on the database level, especially not when other database vendors don't
88
103
  // act the same
89
104
  (0, lodash_1.merge)(knexConfig, { connection: { options: { useUTC: false } } });
90
105
  }
91
- if (env_1.default.DB_CLIENT === 'mysql' && !env_1.default.DB_CHARSET) {
92
- logger_1.default.warn(`DB_CHARSET hasn't been set. Please make sure DB_CHARSET matches your database's collation.`);
93
- }
94
106
  database = (0, knex_1.knex)(knexConfig);
107
+ validateDatabaseCharset(database);
95
108
  const times = {};
96
109
  database
97
110
  .on('query', (queryInfo) => {
98
111
  times[queryInfo.__knexUid] = perf_hooks_1.performance.now();
99
112
  })
100
- .on('query-response', (response, queryInfo) => {
113
+ .on('query-response', (_response, queryInfo) => {
101
114
  const delta = perf_hooks_1.performance.now() - times[queryInfo.__knexUid];
102
115
  logger_1.default.trace(`[${delta.toFixed(3)}ms] ${queryInfo.sql} [${queryInfo.bindings.join(', ')}]`);
103
116
  delete times[queryInfo.__knexUid];
@@ -154,6 +167,8 @@ function getDatabaseClient(database) {
154
167
  return 'mysql';
155
168
  case 'Client_PG':
156
169
  return 'postgres';
170
+ case 'Client_CockroachDB':
171
+ return 'cockroachdb';
157
172
  case 'Client_SQLite3':
158
173
  return 'sqlite';
159
174
  case 'Client_Oracledb':
@@ -217,3 +232,34 @@ async function validateDatabaseExtensions() {
217
232
  }
218
233
  }
219
234
  exports.validateDatabaseExtensions = validateDatabaseExtensions;
235
+ async function validateDatabaseCharset(database) {
236
+ database = database !== null && database !== void 0 ? database : getDatabase();
237
+ if (getDatabaseClient(database) === 'mysql') {
238
+ if (env_1.default.DB_CHARSET) {
239
+ logger_1.default.warn(`Using custom DB_CHARSET "${env_1.default.DB_CHARSET}". Using a charset different from the database's default can cause problems in relationships. Omitting DB_CHARSET is strongly recommended.`);
240
+ }
241
+ const { collation } = await database.select(database.raw(`@@collation_database as collation`)).first();
242
+ const tables = await database('information_schema.tables')
243
+ .select({ name: 'TABLE_NAME', collation: 'TABLE_COLLATION' })
244
+ .where({ TABLE_SCHEMA: env_1.default.DB_DATABASE });
245
+ const columns = await database('information_schema.columns')
246
+ .select({ table_name: 'TABLE_NAME', name: 'COLUMN_NAME', collation: 'COLLATION_NAME' })
247
+ .where({ TABLE_SCHEMA: env_1.default.DB_DATABASE })
248
+ .whereNot({ COLLATION_NAME: collation });
249
+ let inconsistencies = '';
250
+ for (const table of tables) {
251
+ const tableColumns = columns.filter((column) => column.table_name === table.name);
252
+ const tableHasInvalidCollation = table.collation !== collation;
253
+ if (tableHasInvalidCollation || tableColumns.length > 0) {
254
+ inconsistencies += `\t\t- Table "${table.name}": "${table.collation}"\n`;
255
+ for (const column of tableColumns) {
256
+ inconsistencies += `\t\t - Column "${column.name}": "${column.collation}"\n`;
257
+ }
258
+ }
259
+ }
260
+ if (inconsistencies) {
261
+ logger_1.default.warn(`Some tables and columns do not match your database's default collation (${collation}):\n${inconsistencies}`);
262
+ }
263
+ }
264
+ return;
265
+ }
@@ -1,35 +1,16 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.down = exports.up = void 0;
7
- // @ts-ignore
8
- const oracledb_1 = __importDefault(require("knex/lib/dialects/oracledb"));
9
- async function oracleAlterUrl(knex, type) {
10
- await knex.raw('ALTER TABLE "directus_webhooks" ADD "url__temp" ?', [knex.raw(type)]);
11
- await knex.raw('UPDATE "directus_webhooks" SET "url__temp"="url"');
12
- await knex.raw('ALTER TABLE "directus_webhooks" DROP COLUMN "url"');
13
- await knex.raw('ALTER TABLE "directus_webhooks" RENAME COLUMN "url__temp" TO "url"');
14
- await knex.raw('ALTER TABLE "directus_webhooks" MODIFY "url" NOT NULL');
15
- }
4
+ const helpers_1 = require("../helpers");
16
5
  async function up(knex) {
17
- if (knex.client instanceof oracledb_1.default) {
18
- await oracleAlterUrl(knex, 'CLOB');
19
- return;
20
- }
21
- await knex.schema.alterTable('directus_webhooks', (table) => {
22
- table.text('url').alter();
23
- });
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await helper.changeToText('directus_webhooks', 'url');
24
8
  }
25
9
  exports.up = up;
26
10
  async function down(knex) {
27
- if (knex.client instanceof oracledb_1.default) {
28
- await oracleAlterUrl(knex, 'VARCHAR2(255)');
29
- return;
30
- }
31
- await knex.schema.alterTable('directus_webhooks', (table) => {
32
- table.string('url').notNullable().alter();
11
+ await (0, helpers_1.getHelpers)(knex).schema.changeToString('directus_webhooks', 'url', {
12
+ nullable: false,
13
+ length: 255,
33
14
  });
34
15
  }
35
16
  exports.down = down;
@@ -1,35 +1,16 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.down = exports.up = void 0;
7
- // @ts-ignore
8
- const oracledb_1 = __importDefault(require("knex/lib/dialects/oracledb"));
9
- async function oracleAlterCollections(knex, type) {
10
- await knex.raw('ALTER TABLE "directus_webhooks" ADD "collections__temp" ?', [knex.raw(type)]);
11
- await knex.raw('UPDATE "directus_webhooks" SET "collections__temp"="collections"');
12
- await knex.raw('ALTER TABLE "directus_webhooks" DROP COLUMN "collections"');
13
- await knex.raw('ALTER TABLE "directus_webhooks" RENAME COLUMN "collections__temp" TO "collections"');
14
- await knex.raw('ALTER TABLE "directus_webhooks" MODIFY "collections" NOT NULL');
15
- }
4
+ const helpers_1 = require("../helpers");
16
5
  async function up(knex) {
17
- if (knex.client instanceof oracledb_1.default) {
18
- await oracleAlterCollections(knex, 'CLOB');
19
- return;
20
- }
21
- await knex.schema.alterTable('directus_webhooks', (table) => {
22
- table.text('collections').alter();
23
- });
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await helper.changeToText('directus_webhooks', 'collections');
24
8
  }
25
9
  exports.up = up;
26
10
  async function down(knex) {
27
- if (knex.client instanceof oracledb_1.default) {
28
- await oracleAlterCollections(knex, 'VARCHAR2(255)');
29
- return;
30
- }
31
- await knex.schema.alterTable('directus_webhooks', (table) => {
32
- table.string('collections').notNullable().alter();
11
+ await (0, helpers_1.getHelpers)(knex).schema.changeToString('directus_webhooks', 'collections', {
12
+ nullable: false,
13
+ length: 255,
33
14
  });
34
15
  }
35
16
  exports.down = down;
@@ -1,15 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.down = exports.up = void 0;
4
+ const helpers_1 = require("../helpers");
4
5
  async function up(knex) {
5
- await knex.schema.alterTable('directus_files', (table) => {
6
- table.integer('filesize').nullable().defaultTo(null).alter();
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await helper.changeToInteger('directus_files', 'filesize', {
8
+ nullable: true,
9
+ default: null,
7
10
  });
8
11
  }
9
12
  exports.up = up;
10
13
  async function down(knex) {
11
- await knex.schema.alterTable('directus_files', (table) => {
12
- table.integer('filesize').notNullable().defaultTo(0).alter();
14
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
15
+ await helper.changeToInteger('directus_files', 'filesize', {
16
+ nullable: false,
17
+ default: 0,
13
18
  });
14
19
  }
15
20
  exports.down = down;
@@ -32,7 +32,7 @@ const changes = [
32
32
  ['toggle', 'boolean'],
33
33
  ['translations', 'translations'],
34
34
  ['tree-view', 'list-o2m-tree-view'],
35
- ['user', 'select-dropdown-m2o', { template: '{{avatar.$thumbnail}} {{first_name}} {{last_name}}' }],
35
+ ['user', 'select-dropdown-m2o', { template: '{{avatar.$thumbnail}} {{first_name}} {{last_name}}' }],
36
36
  ['wysiwyg', 'input-rich-text-html'],
37
37
  // System:
38
38
  ['collection', 'system-collection'],
@@ -1,24 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.down = exports.up = void 0;
4
+ const helpers_1 = require("../helpers");
4
5
  async function up(knex) {
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
5
7
  await knex.schema.alterTable('directus_relations', (table) => {
6
8
  table.dropColumns('many_primary', 'one_primary');
7
9
  table.string('one_deselect_action').defaultTo('nullify');
8
- table.string('sort_field', 64).alter();
9
10
  });
10
11
  await knex('directus_relations').update({ one_deselect_action: 'nullify' });
11
- await knex.schema.alterTable('directus_relations', (table) => {
12
- table.string('one_deselect_action').notNullable().defaultTo('nullify').alter();
12
+ await helper.changeToString('directus_relations', 'sort_field', {
13
+ length: 64,
14
+ });
15
+ await helper.changeToString('directus_relations', 'one_deselect_action', {
16
+ nullable: false,
17
+ default: 'nullify',
13
18
  });
14
19
  }
15
20
  exports.up = up;
16
21
  async function down(knex) {
22
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
23
+ await helper.changeToString('directus_relations', 'sort_field', {
24
+ length: 255,
25
+ });
17
26
  await knex.schema.alterTable('directus_relations', (table) => {
18
27
  table.dropColumn('one_deselect_action');
19
28
  table.string('many_primary', 64);
20
29
  table.string('one_primary', 64);
21
- table.string('sort_field', 255).alter();
22
30
  });
23
31
  }
24
32
  exports.down = down;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.down = exports.up = void 0;
4
4
  async function up(knex) {
5
5
  await knex.schema.createTable('directus_dashboards', (table) => {
6
- table.uuid('id').primary();
6
+ table.uuid('id').primary().notNullable();
7
7
  table.string('name').notNullable();
8
8
  table.string('icon', 30).notNullable().defaultTo('dashboard');
9
9
  table.text('note');
@@ -11,7 +11,7 @@ async function up(knex) {
11
11
  table.uuid('user_created').references('id').inTable('directus_users').onDelete('SET NULL');
12
12
  });
13
13
  await knex.schema.createTable('directus_panels', (table) => {
14
- table.uuid('id').primary();
14
+ table.uuid('id').primary().notNullable();
15
15
  table.uuid('dashboard').notNullable().references('id').inTable('directus_dashboards').onDelete('CASCADE');
16
16
  table.string('name');
17
17
  table.string('icon', 30).defaultTo('insert_chart');
@@ -1,13 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.down = exports.up = void 0;
7
- // @ts-ignore
8
- const oracledb_1 = __importDefault(require("knex/lib/dialects/oracledb"));
4
+ const helpers_1 = require("../helpers");
9
5
  async function up(knex) {
10
- if (knex.client instanceof oracledb_1.default) {
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ if (helper.isOneOfClients(['oracle', 'cockroachdb'])) {
11
8
  return;
12
9
  }
13
10
  await knex.schema.alterTable('directus_files', (table) => {
@@ -16,7 +13,8 @@ async function up(knex) {
16
13
  }
17
14
  exports.up = up;
18
15
  async function down(knex) {
19
- if (knex.client instanceof oracledb_1.default) {
16
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
17
+ if (helper.isOneOfClients(['oracle', 'cockroachdb'])) {
20
18
  return;
21
19
  }
22
20
  await knex.schema.alterTable('directus_files', (table) => {
@@ -1,14 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.down = exports.up = void 0;
4
+ const helpers_1 = require("../helpers");
4
5
  async function up(knex) {
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
5
7
  await knex.schema.alterTable('directus_users', (table) => {
6
8
  table.dropUnique(['email']);
7
9
  });
8
10
  await knex.schema.alterTable('directus_users', (table) => {
9
11
  table.string('provider', 128).notNullable().defaultTo('default');
10
12
  table.string('external_identifier').unique();
11
- table.string('email', 128).nullable().alter();
13
+ });
14
+ await helper.changeToString('directus_users', 'email', {
15
+ nullable: true,
16
+ length: 128,
12
17
  });
13
18
  await knex.schema.alterTable('directus_users', (table) => {
14
19
  table.unique(['email']);
@@ -19,10 +24,14 @@ async function up(knex) {
19
24
  }
20
25
  exports.up = up;
21
26
  async function down(knex) {
27
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
22
28
  await knex.schema.alterTable('directus_users', (table) => {
23
29
  table.dropColumn('provider');
24
30
  table.dropColumn('external_identifier');
25
- table.string('email', 128).notNullable().alter();
31
+ });
32
+ await helper.changeToString('directus_users', 'email', {
33
+ nullable: false,
34
+ length: 128,
26
35
  });
27
36
  await knex.schema.alterTable('directus_sessions', (table) => {
28
37
  table.dropColumn('data');
@@ -1,30 +1,16 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.down = exports.up = void 0;
7
- // @ts-ignore
8
- const oracledb_1 = __importDefault(require("knex/lib/dialects/oracledb"));
4
+ const helpers_1 = require("../helpers");
9
5
  async function up(knex) {
10
- if (knex.client instanceof oracledb_1.default) {
11
- // Oracle is already not nullable due to an oversight in
12
- // "20210312A-webhooks-collections-text.ts"
13
- return;
14
- }
15
- await knex.schema.alterTable('directus_webhooks', (table) => {
16
- table.text('collections').notNullable().alter();
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ await helper.changeToText('directus_webhooks', 'collections', {
8
+ nullable: false,
17
9
  });
18
10
  }
19
11
  exports.up = up;
20
12
  async function down(knex) {
21
- if (knex.client instanceof oracledb_1.default) {
22
- // Oracle is already not nullable due to an oversight in
23
- // "20210312A-webhooks-collections-text.ts"
24
- return;
25
- }
26
- await knex.schema.alterTable('directus_webhooks', (table) => {
27
- table.text('collections').alter();
28
- });
13
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
14
+ await helper.changeToText('directus_webhooks', 'collections');
29
15
  }
30
16
  exports.down = down;
@@ -1,30 +1,26 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.down = exports.up = void 0;
7
- // @ts-ignore
8
- const oracledb_1 = __importDefault(require("knex/lib/dialects/oracledb"));
4
+ const helpers_1 = require("../helpers");
9
5
  async function up(knex) {
10
- if (knex.client instanceof oracledb_1.default) {
11
- // Oracle is already not nullable due to an oversight in
6
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
7
+ if (helper.isOneOfClients(['oracle', 'cockroachdb'])) {
8
+ // Oracle and Cockroach are already not nullable due to an oversight in
12
9
  // "20201105B-change-webhook-url-type.ts"
13
10
  return;
14
11
  }
15
- await knex.schema.alterTable('directus_webhooks', (table) => {
16
- table.text('url').notNullable().alter();
12
+ await helper.changeToText('directus_webhooks', 'url', {
13
+ nullable: false,
17
14
  });
18
15
  }
19
16
  exports.up = up;
20
17
  async function down(knex) {
21
- if (knex.client instanceof oracledb_1.default) {
22
- // Oracle is already not nullable due to an oversight in
18
+ const helper = (0, helpers_1.getHelpers)(knex).schema;
19
+ if (helper.isOneOfClients(['oracle', 'cockroachdb'])) {
20
+ // Oracle and Cockroach are already not nullable due to an oversight in
23
21
  // "20201105B-change-webhook-url-type.ts"
24
22
  return;
25
23
  }
26
- await knex.schema.alterTable('directus_webhooks', (table) => {
27
- table.text('url').alter();
28
- });
24
+ await helper.changeToText('directus_webhooks', 'url');
29
25
  }
30
26
  exports.down = down;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.down = exports.up = void 0;
4
4
  async function up(knex) {
5
5
  await knex.schema.createTable('directus_shares', (table) => {
6
- table.uuid('id').primary();
6
+ table.uuid('id').primary().notNullable();
7
7
  table.string('name');
8
8
  table.string('collection', 64).references('collection').inTable('directus_collections').onDelete('CASCADE');
9
9
  table.string('item');
@@ -21,7 +21,7 @@ async function up(knex) {
21
21
  table.dropColumn('data');
22
22
  });
23
23
  await knex.schema.alterTable('directus_sessions', (table) => {
24
- table.uuid('user').nullable().alter();
24
+ table.setNullable('user');
25
25
  table.uuid('share').references('id').inTable('directus_shares').onDelete('CASCADE');
26
26
  });
27
27
  }
@@ -13,7 +13,7 @@ async function run(database, direction, log = true) {
13
13
  let migrationFiles = await fs_extra_1.default.readdir(__dirname);
14
14
  const customMigrationsPath = path_1.default.resolve(env_1.default.EXTENSIONS_PATH, 'migrations');
15
15
  let customMigrationFiles = ((await fs_extra_1.default.pathExists(customMigrationsPath)) && (await fs_extra_1.default.readdir(customMigrationsPath))) || [];
16
- migrationFiles = migrationFiles.filter((file) => file.startsWith('run') === false && file.endsWith('.d.ts') === false);
16
+ migrationFiles = migrationFiles.filter((file) => /^[0-9]+[A-Z]-[^.]+\.(?:js|ts)$/.test(file));
17
17
  customMigrationFiles = customMigrationFiles.filter((file) => file.endsWith('.js'));
18
18
  const completedMigrations = await database.select('*').from('directus_migrations').orderBy('version');
19
19
  const migrations = [
@@ -1,5 +1,5 @@
1
1
  import { Knex } from 'knex';
2
- import { Item, SchemaOverview } from '../types';
2
+ import { Item, SchemaOverview } from '@directus/shared/types';
3
3
  import { AST, NestedCollectionNode } from '../types/ast';
4
4
  declare type RunASTOptions = {
5
5
  /**
@@ -5,6 +5,7 @@ columns:
5
5
  type: string
6
6
  length: 64
7
7
  primary: true
8
+ nullable: false
8
9
  icon:
9
10
  type: string
10
11
  length: 30
@@ -4,6 +4,7 @@ columns:
4
4
  id:
5
5
  type: uuid
6
6
  primary: true
7
+ nullable: false
7
8
  name:
8
9
  type: string
9
10
  length: 100
@@ -4,6 +4,7 @@ columns:
4
4
  id:
5
5
  type: uuid
6
6
  primary: true
7
+ nullable: false
7
8
  first_name:
8
9
  type: string
9
10
  length: 50
@@ -62,14 +62,20 @@
62
62
  permissions:
63
63
  recipient:
64
64
  _eq: $CURRENT_USER
65
- fields: '*'
66
65
 
67
66
  - collection: directus_notifications
68
67
  action: update
69
68
  permissions:
70
69
  recipient:
71
70
  _eq: $CURRENT_USER
72
- fields: 'status'
71
+ fields:
72
+ - status
73
+
74
+ - collection: directus_shares
75
+ action: read
76
+ permissions:
77
+ user_created:
78
+ _eq: $CURRENT_USER
73
79
 
74
80
  - collection: directus_users
75
81
  action: read