directus 9.9.0 → 9.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +1 -1
  2. package/dist/app.js +3 -0
  3. package/dist/auth/drivers/oauth2.d.ts +1 -1
  4. package/dist/auth/drivers/oauth2.js +14 -11
  5. package/dist/auth/drivers/openid.d.ts +1 -1
  6. package/dist/auth/drivers/openid.js +14 -11
  7. package/dist/cli/commands/schema/apply.js +4 -3
  8. package/dist/controllers/assets.js +8 -9
  9. package/dist/controllers/files.js +3 -0
  10. package/dist/database/helpers/date/dialects/sqlite.js +6 -2
  11. package/dist/database/helpers/fn/dialects/postgres.js +5 -1
  12. package/dist/database/migrations/20210225A-add-relations-sort-field.js +2 -1
  13. package/dist/database/migrations/20210506A-rename-interfaces.js +2 -1
  14. package/dist/database/migrations/20210802A-replace-groups.js +2 -1
  15. package/dist/database/migrations/20210805A-update-groups.js +2 -1
  16. package/dist/database/migrations/20210805B-change-image-metadata-structure.js +3 -2
  17. package/dist/database/migrations/20211007A-update-presets.js +5 -4
  18. package/dist/database/run-ast.js +11 -15
  19. package/dist/database/system-data/fields/collections.yaml +1 -1
  20. package/dist/env.js +8 -3
  21. package/dist/exceptions/index.d.ts +1 -0
  22. package/dist/exceptions/index.js +1 -0
  23. package/dist/exceptions/invalid-provider.d.ts +4 -0
  24. package/dist/exceptions/invalid-provider.js +10 -0
  25. package/dist/exceptions/range-not-satisfiable.d.ts +2 -2
  26. package/dist/exceptions/range-not-satisfiable.js +5 -1
  27. package/dist/middleware/graphql.js +2 -1
  28. package/dist/services/assets.js +27 -1
  29. package/dist/services/authentication.js +4 -1
  30. package/dist/services/collections.js +2 -0
  31. package/dist/services/fields.js +17 -8
  32. package/dist/services/graphql.js +75 -34
  33. package/dist/services/import-export.d.ts +1 -1
  34. package/dist/services/import-export.js +14 -11
  35. package/dist/services/items.d.ts +3 -3
  36. package/dist/services/items.js +20 -6
  37. package/dist/services/payload.d.ts +3 -3
  38. package/dist/services/payload.js +11 -8
  39. package/dist/services/specifications.js +1 -3
  40. package/dist/services/users.d.ts +4 -0
  41. package/dist/services/users.js +24 -1
  42. package/dist/utils/{apply-query.d.ts → apply-query/index.d.ts} +2 -1
  43. package/dist/utils/apply-query/index.js +394 -0
  44. package/dist/utils/apply-query/operators/between.operator.d.ts +2 -0
  45. package/dist/utils/apply-query/operators/between.operator.js +16 -0
  46. package/dist/utils/apply-query/operators/contains.operator.d.ts +2 -0
  47. package/dist/utils/apply-query/operators/contains.operator.js +9 -0
  48. package/dist/utils/apply-query/operators/ends-with.operator.d.ts +2 -0
  49. package/dist/utils/apply-query/operators/ends-with.operator.js +9 -0
  50. package/dist/utils/apply-query/operators/equals.operator.d.ts +2 -0
  51. package/dist/utils/apply-query/operators/equals.operator.js +9 -0
  52. package/dist/utils/apply-query/operators/greather-than-equals.operator.d.ts +2 -0
  53. package/dist/utils/apply-query/operators/greather-than-equals.operator.js +9 -0
  54. package/dist/utils/apply-query/operators/greather-than.operator.d.ts +2 -0
  55. package/dist/utils/apply-query/operators/greather-than.operator.js +9 -0
  56. package/dist/utils/apply-query/operators/in.operator.d.ts +2 -0
  57. package/dist/utils/apply-query/operators/in.operator.js +14 -0
  58. package/dist/utils/apply-query/operators/index.d.ts +3 -0
  59. package/dist/utils/apply-query/operators/index.js +72 -0
  60. package/dist/utils/apply-query/operators/insensitive-contains.operator.d.ts +2 -0
  61. package/dist/utils/apply-query/operators/insensitive-contains.operator.js +9 -0
  62. package/dist/utils/apply-query/operators/insensitive-ends-with.operator.d.ts +2 -0
  63. package/dist/utils/apply-query/operators/insensitive-ends-with.operator.js +9 -0
  64. package/dist/utils/apply-query/operators/insensitive-equals.operator.d.ts +2 -0
  65. package/dist/utils/apply-query/operators/insensitive-equals.operator.js +9 -0
  66. package/dist/utils/apply-query/operators/insensitive-not-contains.operator.d.ts +2 -0
  67. package/dist/utils/apply-query/operators/insensitive-not-contains.operator.js +9 -0
  68. package/dist/utils/apply-query/operators/insensitive-not-ends-with.operator.d.ts +2 -0
  69. package/dist/utils/apply-query/operators/insensitive-not-ends-with.operator.js +9 -0
  70. package/dist/utils/apply-query/operators/insensitive-not-equals.operator.d.ts +2 -0
  71. package/dist/utils/apply-query/operators/insensitive-not-equals.operator.js +9 -0
  72. package/dist/utils/apply-query/operators/insensitive-not-starts-with.operator.d.ts +2 -0
  73. package/dist/utils/apply-query/operators/insensitive-not-starts-with.operator.js +9 -0
  74. package/dist/utils/apply-query/operators/insensitive-starts-with.operator.d.ts +2 -0
  75. package/dist/utils/apply-query/operators/insensitive-starts-with.operator.js +9 -0
  76. package/dist/utils/apply-query/operators/intersects-bbox.operator.d.ts +2 -0
  77. package/dist/utils/apply-query/operators/intersects-bbox.operator.js +9 -0
  78. package/dist/utils/apply-query/operators/intersects.operator.d.ts +2 -0
  79. package/dist/utils/apply-query/operators/intersects.operator.js +9 -0
  80. package/dist/utils/apply-query/operators/is-empty.operator.d.ts +2 -0
  81. package/dist/utils/apply-query/operators/is-empty.operator.js +14 -0
  82. package/dist/utils/apply-query/operators/is-not-empty.operator.d.ts +2 -0
  83. package/dist/utils/apply-query/operators/is-not-empty.operator.js +14 -0
  84. package/dist/utils/apply-query/operators/is-not-null.operator.d.ts +2 -0
  85. package/dist/utils/apply-query/operators/is-not-null.operator.js +14 -0
  86. package/dist/utils/apply-query/operators/is-null.operator.d.ts +2 -0
  87. package/dist/utils/apply-query/operators/is-null.operator.js +14 -0
  88. package/dist/utils/apply-query/operators/less-than-equals.operator.d.ts +2 -0
  89. package/dist/utils/apply-query/operators/less-than-equals.operator.js +9 -0
  90. package/dist/utils/apply-query/operators/less-than.operator.d.ts +2 -0
  91. package/dist/utils/apply-query/operators/less-than.operator.js +9 -0
  92. package/dist/utils/apply-query/operators/not-between.operator.d.ts +2 -0
  93. package/dist/utils/apply-query/operators/not-between.operator.js +16 -0
  94. package/dist/utils/apply-query/operators/not-contains.operator.d.ts +2 -0
  95. package/dist/utils/apply-query/operators/not-contains.operator.js +9 -0
  96. package/dist/utils/apply-query/operators/not-ends-with.operator.d.ts +2 -0
  97. package/dist/utils/apply-query/operators/not-ends-with.operator.js +9 -0
  98. package/dist/utils/apply-query/operators/not-equals.operator.d.ts +2 -0
  99. package/dist/utils/apply-query/operators/not-equals.operator.js +9 -0
  100. package/dist/utils/apply-query/operators/not-in.operator.d.ts +2 -0
  101. package/dist/utils/apply-query/operators/not-in.operator.js +14 -0
  102. package/dist/utils/apply-query/operators/not-intersects-bbox.operator.d.ts +2 -0
  103. package/dist/utils/apply-query/operators/not-intersects-bbox.operator.js +9 -0
  104. package/dist/utils/apply-query/operators/not-intersects.operator.d.ts +2 -0
  105. package/dist/utils/apply-query/operators/not-intersects.operator.js +9 -0
  106. package/dist/utils/apply-query/operators/not-starts-with.operator.d.ts +2 -0
  107. package/dist/utils/apply-query/operators/not-starts-with.operator.js +9 -0
  108. package/dist/utils/apply-query/operators/operator-register.d.ts +13 -0
  109. package/dist/utils/apply-query/operators/operator-register.js +7 -0
  110. package/dist/utils/apply-query/operators/starts-with.operator.d.ts +2 -0
  111. package/dist/utils/apply-query/operators/starts-with.operator.js +9 -0
  112. package/dist/utils/apply-snapshot.d.ts +3 -3
  113. package/dist/utils/apply-snapshot.js +64 -49
  114. package/dist/utils/get-ast-from-query.js +10 -4
  115. package/dist/utils/get-column-path.d.ts +16 -0
  116. package/dist/utils/get-column-path.js +46 -0
  117. package/dist/utils/get-default-value.js +4 -3
  118. package/dist/utils/get-permissions.d.ts +1 -1
  119. package/dist/utils/get-permissions.js +9 -8
  120. package/dist/utils/get-relation-info.d.ts +7 -0
  121. package/dist/utils/get-relation-info.js +45 -0
  122. package/dist/utils/get-relation-type.d.ts +1 -1
  123. package/dist/utils/get-schema.js +5 -1
  124. package/dist/utils/get-snapshot.js +22 -4
  125. package/dist/utils/merge-permissions-for-share.js +1 -1
  126. package/dist/utils/parse-json.d.ts +5 -0
  127. package/dist/utils/parse-json.js +19 -0
  128. package/dist/utils/reduce-schema.js +18 -11
  129. package/dist/utils/sanitize-query.d.ts +1 -2
  130. package/dist/utils/sanitize-query.js +6 -5
  131. package/package.json +16 -18
  132. package/dist/utils/apply-query.js +0 -498
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nicontains',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(`LOWER(??) NOT LIKE ?`, [selectionRaw, `%${compareValue === null || compareValue === void 0 ? void 0 : compareValue.toLowerCase()}%`]);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_niends_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(`LOWER(??) NOT LIKE ?`, [selectionRaw, `%${compareValue === null || compareValue === void 0 ? void 0 : compareValue.toLowerCase()}`]);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nieq',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(`LOWER(??) != ?`, [selectionRaw, `${compareValue === null || compareValue === void 0 ? void 0 : compareValue.toLowerCase()}`]);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nistarts_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(`LOWER(??) NOT LIKE ?`, [selectionRaw, `${compareValue === null || compareValue === void 0 ? void 0 : compareValue.toLowerCase()}%`]);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_istarts_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(`LOWER(??) LIKE ?`, [selectionRaw, `${compareValue === null || compareValue === void 0 ? void 0 : compareValue.toLowerCase()}%`]);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_intersects_bbox',
6
+ apply: ({ helpers, query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(helpers.st.intersects_bbox(selectionRaw, compareValue));
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_intersects',
6
+ apply: ({ helpers, query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(helpers.st.intersects(selectionRaw, compareValue));
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_empty',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ if (compareValue) {
8
+ query.where(selectionRaw, '=', '');
9
+ }
10
+ else {
11
+ query.where(selectionRaw, '!=', '');
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nempty',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ if (compareValue) {
8
+ query.where(selectionRaw, '!=', '');
9
+ }
10
+ else {
11
+ query.where(selectionRaw, '=', '');
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nnull',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ if (compareValue) {
8
+ query.whereNotNull(selectionRaw);
9
+ }
10
+ else {
11
+ query.whereNull(selectionRaw);
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_null',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ if (compareValue) {
8
+ query.whereNull(selectionRaw);
9
+ }
10
+ else {
11
+ query.whereNotNull(selectionRaw);
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_lte',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.where(selectionRaw, '<=', compareValue);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_lt',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.where(selectionRaw, '<', compareValue);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nbetween',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ let value = compareValue;
8
+ if (typeof value === 'string')
9
+ value = value.split(',');
10
+ if (!(value instanceof Array))
11
+ throw new Error('Invalid value for between operator');
12
+ if (value.length !== 2)
13
+ throw new Error('Expected two values for between operator');
14
+ query.whereNotBetween(selectionRaw, value);
15
+ },
16
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_ncontains',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereNot(selectionRaw, 'like', `%${compareValue}%`);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nends_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereNot(selectionRaw, 'like', `%${compareValue}`);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_neq',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereNot(selectionRaw, compareValue);
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nin',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ let value = compareValue;
8
+ if (typeof value === 'string')
9
+ value = value.split(',');
10
+ if (!(value instanceof Array))
11
+ throw new Error('Invalid value for in operator');
12
+ query.whereNotIn(selectionRaw, value);
13
+ },
14
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nintersects_bbox',
6
+ apply: ({ helpers, query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(helpers.st.nintersects_bbox(selectionRaw, compareValue));
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nintersects',
6
+ apply: ({ helpers, query, selectionRaw, compareValue }) => {
7
+ query.whereRaw(helpers.st.nintersects(selectionRaw, compareValue));
8
+ },
9
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_nstarts_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.whereNot(selectionRaw, 'like', `${compareValue}%`);
8
+ },
9
+ });
@@ -0,0 +1,13 @@
1
+ import { Knex } from 'knex';
2
+ import { Helpers } from '../../../database/helpers';
3
+ export declare type OperatorRegisterContext = {
4
+ query: Knex.QueryBuilder<any, any>;
5
+ selectionRaw: any;
6
+ compareValue: any;
7
+ helpers: Helpers;
8
+ };
9
+ export declare type OperatorRegister = {
10
+ operator: string;
11
+ apply: (context: OperatorRegisterContext) => void;
12
+ };
13
+ export declare function registerOperator(register: OperatorRegister): OperatorRegister;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerOperator = void 0;
4
+ function registerOperator(register) {
5
+ return register;
6
+ }
7
+ exports.registerOperator = registerOperator;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("./operator-register").OperatorRegister;
2
+ export default _default;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const operator_register_1 = require("./operator-register");
4
+ exports.default = (0, operator_register_1.registerOperator)({
5
+ operator: '_starts_with',
6
+ apply: ({ query, selectionRaw, compareValue }) => {
7
+ query.where(selectionRaw, 'like', `${compareValue}%`);
8
+ },
9
+ });
@@ -1,7 +1,7 @@
1
- import { Snapshot, SnapshotDiff, SnapshotField } from '../types';
2
- import { Knex } from 'knex';
3
- import { Diff } from 'deep-diff';
4
1
  import { SchemaOverview } from '@directus/shared/types';
2
+ import { Diff } from 'deep-diff';
3
+ import { Knex } from 'knex';
4
+ import { Snapshot, SnapshotDiff, SnapshotField } from '../types';
5
5
  export declare function applySnapshot(snapshot: Snapshot, options?: {
6
6
  database?: Knex;
7
7
  schema?: SchemaOverview;
@@ -4,13 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isNestedMetaUpdate = exports.applySnapshot = void 0;
7
- const get_snapshot_1 = require("./get-snapshot");
8
- const get_snapshot_diff_1 = require("./get-snapshot-diff");
9
- const database_1 = __importDefault(require("../database"));
10
- const get_schema_1 = require("./get-schema");
11
- const services_1 = require("../services");
12
7
  const lodash_1 = require("lodash");
8
+ const database_1 = __importDefault(require("../database"));
13
9
  const logger_1 = __importDefault(require("../logger"));
10
+ const services_1 = require("../services");
11
+ const get_schema_1 = require("./get-schema");
12
+ const get_snapshot_1 = require("./get-snapshot");
13
+ const get_snapshot_diff_1 = require("./get-snapshot-diff");
14
14
  async function applySnapshot(snapshot, options) {
15
15
  var _a, _b, _c, _d;
16
16
  const database = (_a = options === null || options === void 0 ? void 0 : options.database) !== null && _a !== void 0 ? _a : (0, database_1.default)();
@@ -19,55 +19,70 @@ async function applySnapshot(snapshot, options) {
19
19
  const snapshotDiff = (_d = options === null || options === void 0 ? void 0 : options.diff) !== null && _d !== void 0 ? _d : (0, get_snapshot_diff_1.getSnapshotDiff)(current, snapshot);
20
20
  await database.transaction(async (trx) => {
21
21
  const collectionsService = new services_1.CollectionsService({ knex: trx, schema });
22
- for (const { collection, diff } of snapshotDiff.collections) {
23
- if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
24
- try {
25
- await collectionsService.deleteOne(collection);
26
- }
27
- catch (err) {
28
- logger_1.default.error(`Failed to delete collection "${collection}"`);
29
- throw err;
22
+ const getNestedCollectionsToCreate = (currentLevelCollection) => snapshotDiff.collections.filter(({ diff }) => { var _a, _b; return ((_b = (_a = diff[0].rhs) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.group) === currentLevelCollection; });
23
+ const getNestedCollectionsToDelete = (currentLevelCollection) => snapshotDiff.collections.filter(({ diff }) => { var _a, _b; return ((_b = (_a = diff[0].lhs) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.group) === currentLevelCollection; });
24
+ const createCollections = async (collections) => {
25
+ for (const { collection, diff } of collections) {
26
+ if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N' && diff[0].rhs) {
27
+ // We'll nest the to-be-created fields in the same collection creation, to prevent
28
+ // creating a collection without a primary key
29
+ const fields = snapshotDiff.fields
30
+ .filter((fieldDiff) => fieldDiff.collection === collection)
31
+ .map((fieldDiff) => fieldDiff.diff[0].rhs)
32
+ .map((fieldDiff) => {
33
+ // Casts field type to UUID when applying SQLite-based schema on other databases.
34
+ // This is needed because SQLite snapshots UUID fields as char with length 36, and
35
+ // it will fail when trying to create relation between char field to UUID field
36
+ if (!fieldDiff.schema ||
37
+ fieldDiff.schema.data_type !== 'char' ||
38
+ fieldDiff.schema.max_length !== 36 ||
39
+ !fieldDiff.schema.foreign_key_table ||
40
+ !fieldDiff.schema.foreign_key_column) {
41
+ return fieldDiff;
42
+ }
43
+ const matchingForeignKeyTable = schema.collections[fieldDiff.schema.foreign_key_table];
44
+ if (!matchingForeignKeyTable)
45
+ return fieldDiff;
46
+ const matchingForeignKeyField = matchingForeignKeyTable.fields[fieldDiff.schema.foreign_key_column];
47
+ if (!matchingForeignKeyField || matchingForeignKeyField.type !== 'uuid')
48
+ return fieldDiff;
49
+ return (0, lodash_1.merge)(fieldDiff, { type: 'uuid', schema: { data_type: 'uuid', max_length: null } });
50
+ });
51
+ try {
52
+ await collectionsService.createOne({
53
+ ...diff[0].rhs,
54
+ fields,
55
+ });
56
+ }
57
+ catch (err) {
58
+ logger_1.default.error(`Failed to create collection "${collection}"`);
59
+ throw err;
60
+ }
61
+ // Now that the fields are in for this collection, we can strip them from the field edits
62
+ snapshotDiff.fields = snapshotDiff.fields.filter((fieldDiff) => fieldDiff.collection !== collection);
63
+ await createCollections(getNestedCollectionsToCreate(collection));
30
64
  }
31
65
  }
32
- if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N' && diff[0].rhs) {
33
- // We'll nest the to-be-created fields in the same collection creation, to prevent
34
- // creating a collection without a primary key
35
- const fields = snapshotDiff.fields
36
- .filter((fieldDiff) => fieldDiff.collection === collection)
37
- .map((fieldDiff) => fieldDiff.diff[0].rhs)
38
- .map((fieldDiff) => {
39
- // Casts field type to UUID when applying SQLite-based schema on other databases.
40
- // This is needed because SQLite snapshots UUID fields as char with length 36, and
41
- // it will fail when trying to create relation between char field to UUID field
42
- if (!fieldDiff.schema ||
43
- fieldDiff.schema.data_type !== 'char' ||
44
- fieldDiff.schema.max_length !== 36 ||
45
- !fieldDiff.schema.foreign_key_table ||
46
- !fieldDiff.schema.foreign_key_column) {
47
- return fieldDiff;
66
+ };
67
+ const deleteCollections = async (collections) => {
68
+ for (const { collection, diff } of collections) {
69
+ if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
70
+ await deleteCollections(getNestedCollectionsToDelete(collection));
71
+ try {
72
+ await collectionsService.deleteOne(collection);
73
+ }
74
+ catch (err) {
75
+ logger_1.default.error(`Failed to delete collection "${collection}"`);
76
+ throw err;
48
77
  }
49
- const matchingForeignKeyTable = schema.collections[fieldDiff.schema.foreign_key_table];
50
- if (!matchingForeignKeyTable)
51
- return fieldDiff;
52
- const matchingForeignKeyField = matchingForeignKeyTable.fields[fieldDiff.schema.foreign_key_column];
53
- if (!matchingForeignKeyField || matchingForeignKeyField.type !== 'uuid')
54
- return fieldDiff;
55
- return (0, lodash_1.merge)(fieldDiff, { type: 'uuid', schema: { data_type: 'uuid', max_length: null } });
56
- });
57
- try {
58
- await collectionsService.createOne({
59
- ...diff[0].rhs,
60
- fields,
61
- });
62
- }
63
- catch (err) {
64
- logger_1.default.error(`Failed to create collection "${collection}"`);
65
- throw err;
66
78
  }
67
- // Now that the fields are in for this collection, we can strip them from the field
68
- // edits
69
- snapshotDiff.fields = snapshotDiff.fields.filter((fieldDiff) => fieldDiff.collection !== collection);
70
79
  }
80
+ };
81
+ // create top level collections (no group) first, then continue with nested collections recursively
82
+ await createCollections(snapshotDiff.collections.filter(({ diff }) => { var _a; return diff[0].kind === 'N' && ((_a = diff[0].rhs.meta) === null || _a === void 0 ? void 0 : _a.group) === null; }));
83
+ // delete top level collections (no group) first, then continue with nested collections recursively
84
+ await deleteCollections(snapshotDiff.collections.filter(({ diff }) => { var _a; return diff[0].kind === 'D' && ((_a = diff[0].lhs.meta) === null || _a === void 0 ? void 0 : _a.group) === null; }));
85
+ for (const { collection, diff } of snapshotDiff.collections) {
71
86
  if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
72
87
  const newValues = snapshot.collections.find((field) => {
73
88
  return field.collection === collection;
@@ -75,9 +75,11 @@ async function getASTFromQuery(collection, query, schema, options) {
75
75
  const relationalStructure = {};
76
76
  for (const fieldKey of fields) {
77
77
  let name = fieldKey;
78
- const isAlias = (_a = (query.alias && name in query.alias)) !== null && _a !== void 0 ? _a : false;
79
- if (isAlias) {
80
- name = query.alias[fieldKey];
78
+ if (query.alias) {
79
+ // check for field alias (is is one of the key)
80
+ if (name in query.alias) {
81
+ name = query.alias[fieldKey];
82
+ }
81
83
  }
82
84
  const isRelational = name.includes('.') ||
83
85
  // We'll always treat top level o2m fields as a related item. This is an alias field, otherwise it won't return
@@ -85,7 +87,7 @@ async function getASTFromQuery(collection, query, schema, options) {
85
87
  !!schema.relations.find((relation) => { var _a; return relation.related_collection === parentCollection && ((_a = relation.meta) === null || _a === void 0 ? void 0 : _a.one_field) === name; });
86
88
  if (isRelational) {
87
89
  // field is relational
88
- const parts = name.split('.');
90
+ const parts = fieldKey.split('.');
89
91
  let rootField = parts[0];
90
92
  let collectionScope = null;
91
93
  // a2o related collection scoped field selector `fields=sections.section_id:headings.title`
@@ -162,6 +164,10 @@ async function getASTFromQuery(collection, query, schema, options) {
162
164
  if (permissions && permissions.some((permission) => permission.collection === relatedCollection) === false) {
163
165
  continue;
164
166
  }
167
+ // update query alias for children parseFields
168
+ const deepAlias = (_a = getDeepQuery((deep === null || deep === void 0 ? void 0 : deep[fieldKey]) || {})) === null || _a === void 0 ? void 0 : _a.alias;
169
+ if (!(0, lodash_1.isEmpty)(deepAlias))
170
+ query.alias = deepAlias;
165
171
  child = {
166
172
  type: relationType,
167
173
  name: relatedCollection,
@@ -0,0 +1,16 @@
1
+ import { Relation } from '@directus/shared/types';
2
+ declare type AliasMap = string | {
3
+ [key: string]: AliasMap;
4
+ };
5
+ export declare type ColPathProps = {
6
+ path: string[];
7
+ collection: string;
8
+ aliasMap: AliasMap;
9
+ relations: Relation[];
10
+ };
11
+ /**
12
+ * Converts a Directus field list path to the correct SQL names based on the constructed alias map.
13
+ * For example: ['author', 'role', 'name'] -> 'ljnsv.name'
14
+ */
15
+ export declare function getColumnPath({ path, collection, aliasMap, relations }: ColPathProps): string | void;
16
+ export {};