directus 9.23.1 → 9.23.3
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.
- package/dist/app.js +14 -10
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +2 -0
- package/dist/auth/drivers/ldap.d.ts +1 -1
- package/dist/auth/drivers/ldap.js +39 -28
- package/dist/auth/drivers/local.d.ts +1 -1
- package/dist/auth/drivers/local.js +13 -10
- package/dist/auth/drivers/oauth2.d.ts +1 -1
- package/dist/auth/drivers/oauth2.js +20 -13
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +21 -14
- package/dist/auth/drivers/saml.d.ts +1 -1
- package/dist/auth/drivers/saml.js +10 -7
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +4 -4
- package/dist/cache.d.ts +9 -1
- package/dist/cache.js +57 -14
- package/dist/cli/commands/bootstrap/index.js +2 -2
- package/dist/cli/commands/init/index.js +3 -3
- package/dist/cli/commands/schema/apply.js +14 -15
- package/dist/cli/commands/schema/snapshot.js +2 -2
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +2 -1
- package/dist/cli/utils/create-env/index.d.ts +2 -2
- package/dist/cli/utils/drivers.d.ts +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +2 -3
- package/dist/controllers/activity.js +1 -2
- package/dist/controllers/assets.js +14 -9
- package/dist/controllers/auth.js +29 -15
- package/dist/controllers/dashboards.js +5 -2
- package/dist/controllers/fields.js +4 -4
- package/dist/controllers/files.js +10 -5
- package/dist/controllers/flows.js +5 -2
- package/dist/controllers/folders.js +5 -2
- package/dist/controllers/graphql.js +2 -4
- package/dist/controllers/items.js +5 -2
- package/dist/controllers/not-found.d.ts +1 -1
- package/dist/controllers/not-found.js +1 -2
- package/dist/controllers/notifications.js +5 -2
- package/dist/controllers/operations.js +5 -2
- package/dist/controllers/panels.js +5 -2
- package/dist/controllers/permissions.js +5 -2
- package/dist/controllers/presets.js +5 -2
- package/dist/controllers/roles.js +5 -2
- package/dist/controllers/shares.js +8 -5
- package/dist/controllers/users.js +16 -20
- package/dist/controllers/utils.js +6 -11
- package/dist/controllers/webhooks.js +5 -2
- package/dist/database/helpers/fn/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mssql.js +10 -11
- package/dist/database/helpers/fn/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mysql.js +2 -3
- package/dist/database/helpers/fn/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/oracle.js +10 -11
- package/dist/database/helpers/fn/dialects/postgres.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/postgres.js +10 -11
- package/dist/database/helpers/fn/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/sqlite.js +10 -11
- package/dist/database/helpers/fn/types.d.ts +5 -5
- package/dist/database/helpers/fn/types.js +5 -4
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.js +1 -2
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +2 -2
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/geometry/types.d.ts +2 -2
- package/dist/database/helpers/geometry/types.js +1 -2
- package/dist/database/helpers/index.d.ts +5 -5
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.js +1 -2
- package/dist/database/helpers/schema/dialects/oracle.d.ts +2 -2
- package/dist/database/helpers/schema/dialects/oracle.js +4 -6
- package/dist/database/helpers/schema/types.d.ts +4 -4
- package/dist/database/helpers/types.d.ts +1 -1
- package/dist/database/helpers/types.js +1 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +8 -8
- package/dist/database/migrations/20201028A-remove-collection-foreign-keys.d.ts +1 -1
- package/dist/database/migrations/20201029A-remove-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201029B-remove-system-collections.d.ts +1 -1
- package/dist/database/migrations/20201029C-remove-system-fields.d.ts +1 -1
- package/dist/database/migrations/20201105A-add-cascade-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201105B-change-webhook-url-type.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.js +1 -2
- package/dist/database/migrations/20210304A-remove-locked-fields.d.ts +1 -1
- package/dist/database/migrations/20210312A-webhooks-collections-text.d.ts +1 -1
- package/dist/database/migrations/20210331A-add-refresh-interval.d.ts +1 -1
- package/dist/database/migrations/20210415A-make-filesize-nullable.d.ts +1 -1
- package/dist/database/migrations/20210416A-add-collections-accountability.d.ts +1 -1
- package/dist/database/migrations/20210422A-remove-files-interface.d.ts +1 -1
- package/dist/database/migrations/20210506A-rename-interfaces.d.ts +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.d.ts +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.js +2 -2
- package/dist/database/migrations/20210521A-add-collections-icon-color.d.ts +1 -1
- package/dist/database/migrations/20210525A-add-insights.d.ts +1 -1
- package/dist/database/migrations/20210608A-add-deep-clone-config.d.ts +1 -1
- package/dist/database/migrations/20210626A-change-filesize-bigint.d.ts +1 -1
- package/dist/database/migrations/20210716A-add-conditions-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210721A-add-default-folder.d.ts +1 -1
- package/dist/database/migrations/20210802A-replace-groups.d.ts +1 -1
- package/dist/database/migrations/20210803A-add-required-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210805A-update-groups.d.ts +1 -1
- package/dist/database/migrations/20210805B-change-image-metadata-structure.d.ts +1 -1
- package/dist/database/migrations/20210811A-add-geometry-config.d.ts +1 -1
- package/dist/database/migrations/20210831A-remove-limit-column.d.ts +1 -1
- package/dist/database/migrations/20210903A-add-auth-provider.d.ts +1 -1
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.d.ts +1 -1
- package/dist/database/migrations/20210910A-move-module-setup.d.ts +1 -1
- package/dist/database/migrations/20210920A-webhooks-url-not-null.d.ts +1 -1
- package/dist/database/migrations/20210924A-add-collection-organization.d.ts +1 -1
- package/dist/database/migrations/20210927A-replace-fields-group.d.ts +1 -1
- package/dist/database/migrations/20210927B-replace-m2m-interface.d.ts +1 -1
- package/dist/database/migrations/20210929A-rename-login-action.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.js +7 -9
- package/dist/database/migrations/20211009A-add-auth-data.d.ts +1 -1
- package/dist/database/migrations/20211016A-add-webhook-headers.d.ts +1 -1
- package/dist/database/migrations/20211103A-set-unique-to-user-token.d.ts +1 -1
- package/dist/database/migrations/20211103B-update-special-geometry.d.ts +1 -1
- package/dist/database/migrations/20211104A-remove-collections-listing.d.ts +1 -1
- package/dist/database/migrations/20211118A-add-notifications.d.ts +1 -1
- package/dist/database/migrations/20211211A-add-shares.d.ts +1 -1
- package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +1 -1
- package/dist/database/migrations/20220303A-remove-default-project-color.d.ts +1 -1
- package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +1 -1
- package/dist/database/migrations/20220314A-add-translation-strings.d.ts +1 -1
- package/dist/database/migrations/20220322A-rename-field-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220323A-add-field-validation.d.ts +1 -1
- package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220325B-add-default-language.d.ts +1 -1
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +1 -1
- package/dist/database/migrations/20220429A-add-flows.d.ts +1 -1
- package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +1 -1
- package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +1 -1
- package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +1 -1
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +1 -1
- package/dist/database/migrations/20220801A-update-notifications-timestamp-column.d.ts +1 -1
- package/dist/database/migrations/20220802A-add-custom-aspect-ratios.d.ts +1 -1
- package/dist/database/migrations/20220826A-add-origin-to-accountability.d.ts +1 -1
- package/dist/database/migrations/run.d.ts +1 -1
- package/dist/database/run-ast.d.ts +3 -3
- package/dist/database/run-ast.js +17 -26
- package/dist/database/seeds/run.d.ts +1 -1
- package/dist/database/seeds/run.js +1 -2
- package/dist/database/system-data/app-access-permissions/index.d.ts +1 -1
- package/dist/database/system-data/collections/index.d.ts +1 -1
- package/dist/database/system-data/fields/collections.yaml +2 -0
- package/dist/database/system-data/fields/index.d.ts +1 -1
- package/dist/database/system-data/fields/index.js +1 -2
- package/dist/database/system-data/fields/settings.yaml +4 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +1 -1
- package/dist/emitter.js +3 -0
- package/dist/env.js +10 -2
- package/dist/exceptions/database/dialects/mssql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mssql.js +5 -6
- package/dist/exceptions/database/dialects/mysql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mysql.js +19 -25
- package/dist/exceptions/database/dialects/oracle.d.ts +1 -1
- package/dist/exceptions/database/dialects/postgres.d.ts +1 -1
- package/dist/exceptions/database/dialects/sqlite.d.ts +1 -1
- package/dist/exceptions/database/translate.d.ts +1 -1
- package/dist/exceptions/database/value-out-of-range.js +1 -1
- package/dist/exceptions/range-not-satisfiable.js +2 -3
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +33 -23
- package/dist/flows.js +42 -25
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +19 -3
- package/dist/messenger.js +8 -6
- package/dist/middleware/authenticate.d.ts +1 -1
- package/dist/middleware/authenticate.js +12 -5
- package/dist/middleware/cache.d.ts +1 -1
- package/dist/middleware/cache.js +5 -5
- package/dist/middleware/check-ip.d.ts +1 -1
- package/dist/middleware/check-ip.js +1 -1
- package/dist/middleware/collection-exists.d.ts +1 -1
- package/dist/middleware/collection-exists.js +2 -2
- package/dist/middleware/cors.d.ts +1 -1
- package/dist/middleware/error-handler.d.ts +1 -1
- package/dist/middleware/error-handler.js +9 -10
- package/dist/middleware/extract-token.d.ts +1 -1
- package/dist/middleware/get-permissions.d.ts +1 -1
- package/dist/middleware/graphql.d.ts +1 -1
- package/dist/middleware/graphql.js +3 -3
- package/dist/middleware/rate-limiter-global.d.ts +5 -0
- package/dist/middleware/rate-limiter-global.js +48 -0
- package/dist/middleware/{rate-limiter.d.ts → rate-limiter-ip.d.ts} +2 -2
- package/dist/middleware/{rate-limiter.js → rate-limiter-ip.js} +3 -3
- package/dist/middleware/respond.d.ts +1 -1
- package/dist/middleware/respond.js +6 -7
- package/dist/middleware/sanitize-query.d.ts +1 -1
- package/dist/middleware/schema.d.ts +1 -1
- package/dist/middleware/use-collection.d.ts +1 -1
- package/dist/operations/condition/index.d.ts +1 -1
- package/dist/operations/exec/index.js +14 -3
- package/dist/operations/item-create/index.js +1 -2
- package/dist/operations/item-delete/index.d.ts +1 -1
- package/dist/operations/item-read/index.d.ts +1 -1
- package/dist/operations/item-update/index.d.ts +1 -1
- package/dist/operations/item-update/index.js +1 -2
- package/dist/operations/notification/index.js +1 -2
- package/dist/operations/request/index.js +19 -19
- package/dist/operations/trigger/index.js +2 -3
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +8 -8
- package/dist/server.js +8 -9
- package/dist/services/activity.d.ts +1 -1
- package/dist/services/activity.js +7 -6
- package/dist/services/assets.d.ts +3 -3
- package/dist/services/assets.js +33 -35
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +13 -10
- package/dist/services/authorization.d.ts +3 -3
- package/dist/services/authorization.js +27 -31
- package/dist/services/collections.d.ts +5 -5
- package/dist/services/collections.js +52 -48
- package/dist/services/dashboards.d.ts +1 -1
- package/dist/services/fields.d.ts +5 -5
- package/dist/services/fields.js +48 -48
- package/dist/services/files.d.ts +1 -2
- package/dist/services/files.js +27 -21
- package/dist/services/flows.d.ts +2 -2
- package/dist/services/folders.d.ts +1 -1
- package/dist/services/graphql/index.d.ts +4 -4
- package/dist/services/graphql/index.js +172 -167
- package/dist/services/graphql/utils/add-path-to-validation-error.js +1 -2
- package/dist/services/graphql/utils/process-error.d.ts +2 -2
- package/dist/services/graphql/utils/process-error.js +11 -4
- package/dist/services/import-export.d.ts +3 -3
- package/dist/services/import-export.js +25 -22
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +42 -36
- package/dist/services/mail/index.d.ts +4 -4
- package/dist/services/mail/index.js +9 -5
- package/dist/services/meta.d.ts +3 -3
- package/dist/services/meta.js +10 -9
- package/dist/services/notifications.d.ts +3 -3
- package/dist/services/notifications.js +7 -6
- package/dist/services/operations.d.ts +2 -2
- package/dist/services/panels.d.ts +1 -1
- package/dist/services/payload.d.ts +3 -3
- package/dist/services/payload.js +124 -122
- package/dist/services/permissions.d.ts +3 -3
- package/dist/services/permissions.js +11 -11
- package/dist/services/presets.d.ts +1 -1
- package/dist/services/relations.d.ts +6 -6
- package/dist/services/relations.js +45 -43
- package/dist/services/revisions.d.ts +1 -1
- package/dist/services/roles.d.ts +2 -2
- package/dist/services/roles.js +2 -2
- package/dist/services/schema.d.ts +3 -3
- package/dist/services/schema.js +9 -11
- package/dist/services/server.d.ts +3 -3
- package/dist/services/server.js +69 -13
- package/dist/services/settings.d.ts +1 -1
- package/dist/services/shares.d.ts +1 -1
- package/dist/services/shares.js +5 -6
- package/dist/services/specifications.d.ts +4 -4
- package/dist/services/specifications.js +132 -116
- package/dist/services/tfa.d.ts +2 -2
- package/dist/services/tfa.js +7 -5
- package/dist/services/users.d.ts +3 -3
- package/dist/services/users.js +17 -17
- package/dist/services/utils.d.ts +3 -3
- package/dist/services/utils.js +10 -8
- package/dist/services/webhooks.d.ts +2 -2
- package/dist/services/webhooks.js +2 -1
- package/dist/types/assets.d.ts +1 -1
- package/dist/types/ast.d.ts +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/collection.d.ts +2 -2
- package/dist/types/events.d.ts +2 -2
- package/dist/types/graphql.d.ts +2 -2
- package/dist/types/items.d.ts +3 -3
- package/dist/types/services.d.ts +5 -5
- package/dist/types/snapshot.d.ts +4 -4
- package/dist/utils/apply-diff.d.ts +3 -3
- package/dist/utils/apply-diff.js +25 -28
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +8 -11
- package/dist/utils/apply-snapshot.d.ts +3 -3
- package/dist/utils/apply-snapshot.js +5 -6
- package/dist/utils/construct-flow-tree.d.ts +1 -1
- package/dist/utils/construct-flow-tree.js +2 -2
- package/dist/utils/filter-items.d.ts +1 -1
- package/dist/utils/get-accountability-for-role.d.ts +2 -2
- package/dist/utils/get-accountability-for-role.js +1 -1
- package/dist/utils/get-ast-from-query.d.ts +3 -3
- package/dist/utils/get-ast-from-query.js +22 -28
- package/dist/utils/get-cache-headers.d.ts +1 -1
- package/dist/utils/get-cache-headers.js +3 -4
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +2 -3
- package/dist/utils/get-collection-from-alias.d.ts +1 -1
- package/dist/utils/get-column-path.d.ts +2 -2
- package/dist/utils/get-column-path.js +3 -4
- package/dist/utils/get-column.d.ts +4 -4
- package/dist/utils/get-column.js +4 -5
- package/dist/utils/get-default-value.d.ts +2 -2
- package/dist/utils/get-default-value.js +1 -2
- package/dist/utils/get-graphql-query-and-variables.d.ts +1 -1
- package/dist/utils/get-graphql-query-and-variables.js +1 -2
- package/dist/utils/get-graphql-type.d.ts +2 -2
- package/dist/utils/get-graphql-type.js +1 -1
- package/dist/utils/get-ip-from-req.d.ts +1 -1
- package/dist/utils/get-local-type.d.ts +1 -1
- package/dist/utils/get-local-type.js +3 -3
- package/dist/utils/get-milliseconds.js +1 -2
- package/dist/utils/get-permissions.d.ts +1 -1
- package/dist/utils/get-permissions.js +1 -1
- package/dist/utils/get-relation-info.d.ts +1 -1
- package/dist/utils/get-relation-info.js +3 -5
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-relation-type.js +3 -4
- package/dist/utils/get-schema.d.ts +2 -2
- package/dist/utils/get-schema.js +19 -21
- package/dist/utils/get-snapshot-diff.js +2 -3
- package/dist/utils/get-snapshot.d.ts +3 -3
- package/dist/utils/get-snapshot.js +6 -8
- package/dist/utils/is-directus-jwt.js +1 -1
- package/dist/utils/job-queue.js +2 -0
- package/dist/utils/jwt.d.ts +1 -1
- package/dist/utils/merge-permissions-for-share.d.ts +1 -1
- package/dist/utils/merge-permissions-for-share.js +3 -4
- package/dist/utils/merge-permissions.d.ts +3 -3
- package/dist/utils/redact-header-cookies.d.ts +1 -0
- package/dist/utils/redact-header-cookies.js +11 -0
- package/dist/utils/redact-header-cookies.test.d.ts +1 -0
- package/dist/utils/reduce-schema.d.ts +1 -1
- package/dist/utils/reduce-schema.js +12 -12
- package/dist/utils/sanitize-query.d.ts +1 -1
- package/dist/utils/sanitize-query.js +1 -1
- package/dist/utils/sanitize-schema.d.ts +2 -2
- package/dist/utils/should-skip-cache.d.ts +7 -0
- package/dist/utils/should-skip-cache.js +21 -0
- package/dist/utils/should-skip-cache.test.d.ts +1 -0
- package/dist/utils/transformations.d.ts +1 -1
- package/dist/utils/transformations.js +2 -4
- package/dist/utils/url.js +7 -2
- package/dist/utils/user-name.d.ts +1 -1
- package/dist/utils/validate-diff.js +7 -8
- package/dist/utils/validate-keys.d.ts +2 -2
- package/dist/utils/validate-keys.js +1 -1
- package/dist/utils/validate-query.d.ts +1 -1
- package/dist/utils/validate-query.js +2 -2
- package/dist/webhooks.js +1 -1
- package/package.json +36 -37
- package/dist/utils/with-timeout.d.ts +0 -1
- package/dist/utils/with-timeout.js +0 -16
|
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.addPathToValidationError = void 0;
|
|
4
4
|
const graphql_1 = require("graphql");
|
|
5
5
|
function addPathToValidationError(validationError) {
|
|
6
|
-
|
|
7
|
-
const token = (_c = (_b = (_a = validationError.nodes) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.loc) === null || _c === void 0 ? void 0 : _c.startToken;
|
|
6
|
+
const token = validationError.nodes?.[0]?.loc?.startToken;
|
|
8
7
|
if (!token)
|
|
9
8
|
return validationError;
|
|
10
9
|
let prev = token;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Accountability } from '@directus/shared/types';
|
|
2
|
+
import type { GraphQLError, GraphQLFormattedError } from 'graphql';
|
|
3
3
|
declare const processError: (accountability: Accountability | null, error: Readonly<GraphQLError>) => GraphQLFormattedError;
|
|
4
4
|
export default processError;
|
|
@@ -3,8 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const logger_1 = __importDefault(require("../../../logger"));
|
|
7
6
|
const exceptions_1 = require("@directus/shared/exceptions");
|
|
7
|
+
const logger_1 = __importDefault(require("../../../logger"));
|
|
8
8
|
const processError = (accountability, error) => {
|
|
9
9
|
logger_1.default.error(error);
|
|
10
10
|
const { originalError } = error;
|
|
@@ -18,13 +18,20 @@ const processError = (accountability, error) => {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
if (accountability?.admin === true) {
|
|
22
|
+
const graphqlFormattedError = {
|
|
23
|
+
message: error.message,
|
|
24
24
|
extensions: {
|
|
25
25
|
code: 'INTERNAL_SERVER_ERROR',
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
|
+
if (error.locations) {
|
|
29
|
+
graphqlFormattedError.locations = error.locations;
|
|
30
|
+
}
|
|
31
|
+
if (error.path) {
|
|
32
|
+
graphqlFormattedError.path = error.path;
|
|
33
|
+
}
|
|
34
|
+
return graphqlFormattedError;
|
|
28
35
|
}
|
|
29
36
|
else {
|
|
30
37
|
return {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
3
|
-
import { Knex } from 'knex';
|
|
4
|
-
import { AbstractServiceOptions, File } from '../types';
|
|
2
|
+
import type { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
3
|
+
import type { Knex } from 'knex';
|
|
5
4
|
import type { Readable } from 'node:stream';
|
|
5
|
+
import type { AbstractServiceOptions, File } from '../types';
|
|
6
6
|
type ExportFormat = 'csv' | 'json' | 'xml' | 'yaml';
|
|
7
7
|
export declare class ImportService {
|
|
8
8
|
knex: Knex;
|
|
@@ -17,6 +17,7 @@ const StreamArray_1 = __importDefault(require("stream-json/streamers/StreamArray
|
|
|
17
17
|
const strip_bom_stream_1 = __importDefault(require("strip-bom-stream"));
|
|
18
18
|
const tmp_promise_1 = require("tmp-promise");
|
|
19
19
|
const database_1 = __importDefault(require("../database"));
|
|
20
|
+
const emitter_1 = __importDefault(require("../emitter"));
|
|
20
21
|
const env_1 = __importDefault(require("../env"));
|
|
21
22
|
const exceptions_1 = require("../exceptions");
|
|
22
23
|
const logger_1 = __importDefault(require("../logger"));
|
|
@@ -24,20 +25,21 @@ const get_date_formatted_1 = require("../utils/get-date-formatted");
|
|
|
24
25
|
const files_1 = require("./files");
|
|
25
26
|
const items_1 = require("./items");
|
|
26
27
|
const notifications_1 = require("./notifications");
|
|
27
|
-
const emitter_1 = __importDefault(require("../emitter"));
|
|
28
28
|
class ImportService {
|
|
29
|
+
knex;
|
|
30
|
+
accountability;
|
|
31
|
+
schema;
|
|
29
32
|
constructor(options) {
|
|
30
33
|
this.knex = options.knex || (0, database_1.default)();
|
|
31
34
|
this.accountability = options.accountability || null;
|
|
32
35
|
this.schema = options.schema;
|
|
33
36
|
}
|
|
34
37
|
async import(collection, mimetype, stream) {
|
|
35
|
-
|
|
36
|
-
if (((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true && collection.startsWith('directus_'))
|
|
38
|
+
if (this.accountability?.admin !== true && collection.startsWith('directus_'))
|
|
37
39
|
throw new exceptions_1.ForbiddenException();
|
|
38
|
-
const createPermissions =
|
|
39
|
-
const updatePermissions =
|
|
40
|
-
if (
|
|
40
|
+
const createPermissions = this.accountability?.permissions?.find((permission) => permission.collection === collection && permission.action === 'create');
|
|
41
|
+
const updatePermissions = this.accountability?.permissions?.find((permission) => permission.collection === collection && permission.action === 'update');
|
|
42
|
+
if (this.accountability?.admin !== true && (!createPermissions || !updatePermissions)) {
|
|
41
43
|
throw new exceptions_1.ForbiddenException();
|
|
42
44
|
}
|
|
43
45
|
switch (mimetype) {
|
|
@@ -144,6 +146,9 @@ class ImportService {
|
|
|
144
146
|
}
|
|
145
147
|
exports.ImportService = ImportService;
|
|
146
148
|
class ExportService {
|
|
149
|
+
knex;
|
|
150
|
+
accountability;
|
|
151
|
+
schema;
|
|
147
152
|
constructor(options) {
|
|
148
153
|
this.knex = options.knex || (0, database_1.default)();
|
|
149
154
|
this.accountability = options.accountability || null;
|
|
@@ -155,7 +160,6 @@ class ExportService {
|
|
|
155
160
|
* FilesService upload method.
|
|
156
161
|
*/
|
|
157
162
|
async exportToFile(collection, query, format, options) {
|
|
158
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
159
163
|
try {
|
|
160
164
|
const mimeTypes = {
|
|
161
165
|
csv: 'text/csv',
|
|
@@ -166,7 +170,6 @@ class ExportService {
|
|
|
166
170
|
const database = (0, database_1.default)();
|
|
167
171
|
const { path, cleanup } = await (0, tmp_promise_1.file)();
|
|
168
172
|
await database.transaction(async (trx) => {
|
|
169
|
-
var _a;
|
|
170
173
|
const service = new items_1.ItemsService(collection, {
|
|
171
174
|
accountability: this.accountability,
|
|
172
175
|
schema: this.schema,
|
|
@@ -179,9 +182,9 @@ class ExportService {
|
|
|
179
182
|
count: ['*'],
|
|
180
183
|
},
|
|
181
184
|
})
|
|
182
|
-
.then((result) =>
|
|
185
|
+
.then((result) => Number(result?.[0]?.count ?? 0));
|
|
183
186
|
const count = query.limit ? Math.min(totalCount, query.limit) : totalCount;
|
|
184
|
-
const requestedLimit =
|
|
187
|
+
const requestedLimit = query.limit ?? -1;
|
|
185
188
|
const batchesRequired = Math.ceil(count / env_1.default.EXPORT_BATCH_SIZE);
|
|
186
189
|
let readCount = 0;
|
|
187
190
|
for (let batch = 0; batch < batchesRequired; batch++) {
|
|
@@ -211,14 +214,14 @@ class ExportService {
|
|
|
211
214
|
const title = `export-${collection}-${(0, get_date_formatted_1.getDateFormatted)()}`;
|
|
212
215
|
const filename = `${title}.${format}`;
|
|
213
216
|
const fileWithDefaults = {
|
|
214
|
-
...(
|
|
215
|
-
title:
|
|
216
|
-
filename_download:
|
|
217
|
-
storage:
|
|
217
|
+
...(options?.file ?? {}),
|
|
218
|
+
title: options?.file?.title ?? title,
|
|
219
|
+
filename_download: options?.file?.filename_download ?? filename,
|
|
220
|
+
storage: options?.file?.storage ?? storage,
|
|
218
221
|
type: mimeTypes[format],
|
|
219
222
|
};
|
|
220
223
|
const savedFile = await filesService.uploadOne((0, fs_extra_1.createReadStream)(path), fileWithDefaults);
|
|
221
|
-
if (
|
|
224
|
+
if (this.accountability?.user) {
|
|
222
225
|
const notificationsService = new notifications_1.NotificationsService({
|
|
223
226
|
accountability: this.accountability,
|
|
224
227
|
schema: this.schema,
|
|
@@ -235,7 +238,7 @@ class ExportService {
|
|
|
235
238
|
}
|
|
236
239
|
catch (err) {
|
|
237
240
|
logger_1.default.error(err, `Couldn't export ${collection}: ${err.message}`);
|
|
238
|
-
if (
|
|
241
|
+
if (this.accountability?.user) {
|
|
239
242
|
const notificationsService = new notifications_1.NotificationsService({
|
|
240
243
|
accountability: this.accountability,
|
|
241
244
|
schema: this.schema,
|
|
@@ -255,9 +258,9 @@ class ExportService {
|
|
|
255
258
|
transform(input, format, options) {
|
|
256
259
|
if (format === 'json') {
|
|
257
260
|
let string = JSON.stringify(input || null, null, '\t');
|
|
258
|
-
if (
|
|
261
|
+
if (options?.includeHeader === false)
|
|
259
262
|
string = string.split('\n').slice(1).join('\n');
|
|
260
|
-
if (
|
|
263
|
+
if (options?.includeFooter === false) {
|
|
261
264
|
const lines = string.split('\n');
|
|
262
265
|
string = lines.slice(0, lines.length - 1).join('\n');
|
|
263
266
|
string += ',\n';
|
|
@@ -266,9 +269,9 @@ class ExportService {
|
|
|
266
269
|
}
|
|
267
270
|
if (format === 'xml') {
|
|
268
271
|
let string = (0, js2xmlparser_1.parse)('data', input);
|
|
269
|
-
if (
|
|
272
|
+
if (options?.includeHeader === false)
|
|
270
273
|
string = string.split('\n').slice(2).join('\n');
|
|
271
|
-
if (
|
|
274
|
+
if (options?.includeFooter === false) {
|
|
272
275
|
const lines = string.split('\n');
|
|
273
276
|
string = lines.slice(0, lines.length - 1).join('\n');
|
|
274
277
|
string += '\n';
|
|
@@ -280,10 +283,10 @@ class ExportService {
|
|
|
280
283
|
return '';
|
|
281
284
|
const parser = new json2csv_1.Parser({
|
|
282
285
|
transforms: [json2csv_1.transforms.flatten({ separator: '.' })],
|
|
283
|
-
header:
|
|
286
|
+
header: options?.includeHeader !== false,
|
|
284
287
|
});
|
|
285
288
|
let string = parser.parse(input);
|
|
286
|
-
if (
|
|
289
|
+
if (options?.includeHeader === false) {
|
|
287
290
|
string = '\n' + string;
|
|
288
291
|
}
|
|
289
292
|
return string;
|
package/dist/services/items.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Accountability, PermissionsAction, Query, SchemaOverview } from '@directus/shared/types';
|
|
2
|
-
import Keyv from 'keyv';
|
|
3
|
-
import { Knex } from 'knex';
|
|
4
|
-
import { AbstractService, AbstractServiceOptions, Item as AnyItem, MutationOptions, PrimaryKey } from '../types';
|
|
2
|
+
import type Keyv from 'keyv';
|
|
3
|
+
import type { Knex } from 'knex';
|
|
4
|
+
import type { AbstractService, AbstractServiceOptions, Item as AnyItem, MutationOptions, PrimaryKey } from '../types';
|
|
5
5
|
export type QueryOptions = {
|
|
6
6
|
stripNonRequested?: boolean;
|
|
7
7
|
permissionsAction?: PermissionsAction;
|
package/dist/services/items.js
CHANGED
|
@@ -20,6 +20,12 @@ const authorization_1 = require("./authorization");
|
|
|
20
20
|
const index_1 = require("./index");
|
|
21
21
|
const payload_1 = require("./payload");
|
|
22
22
|
class ItemsService {
|
|
23
|
+
collection;
|
|
24
|
+
knex;
|
|
25
|
+
accountability;
|
|
26
|
+
eventScope;
|
|
27
|
+
schema;
|
|
28
|
+
cache;
|
|
23
29
|
constructor(collection, options) {
|
|
24
30
|
this.collection = collection;
|
|
25
31
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -72,7 +78,7 @@ class ItemsService {
|
|
|
72
78
|
});
|
|
73
79
|
// Run all hooks that are attached to this event so the end user has the chance to augment the
|
|
74
80
|
// item that is about to be saved
|
|
75
|
-
const payloadAfterHooks =
|
|
81
|
+
const payloadAfterHooks = opts?.emitEvents !== false
|
|
76
82
|
? await emitter_1.default.emitFilter(this.eventScope === 'items'
|
|
77
83
|
? ['items.create', `${this.collection}.items.create`]
|
|
78
84
|
: `${this.eventScope}.create`, payload, {
|
|
@@ -86,7 +92,7 @@ class ItemsService {
|
|
|
86
92
|
const payloadWithPresets = this.accountability
|
|
87
93
|
? await authorizationService.validatePayload('create', this.collection, payloadAfterHooks)
|
|
88
94
|
: payloadAfterHooks;
|
|
89
|
-
if (opts
|
|
95
|
+
if (opts?.preMutationException) {
|
|
90
96
|
throw opts.preMutationException;
|
|
91
97
|
}
|
|
92
98
|
const { payload: payloadWithM2O, revisions: revisionsM2O, nestedActionEvents: nestedActionEventsM2O, } = await payloadService.processM2O(payloadWithPresets, opts);
|
|
@@ -103,10 +109,10 @@ class ItemsService {
|
|
|
103
109
|
.then((result) => result[0]);
|
|
104
110
|
const returnedKey = typeof result === 'object' ? result[primaryKeyField] : result;
|
|
105
111
|
if (this.schema.collections[this.collection].fields[primaryKeyField].type === 'uuid') {
|
|
106
|
-
primaryKey = (0, helpers_1.getHelpers)(trx).schema.formatUUID(primaryKey
|
|
112
|
+
primaryKey = (0, helpers_1.getHelpers)(trx).schema.formatUUID(primaryKey ?? returnedKey);
|
|
107
113
|
}
|
|
108
114
|
else {
|
|
109
|
-
primaryKey = primaryKey
|
|
115
|
+
primaryKey = primaryKey ?? returnedKey;
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
catch (err) {
|
|
@@ -148,26 +154,27 @@ class ItemsService {
|
|
|
148
154
|
knex: trx,
|
|
149
155
|
schema: this.schema,
|
|
150
156
|
});
|
|
157
|
+
const revisionDelta = await payloadService.prepareDelta(payloadAfterHooks);
|
|
151
158
|
const revision = await revisionsService.createOne({
|
|
152
159
|
activity: activity,
|
|
153
160
|
collection: this.collection,
|
|
154
161
|
item: primaryKey,
|
|
155
|
-
data:
|
|
156
|
-
delta:
|
|
162
|
+
data: revisionDelta,
|
|
163
|
+
delta: revisionDelta,
|
|
157
164
|
});
|
|
158
165
|
// Make sure to set the parent field of the child-revision rows
|
|
159
166
|
const childrenRevisions = [...revisionsM2O, ...revisionsA2O, ...revisionsO2M];
|
|
160
167
|
if (childrenRevisions.length > 0) {
|
|
161
168
|
await revisionsService.updateMany(childrenRevisions, { parent: revision });
|
|
162
169
|
}
|
|
163
|
-
if (opts
|
|
170
|
+
if (opts?.onRevisionCreate) {
|
|
164
171
|
opts.onRevisionCreate(revision);
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
174
|
}
|
|
168
175
|
return primaryKey;
|
|
169
176
|
});
|
|
170
|
-
if (
|
|
177
|
+
if (opts?.emitEvents !== false) {
|
|
171
178
|
const actionEvent = {
|
|
172
179
|
event: this.eventScope === 'items'
|
|
173
180
|
? ['items.create', `${this.collection}.items.create`]
|
|
@@ -183,14 +190,14 @@ class ItemsService {
|
|
|
183
190
|
accountability: this.accountability,
|
|
184
191
|
},
|
|
185
192
|
};
|
|
186
|
-
if (opts
|
|
193
|
+
if (opts?.bypassEmitAction) {
|
|
187
194
|
opts.bypassEmitAction(actionEvent);
|
|
188
195
|
}
|
|
189
196
|
else {
|
|
190
197
|
emitter_1.default.emitAction(actionEvent.event, actionEvent.meta, actionEvent.context);
|
|
191
198
|
}
|
|
192
199
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
193
|
-
if (opts
|
|
200
|
+
if (opts?.bypassEmitAction) {
|
|
194
201
|
opts.bypassEmitAction(nestedActionEvent);
|
|
195
202
|
}
|
|
196
203
|
else {
|
|
@@ -198,7 +205,7 @@ class ItemsService {
|
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
207
|
}
|
|
201
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
208
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
202
209
|
await this.cache.clear();
|
|
203
210
|
}
|
|
204
211
|
return primaryKey;
|
|
@@ -225,9 +232,9 @@ class ItemsService {
|
|
|
225
232
|
}
|
|
226
233
|
return { primaryKeys, nestedActionEvents };
|
|
227
234
|
});
|
|
228
|
-
if (
|
|
235
|
+
if (opts?.emitEvents !== false) {
|
|
229
236
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
230
|
-
if (opts
|
|
237
|
+
if (opts?.bypassEmitAction) {
|
|
231
238
|
opts.bypassEmitAction(nestedActionEvent);
|
|
232
239
|
}
|
|
233
240
|
else {
|
|
@@ -235,7 +242,7 @@ class ItemsService {
|
|
|
235
242
|
}
|
|
236
243
|
}
|
|
237
244
|
}
|
|
238
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
245
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
239
246
|
await this.cache.clear();
|
|
240
247
|
}
|
|
241
248
|
return primaryKeys;
|
|
@@ -244,7 +251,7 @@ class ItemsService {
|
|
|
244
251
|
* Get items by query
|
|
245
252
|
*/
|
|
246
253
|
async readByQuery(query, opts) {
|
|
247
|
-
const updatedQuery =
|
|
254
|
+
const updatedQuery = opts?.emitEvents !== false
|
|
248
255
|
? await emitter_1.default.emitFilter(this.eventScope === 'items'
|
|
249
256
|
? ['items.query', `${this.collection}.items.query`]
|
|
250
257
|
: `${this.eventScope}.query`, query, {
|
|
@@ -260,7 +267,7 @@ class ItemsService {
|
|
|
260
267
|
// By setting the permissions action, you can read items using the permissions for another
|
|
261
268
|
// operation's permissions. This is used to dynamically check if you have update/delete
|
|
262
269
|
// access to (a) certain item(s)
|
|
263
|
-
action:
|
|
270
|
+
action: opts?.permissionsAction || 'read',
|
|
264
271
|
knex: this.knex,
|
|
265
272
|
});
|
|
266
273
|
if (this.accountability && this.accountability.admin !== true) {
|
|
@@ -269,17 +276,17 @@ class ItemsService {
|
|
|
269
276
|
knex: this.knex,
|
|
270
277
|
schema: this.schema,
|
|
271
278
|
});
|
|
272
|
-
ast = await authorizationService.processAST(ast, opts
|
|
279
|
+
ast = await authorizationService.processAST(ast, opts?.permissionsAction);
|
|
273
280
|
}
|
|
274
281
|
const records = await (0, run_ast_1.default)(ast, this.schema, {
|
|
275
282
|
knex: this.knex,
|
|
276
283
|
// GraphQL requires relational keys to be returned regardless
|
|
277
|
-
stripNonRequested:
|
|
284
|
+
stripNonRequested: opts?.stripNonRequested !== undefined ? opts.stripNonRequested : true,
|
|
278
285
|
});
|
|
279
286
|
if (records === null) {
|
|
280
287
|
throw new exceptions_1.ForbiddenException();
|
|
281
288
|
}
|
|
282
|
-
const filteredRecords =
|
|
289
|
+
const filteredRecords = opts?.emitEvents !== false
|
|
283
290
|
? await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, records, {
|
|
284
291
|
query: updatedQuery,
|
|
285
292
|
collection: this.collection,
|
|
@@ -289,7 +296,7 @@ class ItemsService {
|
|
|
289
296
|
accountability: this.accountability,
|
|
290
297
|
})
|
|
291
298
|
: records;
|
|
292
|
-
if (
|
|
299
|
+
if (opts?.emitEvents !== false) {
|
|
293
300
|
emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, {
|
|
294
301
|
payload: filteredRecords,
|
|
295
302
|
query: updatedQuery,
|
|
@@ -320,10 +327,9 @@ class ItemsService {
|
|
|
320
327
|
* Get multiple items by primary keys
|
|
321
328
|
*/
|
|
322
329
|
async readMany(keys, query = {}, opts) {
|
|
323
|
-
var _a;
|
|
324
330
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
325
331
|
(0, validate_keys_1.validateKeys)(this.schema, this.collection, primaryKeyField, keys);
|
|
326
|
-
const filterWithKey = { _and: [{ [primaryKeyField]: { _in: keys } },
|
|
332
|
+
const filterWithKey = { _and: [{ [primaryKeyField]: { _in: keys } }, query.filter ?? {}] };
|
|
327
333
|
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
328
334
|
// Set query limit as the number of keys
|
|
329
335
|
if (Array.isArray(keys) && keys.length > 0 && !queryWithKey.limit) {
|
|
@@ -375,7 +381,7 @@ class ItemsService {
|
|
|
375
381
|
});
|
|
376
382
|
}
|
|
377
383
|
finally {
|
|
378
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
384
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
379
385
|
await this.cache.clear();
|
|
380
386
|
}
|
|
381
387
|
}
|
|
@@ -400,7 +406,7 @@ class ItemsService {
|
|
|
400
406
|
});
|
|
401
407
|
// Run all hooks that are attached to this event so the end user has the chance to augment the
|
|
402
408
|
// item that is about to be saved
|
|
403
|
-
const payloadAfterHooks =
|
|
409
|
+
const payloadAfterHooks = opts?.emitEvents !== false
|
|
404
410
|
? await emitter_1.default.emitFilter(this.eventScope === 'items'
|
|
405
411
|
? ['items.update', `${this.collection}.items.update`]
|
|
406
412
|
: `${this.eventScope}.update`, payload, {
|
|
@@ -420,7 +426,7 @@ class ItemsService {
|
|
|
420
426
|
const payloadWithPresets = this.accountability
|
|
421
427
|
? await authorizationService.validatePayload('update', this.collection, payloadAfterHooks)
|
|
422
428
|
: payloadAfterHooks;
|
|
423
|
-
if (opts
|
|
429
|
+
if (opts?.preMutationException) {
|
|
424
430
|
throw opts.preMutationException;
|
|
425
431
|
}
|
|
426
432
|
await this.knex.transaction(async (trx) => {
|
|
@@ -484,7 +490,7 @@ class ItemsService {
|
|
|
484
490
|
const revisionIDs = await revisionsService.createMany(revisions);
|
|
485
491
|
for (let i = 0; i < revisionIDs.length; i++) {
|
|
486
492
|
const revisionID = revisionIDs[i];
|
|
487
|
-
if (opts
|
|
493
|
+
if (opts?.onRevisionCreate) {
|
|
488
494
|
opts.onRevisionCreate(revisionID);
|
|
489
495
|
}
|
|
490
496
|
if (i === 0) {
|
|
@@ -500,10 +506,10 @@ class ItemsService {
|
|
|
500
506
|
}
|
|
501
507
|
}
|
|
502
508
|
});
|
|
503
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
509
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
504
510
|
await this.cache.clear();
|
|
505
511
|
}
|
|
506
|
-
if (
|
|
512
|
+
if (opts?.emitEvents !== false) {
|
|
507
513
|
const actionEvent = {
|
|
508
514
|
event: this.eventScope === 'items'
|
|
509
515
|
? ['items.update', `${this.collection}.items.update`]
|
|
@@ -519,14 +525,14 @@ class ItemsService {
|
|
|
519
525
|
accountability: this.accountability,
|
|
520
526
|
},
|
|
521
527
|
};
|
|
522
|
-
if (opts
|
|
528
|
+
if (opts?.bypassEmitAction) {
|
|
523
529
|
opts.bypassEmitAction(actionEvent);
|
|
524
530
|
}
|
|
525
531
|
else {
|
|
526
532
|
emitter_1.default.emitAction(actionEvent.event, actionEvent.meta, actionEvent.context);
|
|
527
533
|
}
|
|
528
534
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
529
|
-
if (opts
|
|
535
|
+
if (opts?.bypassEmitAction) {
|
|
530
536
|
opts.bypassEmitAction(nestedActionEvent);
|
|
531
537
|
}
|
|
532
538
|
else {
|
|
@@ -575,7 +581,7 @@ class ItemsService {
|
|
|
575
581
|
}
|
|
576
582
|
return primaryKeys;
|
|
577
583
|
});
|
|
578
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
584
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
579
585
|
await this.cache.clear();
|
|
580
586
|
}
|
|
581
587
|
return primaryKeys;
|
|
@@ -612,10 +618,10 @@ class ItemsService {
|
|
|
612
618
|
});
|
|
613
619
|
await authorizationService.checkAccess('delete', this.collection, keys);
|
|
614
620
|
}
|
|
615
|
-
if (opts
|
|
621
|
+
if (opts?.preMutationException) {
|
|
616
622
|
throw opts.preMutationException;
|
|
617
623
|
}
|
|
618
|
-
if (
|
|
624
|
+
if (opts?.emitEvents !== false) {
|
|
619
625
|
await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.delete', `${this.collection}.items.delete`] : `${this.eventScope}.delete`, keys, {
|
|
620
626
|
collection: this.collection,
|
|
621
627
|
}, {
|
|
@@ -642,10 +648,10 @@ class ItemsService {
|
|
|
642
648
|
})));
|
|
643
649
|
}
|
|
644
650
|
});
|
|
645
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
651
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
646
652
|
await this.cache.clear();
|
|
647
653
|
}
|
|
648
|
-
if (
|
|
654
|
+
if (opts?.emitEvents !== false) {
|
|
649
655
|
const actionEvent = {
|
|
650
656
|
event: this.eventScope === 'items'
|
|
651
657
|
? ['items.delete', `${this.collection}.items.delete`]
|
|
@@ -661,7 +667,7 @@ class ItemsService {
|
|
|
661
667
|
accountability: this.accountability,
|
|
662
668
|
},
|
|
663
669
|
};
|
|
664
|
-
if (opts
|
|
670
|
+
if (opts?.bypassEmitAction) {
|
|
665
671
|
opts.bypassEmitAction(actionEvent);
|
|
666
672
|
}
|
|
667
673
|
else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import type { SendMailOptions, Transporter } from 'nodemailer';
|
|
4
|
+
import type { AbstractServiceOptions } from '../../types';
|
|
5
5
|
export type EmailOptions = SendMailOptions & {
|
|
6
6
|
template?: {
|
|
7
7
|
name: string;
|
|
@@ -18,10 +18,14 @@ const liquidEngine = new liquidjs_1.Liquid({
|
|
|
18
18
|
extname: '.liquid',
|
|
19
19
|
});
|
|
20
20
|
class MailService {
|
|
21
|
+
schema;
|
|
22
|
+
accountability;
|
|
23
|
+
knex;
|
|
24
|
+
mailer;
|
|
21
25
|
constructor(opts) {
|
|
22
26
|
this.schema = opts.schema;
|
|
23
27
|
this.accountability = opts.accountability || null;
|
|
24
|
-
this.knex =
|
|
28
|
+
this.knex = opts?.knex || (0, database_1.default)();
|
|
25
29
|
this.mailer = (0, mailer_1.default)();
|
|
26
30
|
if (env_1.default.EMAIL_VERIFY_SETUP) {
|
|
27
31
|
this.mailer.verify((error) => {
|
|
@@ -72,10 +76,10 @@ class MailService {
|
|
|
72
76
|
.from('directus_settings')
|
|
73
77
|
.first();
|
|
74
78
|
return {
|
|
75
|
-
projectName:
|
|
76
|
-
projectColor:
|
|
77
|
-
projectLogo: getProjectLogoURL(projectInfo
|
|
78
|
-
projectUrl:
|
|
79
|
+
projectName: projectInfo?.project_name || 'Directus',
|
|
80
|
+
projectColor: projectInfo?.project_color || '#546e7a',
|
|
81
|
+
projectLogo: getProjectLogoURL(projectInfo?.project_logo),
|
|
82
|
+
projectUrl: projectInfo?.project_url || '',
|
|
79
83
|
};
|
|
80
84
|
function getProjectLogoURL(logoID) {
|
|
81
85
|
const projectLogoUrl = new url_1.Url(env_1.default.PUBLIC_URL);
|
package/dist/services/meta.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import type { AbstractServiceOptions } from '../types';
|
|
4
4
|
export declare class MetaService {
|
|
5
5
|
knex: Knex;
|
|
6
6
|
accountability: Accountability | null;
|
package/dist/services/meta.js
CHANGED
|
@@ -8,6 +8,9 @@ const database_1 = __importDefault(require("../database"));
|
|
|
8
8
|
const exceptions_1 = require("../exceptions");
|
|
9
9
|
const apply_query_1 = require("../utils/apply-query");
|
|
10
10
|
class MetaService {
|
|
11
|
+
knex;
|
|
12
|
+
accountability;
|
|
13
|
+
schema;
|
|
11
14
|
constructor(options) {
|
|
12
15
|
this.knex = options.knex || (0, database_1.default)();
|
|
13
16
|
this.accountability = options.accountability || null;
|
|
@@ -31,31 +34,29 @@ class MetaService {
|
|
|
31
34
|
}, {});
|
|
32
35
|
}
|
|
33
36
|
async totalCount(collection) {
|
|
34
|
-
var _a, _b, _c, _d, _e;
|
|
35
37
|
const dbQuery = this.knex(collection).count('*', { as: 'count' }).first();
|
|
36
|
-
if (
|
|
37
|
-
const permissionsRecord =
|
|
38
|
+
if (this.accountability?.admin !== true) {
|
|
39
|
+
const permissionsRecord = this.accountability?.permissions?.find((permission) => {
|
|
38
40
|
return permission.action === 'read' && permission.collection === collection;
|
|
39
41
|
});
|
|
40
42
|
if (!permissionsRecord)
|
|
41
43
|
throw new exceptions_1.ForbiddenException();
|
|
42
|
-
const permissions =
|
|
44
|
+
const permissions = permissionsRecord.permissions ?? {};
|
|
43
45
|
(0, apply_query_1.applyFilter)(this.knex, this.schema, dbQuery, permissions, collection, {});
|
|
44
46
|
}
|
|
45
47
|
const result = await dbQuery;
|
|
46
|
-
return Number(
|
|
48
|
+
return Number(result?.count ?? 0);
|
|
47
49
|
}
|
|
48
50
|
async filterCount(collection, query) {
|
|
49
|
-
var _a, _b, _c, _d;
|
|
50
51
|
const dbQuery = this.knex(collection).count('*', { as: 'count' });
|
|
51
52
|
let filter = query.filter || {};
|
|
52
|
-
if (
|
|
53
|
-
const permissionsRecord =
|
|
53
|
+
if (this.accountability?.admin !== true) {
|
|
54
|
+
const permissionsRecord = this.accountability?.permissions?.find((permission) => {
|
|
54
55
|
return permission.action === 'read' && permission.collection === collection;
|
|
55
56
|
});
|
|
56
57
|
if (!permissionsRecord)
|
|
57
58
|
throw new exceptions_1.ForbiddenException();
|
|
58
|
-
const permissions =
|
|
59
|
+
const permissions = permissionsRecord.permissions ?? {};
|
|
59
60
|
if (Object.keys(filter).length > 0) {
|
|
60
61
|
filter = { _and: [permissions, filter] };
|
|
61
62
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Notification } from '@directus/shared/types';
|
|
2
|
+
import type { AbstractServiceOptions, MutationOptions, PrimaryKey } from '../types';
|
|
2
3
|
import { ItemsService } from './items';
|
|
3
|
-
import { Notification } from '@directus/shared/types';
|
|
4
|
-
import { UsersService } from './users';
|
|
5
4
|
import { MailService } from './mail';
|
|
5
|
+
import { UsersService } from './users';
|
|
6
6
|
export declare class NotificationsService extends ItemsService {
|
|
7
7
|
usersService: UsersService;
|
|
8
8
|
mailService: MailService;
|