directus 9.22.4 → 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 +19 -14
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +2 -0
- package/dist/auth/drivers/ldap.d.ts +2 -2
- package/dist/auth/drivers/ldap.js +47 -36
- 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 +22 -15
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +23 -16
- 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 +59 -16
- 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 +21 -20
- package/dist/cli/commands/schema/snapshot.js +2 -2
- package/dist/cli/utils/create-db-connection.d.ts +2 -1
- package/dist/cli/utils/create-db-connection.js +2 -1
- package/dist/cli/utils/create-env/env-stub.liquid +1 -1
- package/dist/cli/utils/create-env/index.d.ts +2 -2
- package/dist/cli/utils/drivers.d.ts +3 -9
- package/dist/constants.d.ts +3 -9
- package/dist/constants.js +5 -10
- package/dist/controllers/activity.js +1 -2
- package/dist/controllers/assets.js +17 -12
- package/dist/controllers/auth.js +29 -15
- package/dist/controllers/dashboards.js +5 -2
- package/dist/controllers/extensions.js +7 -7
- package/dist/controllers/fields.js +4 -4
- package/dist/controllers/files.js +11 -6
- package/dist/controllers/flows.js +5 -2
- package/dist/controllers/folders.js +5 -2
- package/dist/controllers/graphql.js +6 -0
- 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/schema.d.ts +2 -0
- package/dist/controllers/schema.js +98 -0
- 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 +2 -2
- 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 +5 -2
- package/dist/database/helpers/schema/dialects/oracle.js +23 -0
- package/dist/database/helpers/schema/types.d.ts +9 -7
- package/dist/database/helpers/schema/types.js +7 -1
- package/dist/database/helpers/types.d.ts +1 -1
- package/dist/database/helpers/types.js +1 -0
- package/dist/database/index.d.ts +2 -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 +19 -28
- 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 +19 -4
- 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 +34 -24
- package/dist/flows.js +56 -30
- 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 +7 -7
- 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 +18 -14
- 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 +21 -20
- package/dist/operations/trigger/index.d.ts +2 -0
- package/dist/operations/trigger/index.js +27 -11
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +8 -8
- package/dist/request/index.d.ts +5 -0
- package/dist/request/index.js +18 -0
- package/dist/request/index.test.d.ts +1 -0
- package/dist/request/request-interceptor.d.ts +2 -0
- package/dist/request/request-interceptor.js +33 -0
- package/dist/request/request-interceptor.test.d.ts +1 -0
- package/dist/request/response-interceptor.d.ts +2 -0
- package/dist/request/response-interceptor.js +9 -0
- package/dist/request/response-interceptor.test.d.ts +1 -0
- package/dist/request/validate-ip.d.ts +1 -0
- package/dist/request/validate-ip.js +27 -0
- package/dist/request/validate-ip.test.d.ts +1 -0
- 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 -26
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +18 -15
- 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 +49 -48
- package/dist/services/files.d.ts +1 -2
- package/dist/services/files.js +70 -108
- 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 +181 -170
- 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 +29 -9
- package/dist/services/import-export.d.ts +7 -5
- package/dist/services/import-export.js +41 -24
- package/dist/services/import-export.test.d.ts +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +67 -42
- 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 +47 -43
- package/dist/services/revisions.d.ts +1 -1
- package/dist/services/roles.d.ts +2 -2
- package/dist/services/roles.js +34 -13
- package/dist/services/schema.d.ts +15 -0
- package/dist/services/schema.js +56 -0
- package/dist/services/schema.test.d.ts +1 -0
- 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 +2 -2
- package/dist/services/shares.js +14 -15
- 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 +89 -62
- 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 +2 -2
- 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/database.d.ts +3 -0
- package/dist/types/database.js +4 -0
- package/dist/types/events.d.ts +2 -2
- package/dist/types/graphql.d.ts +2 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/items.d.ts +7 -2
- package/dist/types/services.d.ts +5 -5
- package/dist/types/snapshot.d.ts +25 -3
- package/dist/types/snapshot.js +14 -0
- package/dist/utils/apply-diff.d.ts +9 -0
- package/dist/utils/apply-diff.js +256 -0
- package/dist/utils/apply-diff.test.d.ts +1 -0
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +15 -16
- package/dist/utils/apply-snapshot.d.ts +3 -5
- package/dist/utils/apply-snapshot.js +9 -240
- 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 +4 -2
- package/dist/utils/get-cache-headers.js +21 -21
- package/dist/utils/get-cache-headers.test.d.ts +1 -0
- 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.d.ts +4 -0
- package/dist/utils/get-milliseconds.js +14 -0
- package/dist/utils/get-milliseconds.test.d.ts +1 -0
- 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 +10 -7
- package/dist/utils/get-snapshot.d.ts +3 -3
- package/dist/utils/get-snapshot.js +35 -14
- package/dist/utils/get-versioned-hash.d.ts +1 -0
- package/dist/utils/get-versioned-hash.js +12 -0
- package/dist/utils/get-versioned-hash.test.d.ts +1 -0
- 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/map-values-deep.d.ts +1 -0
- package/dist/utils/map-values-deep.js +29 -0
- package/dist/utils/map-values-deep.test.d.ts +1 -0
- 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 +30 -0
- package/dist/utils/sanitize-schema.js +80 -0
- package/dist/utils/sanitize-schema.test.d.ts +1 -0
- 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/track.js +3 -3
- package/dist/utils/transformations.d.ts +1 -1
- package/dist/utils/transformations.js +2 -4
- package/dist/utils/url.js +9 -8
- package/dist/utils/url.test.d.ts +1 -0
- package/dist/utils/user-name.d.ts +1 -1
- package/dist/utils/validate-diff.d.ts +7 -0
- package/dist/utils/validate-diff.js +113 -0
- package/dist/utils/validate-diff.test.d.ts +1 -0
- 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 +3 -3
- package/dist/utils/validate-query.test.d.ts +1 -0
- package/dist/utils/validate-snapshot.d.ts +5 -0
- package/dist/utils/validate-snapshot.js +71 -0
- package/dist/utils/validate-snapshot.test.d.ts +1 -0
- package/dist/webhooks.js +4 -3
- package/package.json +62 -62
package/dist/services/fields.js
CHANGED
|
@@ -44,10 +44,18 @@ const items_1 = require("../services/items");
|
|
|
44
44
|
const payload_1 = require("../services/payload");
|
|
45
45
|
const get_default_value_1 = __importDefault(require("../utils/get-default-value"));
|
|
46
46
|
const get_local_type_1 = __importDefault(require("../utils/get-local-type"));
|
|
47
|
-
const relations_1 = require("./relations");
|
|
48
|
-
const constants_3 = require("@directus/shared/constants");
|
|
49
47
|
const get_schema_1 = require("../utils/get-schema");
|
|
48
|
+
const relations_1 = require("./relations");
|
|
50
49
|
class FieldsService {
|
|
50
|
+
knex;
|
|
51
|
+
helpers;
|
|
52
|
+
accountability;
|
|
53
|
+
itemsService;
|
|
54
|
+
payloadService;
|
|
55
|
+
schemaInspector;
|
|
56
|
+
schema;
|
|
57
|
+
cache;
|
|
58
|
+
systemCache;
|
|
51
59
|
constructor(options) {
|
|
52
60
|
this.knex = options.knex || (0, database_1.default)();
|
|
53
61
|
this.helpers = (0, helpers_1.getHelpers)(this.knex);
|
|
@@ -61,13 +69,11 @@ class FieldsService {
|
|
|
61
69
|
this.systemCache = systemCache;
|
|
62
70
|
}
|
|
63
71
|
get hasReadAccess() {
|
|
64
|
-
|
|
65
|
-
return !!((_b = (_a = this.accountability) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.find((permission) => {
|
|
72
|
+
return !!this.accountability?.permissions?.find((permission) => {
|
|
66
73
|
return permission.collection === 'directus_fields' && permission.action === 'read';
|
|
67
|
-
})
|
|
74
|
+
});
|
|
68
75
|
}
|
|
69
76
|
async readAll(collection) {
|
|
70
|
-
var _a, _b, _c, _d;
|
|
71
77
|
let fields;
|
|
72
78
|
if (this.accountability && this.accountability.admin !== true && this.hasReadAccess === false) {
|
|
73
79
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -144,8 +150,7 @@ class FieldsService {
|
|
|
144
150
|
});
|
|
145
151
|
const allowedFieldsInCollection = {};
|
|
146
152
|
permissions.forEach((permission) => {
|
|
147
|
-
|
|
148
|
-
allowedFieldsInCollection[permission.collection] = (_a = permission.fields) !== null && _a !== void 0 ? _a : [];
|
|
153
|
+
allowedFieldsInCollection[permission.collection] = permission.fields ?? [];
|
|
149
154
|
});
|
|
150
155
|
if (collection && collection in allowedFieldsInCollection === false) {
|
|
151
156
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -161,12 +166,13 @@ class FieldsService {
|
|
|
161
166
|
}
|
|
162
167
|
// Update specific database type overrides
|
|
163
168
|
for (const field of result) {
|
|
164
|
-
if (
|
|
169
|
+
if (field.meta?.special?.includes('cast-timestamp')) {
|
|
165
170
|
field.type = 'timestamp';
|
|
166
171
|
}
|
|
167
|
-
else if (
|
|
172
|
+
else if (field.meta?.special?.includes('cast-datetime')) {
|
|
168
173
|
field.type = 'dateTime';
|
|
169
174
|
}
|
|
175
|
+
field.type = this.helpers.schema.processFieldType(field);
|
|
170
176
|
}
|
|
171
177
|
return result;
|
|
172
178
|
}
|
|
@@ -280,7 +286,7 @@ class FieldsService {
|
|
|
280
286
|
accountability: this.accountability,
|
|
281
287
|
},
|
|
282
288
|
};
|
|
283
|
-
if (opts
|
|
289
|
+
if (opts?.bypassEmitAction) {
|
|
284
290
|
opts.bypassEmitAction(actionEvent);
|
|
285
291
|
}
|
|
286
292
|
else {
|
|
@@ -292,13 +298,13 @@ class FieldsService {
|
|
|
292
298
|
if (runPostColumnChange) {
|
|
293
299
|
await this.helpers.schema.postColumnChange();
|
|
294
300
|
}
|
|
295
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
301
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
296
302
|
await this.cache.clear();
|
|
297
303
|
}
|
|
298
|
-
if (
|
|
299
|
-
await (0, cache_1.clearSystemCache)();
|
|
304
|
+
if (opts?.autoPurgeSystemCache !== false) {
|
|
305
|
+
await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
|
|
300
306
|
}
|
|
301
|
-
if (
|
|
307
|
+
if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
|
|
302
308
|
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
303
309
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
304
310
|
nestedActionEvent.context.schema = updatedSchema;
|
|
@@ -308,7 +314,6 @@ class FieldsService {
|
|
|
308
314
|
}
|
|
309
315
|
}
|
|
310
316
|
async updateField(collection, field, opts) {
|
|
311
|
-
var _a, _b, _c;
|
|
312
317
|
if (this.accountability && this.accountability.admin !== true) {
|
|
313
318
|
throw new exceptions_1.ForbiddenException();
|
|
314
319
|
}
|
|
@@ -328,8 +333,8 @@ class FieldsService {
|
|
|
328
333
|
: null;
|
|
329
334
|
if (hookAdjustedField.type &&
|
|
330
335
|
(hookAdjustedField.type === 'alias' ||
|
|
331
|
-
|
|
332
|
-
hookAdjustedField.type !== (
|
|
336
|
+
this.schema.collections[collection].fields[field.field]?.type === 'alias') &&
|
|
337
|
+
hookAdjustedField.type !== (this.schema.collections[collection].fields[field.field]?.type ?? 'alias')) {
|
|
333
338
|
throw new exceptions_1.InvalidPayloadException('Alias type cannot be changed');
|
|
334
339
|
}
|
|
335
340
|
if (hookAdjustedField.schema) {
|
|
@@ -376,7 +381,7 @@ class FieldsService {
|
|
|
376
381
|
accountability: this.accountability,
|
|
377
382
|
},
|
|
378
383
|
};
|
|
379
|
-
if (opts
|
|
384
|
+
if (opts?.bypassEmitAction) {
|
|
380
385
|
opts.bypassEmitAction(actionEvent);
|
|
381
386
|
}
|
|
382
387
|
else {
|
|
@@ -388,13 +393,13 @@ class FieldsService {
|
|
|
388
393
|
if (runPostColumnChange) {
|
|
389
394
|
await this.helpers.schema.postColumnChange();
|
|
390
395
|
}
|
|
391
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
396
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
392
397
|
await this.cache.clear();
|
|
393
398
|
}
|
|
394
|
-
if (
|
|
395
|
-
await (0, cache_1.clearSystemCache)();
|
|
399
|
+
if (opts?.autoPurgeSystemCache !== false) {
|
|
400
|
+
await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
|
|
396
401
|
}
|
|
397
|
-
if (
|
|
402
|
+
if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
|
|
398
403
|
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
399
404
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
400
405
|
nestedActionEvent.context.schema = updatedSchema;
|
|
@@ -418,11 +423,9 @@ class FieldsService {
|
|
|
418
423
|
accountability: this.accountability,
|
|
419
424
|
});
|
|
420
425
|
await this.knex.transaction(async (trx) => {
|
|
421
|
-
var _a, _b;
|
|
422
426
|
const relations = this.schema.relations.filter((relation) => {
|
|
423
|
-
var _a;
|
|
424
427
|
return ((relation.collection === collection && relation.field === field) ||
|
|
425
|
-
(relation.related_collection === collection &&
|
|
428
|
+
(relation.related_collection === collection && relation.meta?.one_field === field));
|
|
426
429
|
});
|
|
427
430
|
const relationsService = new relations_1.RelationsService({
|
|
428
431
|
knex: trx,
|
|
@@ -440,21 +443,21 @@ class FieldsService {
|
|
|
440
443
|
if (isM2O) {
|
|
441
444
|
await relationsService.deleteOne(collection, field, {
|
|
442
445
|
autoPurgeSystemCache: false,
|
|
443
|
-
bypassEmitAction: (params) =>
|
|
446
|
+
bypassEmitAction: (params) => opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
444
447
|
});
|
|
445
448
|
if (relation.related_collection &&
|
|
446
|
-
|
|
449
|
+
relation.meta?.one_field &&
|
|
447
450
|
relation.related_collection !== collection &&
|
|
448
451
|
relation.meta.one_field !== field) {
|
|
449
452
|
await fieldsService.deleteField(relation.related_collection, relation.meta.one_field, {
|
|
450
453
|
autoPurgeCache: false,
|
|
451
454
|
autoPurgeSystemCache: false,
|
|
452
|
-
bypassEmitAction: (params) =>
|
|
455
|
+
bypassEmitAction: (params) => opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
453
456
|
});
|
|
454
457
|
}
|
|
455
458
|
}
|
|
456
459
|
// If the current field is a o2m, just delete the one field config from the relation
|
|
457
|
-
if (!isM2O &&
|
|
460
|
+
if (!isM2O && relation.meta?.one_field) {
|
|
458
461
|
await trx('directus_relations')
|
|
459
462
|
.update({ one_field: null })
|
|
460
463
|
.where({ many_collection: relation.collection, many_field: relation.field });
|
|
@@ -474,10 +477,10 @@ class FieldsService {
|
|
|
474
477
|
.where({ collection })
|
|
475
478
|
.first();
|
|
476
479
|
const collectionMetaUpdates = {};
|
|
477
|
-
if (
|
|
480
|
+
if (collectionMeta?.archive_field === field) {
|
|
478
481
|
collectionMetaUpdates.archive_field = null;
|
|
479
482
|
}
|
|
480
|
-
if (
|
|
483
|
+
if (collectionMeta?.sort_field === field) {
|
|
481
484
|
collectionMetaUpdates.sort_field = null;
|
|
482
485
|
}
|
|
483
486
|
if (Object.keys(collectionMetaUpdates).length > 0) {
|
|
@@ -509,7 +512,7 @@ class FieldsService {
|
|
|
509
512
|
accountability: this.accountability,
|
|
510
513
|
},
|
|
511
514
|
};
|
|
512
|
-
if (opts
|
|
515
|
+
if (opts?.bypassEmitAction) {
|
|
513
516
|
opts.bypassEmitAction(actionEvent);
|
|
514
517
|
}
|
|
515
518
|
else {
|
|
@@ -520,13 +523,13 @@ class FieldsService {
|
|
|
520
523
|
if (runPostColumnChange) {
|
|
521
524
|
await this.helpers.schema.postColumnChange();
|
|
522
525
|
}
|
|
523
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
526
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
524
527
|
await this.cache.clear();
|
|
525
528
|
}
|
|
526
|
-
if (
|
|
527
|
-
await (0, cache_1.clearSystemCache)();
|
|
529
|
+
if (opts?.autoPurgeSystemCache !== false) {
|
|
530
|
+
await (0, cache_1.clearSystemCache)({ autoPurgeCache: opts?.autoPurgeCache });
|
|
528
531
|
}
|
|
529
|
-
if (
|
|
532
|
+
if (opts?.emitEvents !== false && nestedActionEvents.length > 0) {
|
|
530
533
|
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
531
534
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
532
535
|
nestedActionEvent.context.schema = updatedSchema;
|
|
@@ -536,14 +539,12 @@ class FieldsService {
|
|
|
536
539
|
}
|
|
537
540
|
}
|
|
538
541
|
addColumnToTable(table, field, alter = null) {
|
|
539
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
540
542
|
let column;
|
|
541
543
|
// Don't attempt to add a DB column for alias / corrupt fields
|
|
542
544
|
if (field.type === 'alias' || field.type === 'unknown')
|
|
543
545
|
return;
|
|
544
|
-
if (
|
|
546
|
+
if (field.schema?.has_auto_increment) {
|
|
545
547
|
if (field.type === 'bigInteger') {
|
|
546
|
-
// Create an auto-incremented big integer (MySQL, PostgreSQL) or an auto-incremented integer (other DBs)
|
|
547
548
|
column = table.bigIncrements(field.field);
|
|
548
549
|
}
|
|
549
550
|
else {
|
|
@@ -551,11 +552,11 @@ class FieldsService {
|
|
|
551
552
|
}
|
|
552
553
|
}
|
|
553
554
|
else if (field.type === 'string') {
|
|
554
|
-
column = table.string(field.field,
|
|
555
|
+
column = table.string(field.field, field.schema?.max_length ?? undefined);
|
|
555
556
|
}
|
|
556
557
|
else if (['float', 'decimal'].includes(field.type)) {
|
|
557
558
|
const type = field.type;
|
|
558
|
-
column = table[type](field.field,
|
|
559
|
+
column = table[type](field.field, field.schema?.numeric_precision ?? 10, field.schema?.numeric_scale ?? 5);
|
|
559
560
|
}
|
|
560
561
|
else if (field.type === 'csv') {
|
|
561
562
|
column = table.string(field.field);
|
|
@@ -572,13 +573,13 @@ class FieldsService {
|
|
|
572
573
|
else if (field.type.startsWith('geometry')) {
|
|
573
574
|
column = this.helpers.st.createColumn(table, field);
|
|
574
575
|
}
|
|
575
|
-
else if (
|
|
576
|
+
else if (constants_1.KNEX_TYPES.includes(field.type)) {
|
|
576
577
|
column = table[field.type](field.field);
|
|
577
578
|
}
|
|
578
579
|
else {
|
|
579
580
|
throw new exceptions_1.InvalidPayloadException(`Illegal type passed: "${field.type}"`);
|
|
580
581
|
}
|
|
581
|
-
if (
|
|
582
|
+
if (field.schema?.default_value !== undefined) {
|
|
582
583
|
if (typeof field.schema.default_value === 'string' &&
|
|
583
584
|
(field.schema.default_value.toLowerCase() === 'now()' || field.schema.default_value === 'CURRENT_TIMESTAMP')) {
|
|
584
585
|
column.defaultTo(this.knex.fn.now());
|
|
@@ -593,7 +594,7 @@ class FieldsService {
|
|
|
593
594
|
column.defaultTo(field.schema.default_value);
|
|
594
595
|
}
|
|
595
596
|
}
|
|
596
|
-
if (
|
|
597
|
+
if (field.schema?.is_nullable === false) {
|
|
597
598
|
if (!alter || alter.is_nullable === true) {
|
|
598
599
|
column.notNullable();
|
|
599
600
|
}
|
|
@@ -603,15 +604,15 @@ class FieldsService {
|
|
|
603
604
|
column.nullable();
|
|
604
605
|
}
|
|
605
606
|
}
|
|
606
|
-
if (
|
|
607
|
+
if (field.schema?.is_primary_key) {
|
|
607
608
|
column.primary().notNullable();
|
|
608
609
|
}
|
|
609
|
-
else if (
|
|
610
|
+
else if (field.schema?.is_unique === true) {
|
|
610
611
|
if (!alter || alter.is_unique === false) {
|
|
611
612
|
column.unique();
|
|
612
613
|
}
|
|
613
614
|
}
|
|
614
|
-
else if (
|
|
615
|
+
else if (field.schema?.is_unique === false) {
|
|
615
616
|
if (alter && alter.is_unique === true) {
|
|
616
617
|
table.dropUnique([field.field]);
|
|
617
618
|
}
|
package/dist/services/files.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Readable } from 'node:stream';
|
|
3
|
-
import { AbstractServiceOptions, File, Metadata, MutationOptions, PrimaryKey } from '../types';
|
|
3
|
+
import type { AbstractServiceOptions, File, Metadata, MutationOptions, PrimaryKey } from '../types';
|
|
4
4
|
import { ItemsService } from './items';
|
|
5
5
|
export declare class FilesService extends ItemsService {
|
|
6
6
|
constructor(options: AbstractServiceOptions);
|
|
@@ -8,7 +8,6 @@ export declare class FilesService extends ItemsService {
|
|
|
8
8
|
* Upload a single new file to the configured storage adapter
|
|
9
9
|
*/
|
|
10
10
|
uploadOne(stream: Readable, data: Partial<File> & {
|
|
11
|
-
filename_download: string;
|
|
12
11
|
storage: string;
|
|
13
12
|
}, primaryKey?: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
14
13
|
/**
|
package/dist/services/files.js
CHANGED
|
@@ -1,56 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
28
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
6
|
exports.FilesService = void 0;
|
|
30
7
|
const utils_1 = require("@directus/shared/utils");
|
|
31
|
-
const dns_1 = require("dns");
|
|
32
8
|
const encodeurl_1 = __importDefault(require("encodeurl"));
|
|
33
9
|
const exif_reader_1 = __importDefault(require("exif-reader"));
|
|
34
10
|
const icc_1 = require("icc");
|
|
35
11
|
const lodash_1 = require("lodash");
|
|
36
12
|
const mime_types_1 = require("mime-types");
|
|
37
|
-
const net_1 = __importDefault(require("net"));
|
|
38
13
|
const promises_1 = require("node:stream/promises");
|
|
39
|
-
const os_1 = __importDefault(require("os"));
|
|
40
14
|
const path_1 = __importDefault(require("path"));
|
|
41
15
|
const sharp_1 = __importDefault(require("sharp"));
|
|
42
|
-
const url_1 =
|
|
43
|
-
const util_1 = require("util");
|
|
16
|
+
const url_1 = __importDefault(require("url"));
|
|
44
17
|
const emitter_1 = __importDefault(require("../emitter"));
|
|
45
18
|
const env_1 = __importDefault(require("../env"));
|
|
46
19
|
const exceptions_1 = require("../exceptions");
|
|
47
20
|
const logger_1 = __importDefault(require("../logger"));
|
|
21
|
+
const index_1 = require("../request/index");
|
|
48
22
|
const storage_1 = require("../storage");
|
|
49
23
|
const parse_image_metadata_1 = require("../utils/parse-image-metadata");
|
|
50
24
|
const items_1 = require("./items");
|
|
51
25
|
// @ts-ignore
|
|
52
26
|
const format_title_1 = __importDefault(require("@directus/format-title"));
|
|
53
|
-
const lookupDNS = (0, util_1.promisify)(dns_1.lookup);
|
|
54
27
|
class FilesService extends items_1.ItemsService {
|
|
55
28
|
constructor(options) {
|
|
56
29
|
super('directus_files', options);
|
|
@@ -59,12 +32,20 @@ class FilesService extends items_1.ItemsService {
|
|
|
59
32
|
* Upload a single new file to the configured storage adapter
|
|
60
33
|
*/
|
|
61
34
|
async uploadOne(stream, data, primaryKey, opts) {
|
|
62
|
-
var _a, _b, _c, _d, _e, _f;
|
|
63
35
|
const storage = await (0, storage_1.getStorage)();
|
|
64
|
-
|
|
36
|
+
let existingFile = {};
|
|
37
|
+
if (primaryKey !== undefined) {
|
|
38
|
+
existingFile =
|
|
39
|
+
(await this.knex
|
|
40
|
+
.select('folder', 'filename_download')
|
|
41
|
+
.from('directus_files')
|
|
42
|
+
.where({ id: primaryKey })
|
|
43
|
+
.first()) ?? {};
|
|
44
|
+
}
|
|
45
|
+
const payload = { ...existingFile, ...(0, lodash_1.clone)(data) };
|
|
65
46
|
if ('folder' in payload === false) {
|
|
66
47
|
const settings = await this.knex.select('storage_default_folder').from('directus_settings').first();
|
|
67
|
-
if (settings
|
|
48
|
+
if (settings?.storage_default_folder) {
|
|
68
49
|
payload.folder = settings.storage_default_folder;
|
|
69
50
|
}
|
|
70
51
|
}
|
|
@@ -98,12 +79,12 @@ class FilesService extends items_1.ItemsService {
|
|
|
98
79
|
if (['image/jpeg', 'image/png', 'image/webp', 'image/gif', 'image/tiff'].includes(payload.type)) {
|
|
99
80
|
const stream = await storage.location(data.storage).read(payload.filename_disk);
|
|
100
81
|
const { height, width, description, title, tags, metadata } = await this.getMetadata(stream);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
82
|
+
payload.height = height ?? null;
|
|
83
|
+
payload.width = width ?? null;
|
|
84
|
+
payload.description = description ?? null;
|
|
85
|
+
payload.title = title ?? null;
|
|
86
|
+
payload.tags = tags ?? null;
|
|
87
|
+
payload.metadata = metadata ?? null;
|
|
107
88
|
}
|
|
108
89
|
// We do this in a service without accountability. Even if you don't have update permissions to the file,
|
|
109
90
|
// we still want to be able to set the extracted values from the file on create
|
|
@@ -112,10 +93,10 @@ class FilesService extends items_1.ItemsService {
|
|
|
112
93
|
schema: this.schema,
|
|
113
94
|
});
|
|
114
95
|
await sudoService.updateOne(primaryKey, payload, { emitEvents: false });
|
|
115
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
|
|
96
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
116
97
|
await this.cache.clear();
|
|
117
98
|
}
|
|
118
|
-
if (
|
|
99
|
+
if (opts?.emitEvents !== false) {
|
|
119
100
|
emitter_1.default.emitAction('files.upload', {
|
|
120
101
|
payload,
|
|
121
102
|
key: primaryKey,
|
|
@@ -134,9 +115,10 @@ class FilesService extends items_1.ItemsService {
|
|
|
134
115
|
async getMetadata(stream, allowList = env_1.default.FILE_METADATA_ALLOW_LIST) {
|
|
135
116
|
return new Promise((resolve, reject) => {
|
|
136
117
|
(0, promises_1.pipeline)(stream, (0, sharp_1.default)().metadata(async (err, sharpMetadata) => {
|
|
137
|
-
|
|
138
|
-
if (err)
|
|
118
|
+
if (err) {
|
|
139
119
|
reject(err);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
140
122
|
const metadata = {};
|
|
141
123
|
if (sharpMetadata.orientation && sharpMetadata.orientation >= 5) {
|
|
142
124
|
metadata.height = sharpMetadata.width;
|
|
@@ -149,37 +131,61 @@ class FilesService extends items_1.ItemsService {
|
|
|
149
131
|
// Backward-compatible layout as it used to be with 'exifr'
|
|
150
132
|
const fullMetadata = {};
|
|
151
133
|
if (sharpMetadata.exif) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
134
|
+
try {
|
|
135
|
+
const { image, thumbnail, interoperability, ...rest } = (0, exif_reader_1.default)(sharpMetadata.exif);
|
|
136
|
+
if (image) {
|
|
137
|
+
fullMetadata.ifd0 = image;
|
|
138
|
+
}
|
|
139
|
+
if (thumbnail) {
|
|
140
|
+
fullMetadata.ifd1 = thumbnail;
|
|
141
|
+
}
|
|
142
|
+
if (interoperability) {
|
|
143
|
+
fullMetadata.interop = interoperability;
|
|
144
|
+
}
|
|
145
|
+
Object.assign(fullMetadata, rest);
|
|
158
146
|
}
|
|
159
|
-
|
|
160
|
-
|
|
147
|
+
catch (err) {
|
|
148
|
+
logger_1.default.warn(`Couldn't extract EXIF metadata from file`);
|
|
149
|
+
logger_1.default.warn(err);
|
|
161
150
|
}
|
|
162
|
-
Object.assign(fullMetadata, rest);
|
|
163
151
|
}
|
|
164
152
|
if (sharpMetadata.icc) {
|
|
165
|
-
|
|
153
|
+
try {
|
|
154
|
+
fullMetadata.icc = (0, icc_1.parse)(sharpMetadata.icc);
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
logger_1.default.warn(`Couldn't extract ICC profile data from file`);
|
|
158
|
+
logger_1.default.warn(err);
|
|
159
|
+
}
|
|
166
160
|
}
|
|
167
161
|
if (sharpMetadata.iptc) {
|
|
168
|
-
|
|
162
|
+
try {
|
|
163
|
+
fullMetadata.iptc = (0, parse_image_metadata_1.parseIptc)(sharpMetadata.iptc);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
logger_1.default.warn(`Couldn't extract IPTC Photo Metadata from file`);
|
|
167
|
+
logger_1.default.warn(err);
|
|
168
|
+
}
|
|
169
169
|
}
|
|
170
170
|
if (sharpMetadata.xmp) {
|
|
171
|
-
|
|
171
|
+
try {
|
|
172
|
+
fullMetadata.xmp = (0, parse_image_metadata_1.parseXmp)(sharpMetadata.xmp);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
logger_1.default.warn(`Couldn't extract XMP data from file`);
|
|
176
|
+
logger_1.default.warn(err);
|
|
177
|
+
}
|
|
172
178
|
}
|
|
173
|
-
if (
|
|
174
|
-
metadata.description =
|
|
179
|
+
if (fullMetadata?.iptc?.Caption && typeof fullMetadata.iptc.Caption === 'string') {
|
|
180
|
+
metadata.description = fullMetadata.iptc?.Caption;
|
|
175
181
|
}
|
|
176
|
-
if (
|
|
182
|
+
if (fullMetadata?.iptc?.Headline && typeof fullMetadata.iptc.Headline === 'string') {
|
|
177
183
|
metadata.title = fullMetadata.iptc.Headline;
|
|
178
184
|
}
|
|
179
|
-
if (
|
|
185
|
+
if (fullMetadata?.iptc?.Keywords) {
|
|
180
186
|
metadata.tags = fullMetadata.iptc.Keywords;
|
|
181
187
|
}
|
|
182
|
-
if (allowList === '*' ||
|
|
188
|
+
if (allowList === '*' || allowList?.[0] === '*') {
|
|
183
189
|
metadata.metadata = fullMetadata;
|
|
184
190
|
}
|
|
185
191
|
else {
|
|
@@ -202,63 +208,19 @@ class FilesService extends items_1.ItemsService {
|
|
|
202
208
|
* Import a single file from an external URL
|
|
203
209
|
*/
|
|
204
210
|
async importOne(importURL, body) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const fileCreatePermissions = (_b = (_a = this.accountability) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.find((permission) => permission.collection === 'directus_files' && permission.action === 'create');
|
|
208
|
-
if (this.accountability && ((_c = this.accountability) === null || _c === void 0 ? void 0 : _c.admin) !== true && !fileCreatePermissions) {
|
|
211
|
+
const fileCreatePermissions = this.accountability?.permissions?.find((permission) => permission.collection === 'directus_files' && permission.action === 'create');
|
|
212
|
+
if (this.accountability && this.accountability?.admin !== true && !fileCreatePermissions) {
|
|
209
213
|
throw new exceptions_1.ForbiddenException();
|
|
210
214
|
}
|
|
211
|
-
let resolvedUrl;
|
|
212
|
-
try {
|
|
213
|
-
resolvedUrl = new url_1.URL(importURL);
|
|
214
|
-
}
|
|
215
|
-
catch (err) {
|
|
216
|
-
logger_1.default.warn(err, `Requested URL ${importURL} isn't a valid URL`);
|
|
217
|
-
throw new exceptions_1.ServiceUnavailableException(`Couldn't fetch file from url "${importURL}"`, {
|
|
218
|
-
service: 'external-file',
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
let ip = resolvedUrl.hostname;
|
|
222
|
-
if (net_1.default.isIP(ip) === 0) {
|
|
223
|
-
try {
|
|
224
|
-
ip = (await lookupDNS(ip)).address;
|
|
225
|
-
}
|
|
226
|
-
catch (err) {
|
|
227
|
-
logger_1.default.warn(err, `Couldn't lookup the DNS for url ${importURL}`);
|
|
228
|
-
throw new exceptions_1.ServiceUnavailableException(`Couldn't fetch file from url "${importURL}"`, {
|
|
229
|
-
service: 'external-file',
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (env_1.default.IMPORT_IP_DENY_LIST.includes('0.0.0.0')) {
|
|
234
|
-
const networkInterfaces = os_1.default.networkInterfaces();
|
|
235
|
-
for (const networkInfo of Object.values(networkInterfaces)) {
|
|
236
|
-
if (!networkInfo)
|
|
237
|
-
continue;
|
|
238
|
-
for (const info of networkInfo) {
|
|
239
|
-
if (info.address === ip) {
|
|
240
|
-
logger_1.default.warn(`Requested URL ${importURL} resolves to localhost.`);
|
|
241
|
-
throw new exceptions_1.ServiceUnavailableException(`Couldn't fetch file from url "${importURL}"`, {
|
|
242
|
-
service: 'external-file',
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (env_1.default.IMPORT_IP_DENY_LIST.includes(ip)) {
|
|
249
|
-
logger_1.default.warn(`Requested URL ${importURL} resolves to a denied IP address.`);
|
|
250
|
-
throw new exceptions_1.ServiceUnavailableException(`Couldn't fetch file from url "${importURL}"`, {
|
|
251
|
-
service: 'external-file',
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
215
|
let fileResponse;
|
|
255
216
|
try {
|
|
217
|
+
const axios = await (0, index_1.getAxios)();
|
|
256
218
|
fileResponse = await axios.get((0, encodeurl_1.default)(importURL), {
|
|
257
219
|
responseType: 'stream',
|
|
258
220
|
});
|
|
259
221
|
}
|
|
260
222
|
catch (err) {
|
|
261
|
-
logger_1.default.warn(err, `Couldn't fetch file from
|
|
223
|
+
logger_1.default.warn(err, `Couldn't fetch file from URL "${importURL}"`);
|
|
262
224
|
throw new exceptions_1.ServiceUnavailableException(`Couldn't fetch file from url "${importURL}"`, {
|
|
263
225
|
service: 'external-file',
|
|
264
226
|
});
|
|
@@ -309,7 +271,7 @@ class FilesService extends items_1.ItemsService {
|
|
|
309
271
|
await disk.delete(filepath);
|
|
310
272
|
}
|
|
311
273
|
}
|
|
312
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE &&
|
|
274
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && opts?.autoPurgeCache !== false) {
|
|
313
275
|
await this.cache.clear();
|
|
314
276
|
}
|
|
315
277
|
return keys;
|
package/dist/services/flows.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FlowRaw } from '@directus/shared/types';
|
|
2
|
-
import { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
1
|
+
import type { FlowRaw } from '@directus/shared/types';
|
|
2
|
+
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
3
3
|
import { ItemsService } from './items';
|
|
4
4
|
export declare class FlowsService extends ItemsService<FlowRaw> {
|
|
5
5
|
constructor(options: AbstractServiceOptions);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { BaseException } from '@directus/shared/exceptions';
|
|
1
|
+
import type { BaseException } from '@directus/shared/exceptions';
|
|
2
2
|
import { Accountability, Filter, Query, SchemaOverview } from '@directus/shared/types';
|
|
3
3
|
import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLSchema, SelectionNode } from 'graphql';
|
|
4
4
|
import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
|
|
5
|
-
import { Knex } from 'knex';
|
|
6
|
-
import { AbstractServiceOptions, GraphQLParams, Item } from '../../types';
|
|
5
|
+
import type { Knex } from 'knex';
|
|
6
|
+
import type { AbstractServiceOptions, GraphQLParams, Item } from '../../types';
|
|
7
7
|
import { ItemsService } from '../items';
|
|
8
8
|
export declare class GraphQLService {
|
|
9
9
|
accountability: Accountability | null;
|
|
@@ -57,7 +57,7 @@ export declare class GraphQLService {
|
|
|
57
57
|
/**
|
|
58
58
|
* Replace functions from GraphQL format to Directus-Filter format
|
|
59
59
|
*/
|
|
60
|
-
replaceFuncs(filter
|
|
60
|
+
replaceFuncs(filter: Filter): Filter;
|
|
61
61
|
/**
|
|
62
62
|
* Convert Directus-Exception into a GraphQL format, so it can be returned by GraphQL properly.
|
|
63
63
|
*/
|