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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const utils_1 = require("@directus/shared/utils");
|
|
7
|
+
const busboy_1 = __importDefault(require("busboy"));
|
|
8
|
+
const express_1 = __importDefault(require("express"));
|
|
9
|
+
const js_yaml_1 = require("js-yaml");
|
|
10
|
+
const exceptions_1 = require("../exceptions");
|
|
11
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
12
|
+
const respond_1 = require("../middleware/respond");
|
|
13
|
+
const schema_1 = require("../services/schema");
|
|
14
|
+
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
15
|
+
const get_versioned_hash_1 = require("../utils/get-versioned-hash");
|
|
16
|
+
const router = express_1.default.Router();
|
|
17
|
+
router.get('/snapshot', (0, async_handler_1.default)(async (req, res, next) => {
|
|
18
|
+
const service = new schema_1.SchemaService({ accountability: req.accountability });
|
|
19
|
+
const currentSnapshot = await service.snapshot();
|
|
20
|
+
res.locals.payload = { data: currentSnapshot };
|
|
21
|
+
return next();
|
|
22
|
+
}), respond_1.respond);
|
|
23
|
+
router.post('/apply', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
24
|
+
const service = new schema_1.SchemaService({ accountability: req.accountability });
|
|
25
|
+
await service.apply(req.body);
|
|
26
|
+
return next();
|
|
27
|
+
}), respond_1.respond);
|
|
28
|
+
const schemaMultipartHandler = (req, res, next) => {
|
|
29
|
+
if (req.is('application/json')) {
|
|
30
|
+
if (Object.keys(req.body).length === 0)
|
|
31
|
+
throw new exceptions_1.InvalidPayloadException(`No data was included in the body`);
|
|
32
|
+
res.locals.uploadedSnapshot = req.body;
|
|
33
|
+
return next();
|
|
34
|
+
}
|
|
35
|
+
if (!req.is('multipart/form-data'))
|
|
36
|
+
throw new exceptions_1.UnsupportedMediaTypeException(`Unsupported Content-Type header`);
|
|
37
|
+
const headers = req.headers['content-type']
|
|
38
|
+
? req.headers
|
|
39
|
+
: {
|
|
40
|
+
...req.headers,
|
|
41
|
+
'content-type': 'application/octet-stream',
|
|
42
|
+
};
|
|
43
|
+
const busboy = (0, busboy_1.default)({ headers });
|
|
44
|
+
let isFileIncluded = false;
|
|
45
|
+
let uploadedSnapshot = null;
|
|
46
|
+
busboy.on('file', async (_, fileStream, { mimeType }) => {
|
|
47
|
+
if (isFileIncluded)
|
|
48
|
+
return next(new exceptions_1.InvalidPayloadException(`More than one file was included in the body`));
|
|
49
|
+
isFileIncluded = true;
|
|
50
|
+
const { readableStreamToString } = await import('@directus/utils/node');
|
|
51
|
+
try {
|
|
52
|
+
const uploadedString = await readableStreamToString(fileStream);
|
|
53
|
+
if (mimeType === 'application/json') {
|
|
54
|
+
try {
|
|
55
|
+
uploadedSnapshot = (0, utils_1.parseJSON)(uploadedString);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
logger_1.default.warn(err);
|
|
59
|
+
throw new exceptions_1.InvalidPayloadException('Invalid JSON schema snapshot');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
try {
|
|
64
|
+
uploadedSnapshot = (await (0, js_yaml_1.load)(uploadedString));
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
logger_1.default.warn(err);
|
|
68
|
+
throw new exceptions_1.InvalidPayloadException('Invalid YAML schema snapshot');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!uploadedSnapshot)
|
|
72
|
+
throw new exceptions_1.InvalidPayloadException(`No file was included in the body`);
|
|
73
|
+
res.locals.uploadedSnapshot = uploadedSnapshot;
|
|
74
|
+
return next();
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
busboy.emit('error', error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
busboy.on('error', (error) => next(error));
|
|
81
|
+
busboy.on('close', () => {
|
|
82
|
+
if (!isFileIncluded)
|
|
83
|
+
return next(new exceptions_1.InvalidPayloadException(`No file was included in the body`));
|
|
84
|
+
});
|
|
85
|
+
req.pipe(busboy);
|
|
86
|
+
};
|
|
87
|
+
router.post('/diff', (0, async_handler_1.default)(schemaMultipartHandler), (0, async_handler_1.default)(async (req, res, next) => {
|
|
88
|
+
const service = new schema_1.SchemaService({ accountability: req.accountability });
|
|
89
|
+
const snapshot = res.locals.uploadedSnapshot;
|
|
90
|
+
const currentSnapshot = await service.snapshot();
|
|
91
|
+
const snapshotDiff = await service.diff(snapshot, { currentSnapshot, force: 'force' in req.query });
|
|
92
|
+
if (!snapshotDiff)
|
|
93
|
+
return next();
|
|
94
|
+
const currentSnapshotHash = (0, get_versioned_hash_1.getVersionedHash)(currentSnapshot);
|
|
95
|
+
res.locals.payload = { data: { hash: currentSnapshotHash, diff: snapshotDiff } };
|
|
96
|
+
return next();
|
|
97
|
+
}), respond_1.respond);
|
|
98
|
+
exports.default = router;
|
|
@@ -4,15 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const express_1 = __importDefault(require("express"));
|
|
7
|
+
const joi_1 = __importDefault(require("joi"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const env_1 = __importDefault(require("../env"));
|
|
7
10
|
const exceptions_1 = require("../exceptions");
|
|
8
11
|
const respond_1 = require("../middleware/respond");
|
|
9
12
|
const use_collection_1 = __importDefault(require("../middleware/use-collection"));
|
|
10
13
|
const validate_batch_1 = require("../middleware/validate-batch");
|
|
11
14
|
const services_1 = require("../services");
|
|
12
15
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
13
|
-
const
|
|
14
|
-
const joi_1 = __importDefault(require("joi"));
|
|
15
|
-
const env_1 = __importDefault(require("../env"));
|
|
16
|
+
const sanitize_query_1 = require("../utils/sanitize-query");
|
|
16
17
|
const router = express_1.default.Router();
|
|
17
18
|
router.use((0, use_collection_1.default)('directus_shares'));
|
|
18
19
|
const sharedLoginSchema = joi_1.default.object({
|
|
@@ -156,7 +157,8 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
156
157
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
157
158
|
}
|
|
158
159
|
else {
|
|
159
|
-
|
|
160
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
161
|
+
keys = await service.updateByQuery(sanitizedQuery, req.body.data);
|
|
160
162
|
}
|
|
161
163
|
try {
|
|
162
164
|
const result = await service.readMany(keys, req.sanitizedQuery);
|
|
@@ -200,7 +202,8 @@ router.delete('/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
|
200
202
|
await service.deleteMany(req.body.keys);
|
|
201
203
|
}
|
|
202
204
|
else {
|
|
203
|
-
|
|
205
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
206
|
+
await service.deleteByQuery(sanitizedQuery);
|
|
204
207
|
}
|
|
205
208
|
return next();
|
|
206
209
|
}), respond_1.respond);
|
|
@@ -11,6 +11,7 @@ const use_collection_1 = __importDefault(require("../middleware/use-collection")
|
|
|
11
11
|
const validate_batch_1 = require("../middleware/validate-batch");
|
|
12
12
|
const services_1 = require("../services");
|
|
13
13
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
14
|
+
const sanitize_query_1 = require("../utils/sanitize-query");
|
|
14
15
|
const router = express_1.default.Router();
|
|
15
16
|
router.use((0, use_collection_1.default)('directus_users'));
|
|
16
17
|
router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -62,10 +63,9 @@ const readHandler = (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
62
63
|
router.get('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
|
|
63
64
|
router.search('/', (0, validate_batch_1.validateBatch)('read'), readHandler, respond_1.respond);
|
|
64
65
|
router.get('/me', (0, async_handler_1.default)(async (req, res, next) => {
|
|
65
|
-
|
|
66
|
-
if ((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.share_scope) {
|
|
66
|
+
if (req.accountability?.share_scope) {
|
|
67
67
|
const user = {
|
|
68
|
-
share:
|
|
68
|
+
share: req.accountability?.share,
|
|
69
69
|
role: {
|
|
70
70
|
id: req.accountability.role,
|
|
71
71
|
admin_access: false,
|
|
@@ -75,7 +75,7 @@ router.get('/me', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
75
75
|
res.locals.payload = { data: user };
|
|
76
76
|
return next();
|
|
77
77
|
}
|
|
78
|
-
if (!
|
|
78
|
+
if (!req.accountability?.user) {
|
|
79
79
|
throw new exceptions_1.InvalidCredentialsException();
|
|
80
80
|
}
|
|
81
81
|
const service = new services_1.UsersService({
|
|
@@ -107,8 +107,7 @@ router.get('/:pk', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
107
107
|
return next();
|
|
108
108
|
}), respond_1.respond);
|
|
109
109
|
router.patch('/me', (0, async_handler_1.default)(async (req, res, next) => {
|
|
110
|
-
|
|
111
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
110
|
+
if (!req.accountability?.user) {
|
|
112
111
|
throw new exceptions_1.InvalidCredentialsException();
|
|
113
112
|
}
|
|
114
113
|
const service = new services_1.UsersService({
|
|
@@ -121,8 +120,7 @@ router.patch('/me', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
121
120
|
return next();
|
|
122
121
|
}), respond_1.respond);
|
|
123
122
|
router.patch('/me/track/page', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
124
|
-
|
|
125
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
123
|
+
if (!req.accountability?.user) {
|
|
126
124
|
throw new exceptions_1.InvalidCredentialsException();
|
|
127
125
|
}
|
|
128
126
|
if (!req.body.last_page) {
|
|
@@ -145,7 +143,8 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
145
143
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
146
144
|
}
|
|
147
145
|
else {
|
|
148
|
-
|
|
146
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
147
|
+
keys = await service.updateByQuery(sanitizedQuery, req.body.data);
|
|
149
148
|
}
|
|
150
149
|
try {
|
|
151
150
|
const result = await service.readMany(keys, req.sanitizedQuery);
|
|
@@ -189,7 +188,8 @@ router.delete('/', (0, validate_batch_1.validateBatch)('delete'), (0, async_hand
|
|
|
189
188
|
await service.deleteMany(req.body.keys);
|
|
190
189
|
}
|
|
191
190
|
else {
|
|
192
|
-
|
|
191
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
192
|
+
await service.deleteByQuery(sanitizedQuery);
|
|
193
193
|
}
|
|
194
194
|
return next();
|
|
195
195
|
}), respond_1.respond);
|
|
@@ -233,8 +233,7 @@ router.post('/invite/accept', (0, async_handler_1.default)(async (req, _res, nex
|
|
|
233
233
|
return next();
|
|
234
234
|
}), respond_1.respond);
|
|
235
235
|
router.post('/me/tfa/generate/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
236
|
-
|
|
237
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
236
|
+
if (!req.accountability?.user) {
|
|
238
237
|
throw new exceptions_1.InvalidCredentialsException();
|
|
239
238
|
}
|
|
240
239
|
if (!req.body.password) {
|
|
@@ -254,8 +253,7 @@ router.post('/me/tfa/generate/', (0, async_handler_1.default)(async (req, res, n
|
|
|
254
253
|
return next();
|
|
255
254
|
}), respond_1.respond);
|
|
256
255
|
router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
257
|
-
|
|
258
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
256
|
+
if (!req.accountability?.user) {
|
|
259
257
|
throw new exceptions_1.InvalidCredentialsException();
|
|
260
258
|
}
|
|
261
259
|
if (!req.body.secret) {
|
|
@@ -271,7 +269,7 @@ router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
271
269
|
});
|
|
272
270
|
const role = (await rolesService.readOne(req.accountability.role));
|
|
273
271
|
if (role && role.enforce_tfa) {
|
|
274
|
-
const existingPermission = await
|
|
272
|
+
const existingPermission = await req.accountability.permissions?.find((p) => p.collection === 'directus_users' && p.action === 'update');
|
|
275
273
|
if (existingPermission) {
|
|
276
274
|
existingPermission.fields = ['tfa_secret'];
|
|
277
275
|
existingPermission.permissions = { id: { _eq: req.accountability.user } };
|
|
@@ -299,8 +297,7 @@ router.post('/me/tfa/enable/', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
299
297
|
return next();
|
|
300
298
|
}), respond_1.respond);
|
|
301
299
|
router.post('/me/tfa/disable', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
302
|
-
|
|
303
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
300
|
+
if (!req.accountability?.user) {
|
|
304
301
|
throw new exceptions_1.InvalidCredentialsException();
|
|
305
302
|
}
|
|
306
303
|
if (!req.body.otp) {
|
|
@@ -313,7 +310,7 @@ router.post('/me/tfa/disable', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
313
310
|
});
|
|
314
311
|
const role = (await rolesService.readOne(req.accountability.role));
|
|
315
312
|
if (role && role.enforce_tfa) {
|
|
316
|
-
const existingPermission = await
|
|
313
|
+
const existingPermission = await req.accountability.permissions?.find((p) => p.collection === 'directus_users' && p.action === 'update');
|
|
317
314
|
if (existingPermission) {
|
|
318
315
|
existingPermission.fields = ['tfa_secret'];
|
|
319
316
|
existingPermission.permissions = { id: { _eq: req.accountability.user } };
|
|
@@ -345,8 +342,7 @@ router.post('/me/tfa/disable', (0, async_handler_1.default)(async (req, _res, ne
|
|
|
345
342
|
return next();
|
|
346
343
|
}), respond_1.respond);
|
|
347
344
|
router.post('/:pk/tfa/disable', (0, async_handler_1.default)(async (req, _res, next) => {
|
|
348
|
-
|
|
349
|
-
if (!((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.user)) {
|
|
345
|
+
if (!req.accountability?.user) {
|
|
350
346
|
throw new exceptions_1.InvalidCredentialsException();
|
|
351
347
|
}
|
|
352
348
|
if (!req.accountability.admin || !req.params.pk) {
|
|
@@ -17,27 +17,24 @@ const generate_hash_1 = require("../utils/generate-hash");
|
|
|
17
17
|
const sanitize_query_1 = require("../utils/sanitize-query");
|
|
18
18
|
const router = (0, express_1.Router)();
|
|
19
19
|
router.get('/random/string', (0, async_handler_1.default)(async (req, res) => {
|
|
20
|
-
var _a;
|
|
21
20
|
const { nanoid } = await import('nanoid');
|
|
22
21
|
if (req.query && req.query.length && Number(req.query.length) > 500)
|
|
23
22
|
throw new exceptions_1.InvalidQueryException(`"length" can't be more than 500 characters`);
|
|
24
|
-
const string = nanoid(
|
|
23
|
+
const string = nanoid(req.query?.length ? Number(req.query.length) : 32);
|
|
25
24
|
return res.json({ data: string });
|
|
26
25
|
}));
|
|
27
26
|
router.post('/hash/generate', (0, async_handler_1.default)(async (req, res) => {
|
|
28
|
-
|
|
29
|
-
if (!((_a = req.body) === null || _a === void 0 ? void 0 : _a.string)) {
|
|
27
|
+
if (!req.body?.string) {
|
|
30
28
|
throw new exceptions_1.InvalidPayloadException(`"string" is required`);
|
|
31
29
|
}
|
|
32
30
|
const hash = await (0, generate_hash_1.generateHash)(req.body.string);
|
|
33
31
|
return res.json({ data: hash });
|
|
34
32
|
}));
|
|
35
33
|
router.post('/hash/verify', (0, async_handler_1.default)(async (req, res) => {
|
|
36
|
-
|
|
37
|
-
if (!((_a = req.body) === null || _a === void 0 ? void 0 : _a.string)) {
|
|
34
|
+
if (!req.body?.string) {
|
|
38
35
|
throw new exceptions_1.InvalidPayloadException(`"string" is required`);
|
|
39
36
|
}
|
|
40
|
-
if (!
|
|
37
|
+
if (!req.body?.hash) {
|
|
41
38
|
throw new exceptions_1.InvalidPayloadException(`"hash" is required`);
|
|
42
39
|
}
|
|
43
40
|
const result = await argon2_1.default.verify(req.body.hash, req.body.string);
|
|
@@ -97,7 +94,6 @@ router.post('/import/:collection', collection_exists_1.default, (0, async_handle
|
|
|
97
94
|
req.pipe(busboy);
|
|
98
95
|
}));
|
|
99
96
|
router.post('/export/:collection', collection_exists_1.default, (0, async_handler_1.default)(async (req, res, next) => {
|
|
100
|
-
var _a;
|
|
101
97
|
if (!req.body.query) {
|
|
102
98
|
throw new exceptions_1.InvalidPayloadException(`"query" is required.`);
|
|
103
99
|
}
|
|
@@ -108,7 +104,7 @@ router.post('/export/:collection', collection_exists_1.default, (0, async_handle
|
|
|
108
104
|
accountability: req.accountability,
|
|
109
105
|
schema: req.schema,
|
|
110
106
|
});
|
|
111
|
-
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query,
|
|
107
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability ?? null);
|
|
112
108
|
// We're not awaiting this, as it's supposed to run async in the background
|
|
113
109
|
service.exportToFile(req.params.collection, sanitizedQuery, req.body.format, {
|
|
114
110
|
file: req.body.file,
|
|
@@ -116,8 +112,7 @@ router.post('/export/:collection', collection_exists_1.default, (0, async_handle
|
|
|
116
112
|
return next();
|
|
117
113
|
}), respond_1.respond);
|
|
118
114
|
router.post('/cache/clear', (0, async_handler_1.default)(async (req, res) => {
|
|
119
|
-
|
|
120
|
-
if (((_a = req.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
115
|
+
if (req.accountability?.admin !== true) {
|
|
121
116
|
throw new exceptions_1.ForbiddenException();
|
|
122
117
|
}
|
|
123
118
|
await (0, cache_1.flushCaches)(true);
|
|
@@ -10,6 +10,7 @@ const use_collection_1 = __importDefault(require("../middleware/use-collection")
|
|
|
10
10
|
const validate_batch_1 = require("../middleware/validate-batch");
|
|
11
11
|
const services_1 = require("../services");
|
|
12
12
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
13
|
+
const sanitize_query_1 = require("../utils/sanitize-query");
|
|
13
14
|
const router = express_1.default.Router();
|
|
14
15
|
router.use((0, use_collection_1.default)('directus_webhooks'));
|
|
15
16
|
router.post('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
@@ -79,7 +80,8 @@ router.patch('/', (0, validate_batch_1.validateBatch)('update'), (0, async_handl
|
|
|
79
80
|
keys = await service.updateMany(req.body.keys, req.body.data);
|
|
80
81
|
}
|
|
81
82
|
else {
|
|
82
|
-
|
|
83
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
84
|
+
keys = await service.updateByQuery(sanitizedQuery, req.body.data);
|
|
83
85
|
}
|
|
84
86
|
try {
|
|
85
87
|
const result = await service.readMany(keys, req.sanitizedQuery);
|
|
@@ -123,7 +125,8 @@ router.delete('/', (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
123
125
|
await service.deleteMany(req.body.keys);
|
|
124
126
|
}
|
|
125
127
|
else {
|
|
126
|
-
|
|
128
|
+
const sanitizedQuery = (0, sanitize_query_1.sanitizeQuery)(req.body.query, req.accountability);
|
|
129
|
+
await service.deleteByQuery(sanitizedQuery);
|
|
127
130
|
}
|
|
128
131
|
return next();
|
|
129
132
|
}), respond_1.respond);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
1
2
|
import { FnHelper, FnHelperOptions } from '../types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
3
|
export declare class FnHelperMSSQL extends FnHelper {
|
|
4
4
|
year(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
5
5
|
month(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
@@ -10,33 +10,32 @@ const parseLocaltime = (columnType) => {
|
|
|
10
10
|
};
|
|
11
11
|
class FnHelperMSSQL extends types_1.FnHelper {
|
|
12
12
|
year(table, column, options) {
|
|
13
|
-
return this.knex.raw(`DATEPART(year, ??.??${parseLocaltime(options
|
|
13
|
+
return this.knex.raw(`DATEPART(year, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
14
14
|
}
|
|
15
15
|
month(table, column, options) {
|
|
16
|
-
return this.knex.raw(`DATEPART(month, ??.??${parseLocaltime(options
|
|
16
|
+
return this.knex.raw(`DATEPART(month, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
17
17
|
}
|
|
18
18
|
week(table, column, options) {
|
|
19
|
-
return this.knex.raw(`DATEPART(week, ??.??${parseLocaltime(options
|
|
19
|
+
return this.knex.raw(`DATEPART(week, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
20
20
|
}
|
|
21
21
|
day(table, column, options) {
|
|
22
|
-
return this.knex.raw(`DATEPART(day, ??.??${parseLocaltime(options
|
|
22
|
+
return this.knex.raw(`DATEPART(day, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
23
23
|
}
|
|
24
24
|
weekday(table, column, options) {
|
|
25
|
-
return this.knex.raw(`DATEPART(weekday, ??.??${parseLocaltime(options
|
|
25
|
+
return this.knex.raw(`DATEPART(weekday, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
26
26
|
}
|
|
27
27
|
hour(table, column, options) {
|
|
28
|
-
return this.knex.raw(`DATEPART(hour, ??.??${parseLocaltime(options
|
|
28
|
+
return this.knex.raw(`DATEPART(hour, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
29
29
|
}
|
|
30
30
|
minute(table, column, options) {
|
|
31
|
-
return this.knex.raw(`DATEPART(minute, ??.??${parseLocaltime(options
|
|
31
|
+
return this.knex.raw(`DATEPART(minute, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
32
32
|
}
|
|
33
33
|
second(table, column, options) {
|
|
34
|
-
return this.knex.raw(`DATEPART(second, ??.??${parseLocaltime(options
|
|
34
|
+
return this.knex.raw(`DATEPART(second, ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
35
35
|
}
|
|
36
36
|
count(table, column, options) {
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[collectionName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
|
|
37
|
+
const collectionName = options?.originalCollectionName || table;
|
|
38
|
+
const type = this.schema.collections?.[collectionName]?.fields?.[column]?.type ?? 'unknown';
|
|
40
39
|
if (type === 'json') {
|
|
41
40
|
return this.knex.raw(`(SELECT COUNT(*) FROM OPENJSON(??.??, '$'))`, [table, column]);
|
|
42
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
1
2
|
import { FnHelper, FnHelperOptions } from '../types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
3
|
export declare class FnHelperMySQL extends FnHelper {
|
|
4
4
|
year(table: string, column: string): Knex.Raw;
|
|
5
5
|
month(table: string, column: string): Knex.Raw;
|
|
@@ -28,9 +28,8 @@ class FnHelperMySQL extends types_1.FnHelper {
|
|
|
28
28
|
return this.knex.raw('SECOND(??.??)', [table, column]);
|
|
29
29
|
}
|
|
30
30
|
count(table, column, options) {
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[collectionName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
|
|
31
|
+
const collectionName = options?.originalCollectionName || table;
|
|
32
|
+
const type = this.schema.collections?.[collectionName]?.fields?.[column]?.type ?? 'unknown';
|
|
34
33
|
if (type === 'json') {
|
|
35
34
|
return this.knex.raw('JSON_LENGTH(??.??)', [table, column]);
|
|
36
35
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
1
2
|
import { FnHelper, FnHelperOptions } from '../types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
3
|
export declare class FnHelperOracle extends FnHelper {
|
|
4
4
|
year(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
5
5
|
month(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
@@ -10,33 +10,32 @@ const parseLocaltime = (columnType) => {
|
|
|
10
10
|
};
|
|
11
11
|
class FnHelperOracle extends types_1.FnHelper {
|
|
12
12
|
year(table, column, options) {
|
|
13
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
13
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'IYYY')`, [table, column]);
|
|
14
14
|
}
|
|
15
15
|
month(table, column, options) {
|
|
16
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
16
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'MM')`, [table, column]);
|
|
17
17
|
}
|
|
18
18
|
week(table, column, options) {
|
|
19
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
19
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'IW')`, [table, column]);
|
|
20
20
|
}
|
|
21
21
|
day(table, column, options) {
|
|
22
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
22
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'DD')`, [table, column]);
|
|
23
23
|
}
|
|
24
24
|
weekday(table, column, options) {
|
|
25
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
25
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'D')`, [table, column]);
|
|
26
26
|
}
|
|
27
27
|
hour(table, column, options) {
|
|
28
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
28
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'HH24')`, [table, column]);
|
|
29
29
|
}
|
|
30
30
|
minute(table, column, options) {
|
|
31
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
31
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'MI')`, [table, column]);
|
|
32
32
|
}
|
|
33
33
|
second(table, column, options) {
|
|
34
|
-
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options
|
|
34
|
+
return this.knex.raw(`TO_CHAR(??.??${parseLocaltime(options?.type)}, 'SS')`, [table, column]);
|
|
35
35
|
}
|
|
36
36
|
count(table, column, options) {
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[collectionName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
|
|
37
|
+
const collectionName = options?.originalCollectionName || table;
|
|
38
|
+
const type = this.schema.collections?.[collectionName]?.fields?.[column]?.type ?? 'unknown';
|
|
40
39
|
if (type === 'json') {
|
|
41
40
|
return this.knex.raw("json_value(??.??, '$.size()')", [table, column]);
|
|
42
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
1
2
|
import { FnHelper, FnHelperOptions } from '../types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
3
|
export declare class FnHelperPostgres extends FnHelper {
|
|
4
4
|
year(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
5
5
|
month(table: string, column: string, options: FnHelperOptions): Knex.Raw;
|
|
@@ -10,33 +10,32 @@ const parseLocaltime = (columnType) => {
|
|
|
10
10
|
};
|
|
11
11
|
class FnHelperPostgres extends types_1.FnHelper {
|
|
12
12
|
year(table, column, options) {
|
|
13
|
-
return this.knex.raw(`EXTRACT(YEAR FROM ??.??${parseLocaltime(options
|
|
13
|
+
return this.knex.raw(`EXTRACT(YEAR FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
14
14
|
}
|
|
15
15
|
month(table, column, options) {
|
|
16
|
-
return this.knex.raw(`EXTRACT(MONTH FROM ??.??${parseLocaltime(options
|
|
16
|
+
return this.knex.raw(`EXTRACT(MONTH FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
17
17
|
}
|
|
18
18
|
week(table, column, options) {
|
|
19
|
-
return this.knex.raw(`EXTRACT(WEEK FROM ??.??${parseLocaltime(options
|
|
19
|
+
return this.knex.raw(`EXTRACT(WEEK FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
20
20
|
}
|
|
21
21
|
day(table, column, options) {
|
|
22
|
-
return this.knex.raw(`EXTRACT(DAY FROM ??.??${parseLocaltime(options
|
|
22
|
+
return this.knex.raw(`EXTRACT(DAY FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
23
23
|
}
|
|
24
24
|
weekday(table, column, options) {
|
|
25
|
-
return this.knex.raw(`EXTRACT(DOW FROM ??.??${parseLocaltime(options
|
|
25
|
+
return this.knex.raw(`EXTRACT(DOW FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
26
26
|
}
|
|
27
27
|
hour(table, column, options) {
|
|
28
|
-
return this.knex.raw(`EXTRACT(HOUR FROM ??.??${parseLocaltime(options
|
|
28
|
+
return this.knex.raw(`EXTRACT(HOUR FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
29
29
|
}
|
|
30
30
|
minute(table, column, options) {
|
|
31
|
-
return this.knex.raw(`EXTRACT(MINUTE FROM ??.??${parseLocaltime(options
|
|
31
|
+
return this.knex.raw(`EXTRACT(MINUTE FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
32
32
|
}
|
|
33
33
|
second(table, column, options) {
|
|
34
|
-
return this.knex.raw(`EXTRACT(SECOND FROM ??.??${parseLocaltime(options
|
|
34
|
+
return this.knex.raw(`EXTRACT(SECOND FROM ??.??${parseLocaltime(options?.type)})`, [table, column]);
|
|
35
35
|
}
|
|
36
36
|
count(table, column, options) {
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[collectionName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
|
|
37
|
+
const collectionName = options?.originalCollectionName || table;
|
|
38
|
+
const type = this.schema.collections?.[collectionName]?.fields?.[column]?.type ?? 'unknown';
|
|
40
39
|
if (type === 'json') {
|
|
41
40
|
const { dbType } = this.schema.collections[table].fields[column];
|
|
42
41
|
return this.knex.raw(dbType === 'jsonb' ? 'jsonb_array_length(??.??)' : 'json_array_length(??.??)', [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
1
2
|
import { FnHelper, FnHelperOptions } from '../types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
3
|
export declare class FnHelperSQLite extends FnHelper {
|
|
4
4
|
year(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
|
|
5
5
|
month(table: string, column: string, options?: FnHelperOptions): Knex.Raw;
|
|
@@ -10,57 +10,56 @@ const parseLocaltime = (columnType) => {
|
|
|
10
10
|
};
|
|
11
11
|
class FnHelperSQLite extends types_1.FnHelper {
|
|
12
12
|
year(table, column, options) {
|
|
13
|
-
return this.knex.raw(`CAST(strftime('%Y', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
13
|
+
return this.knex.raw(`CAST(strftime('%Y', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
14
14
|
table,
|
|
15
15
|
column,
|
|
16
16
|
]);
|
|
17
17
|
}
|
|
18
18
|
month(table, column, options) {
|
|
19
|
-
return this.knex.raw(`CAST(strftime('%m', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
19
|
+
return this.knex.raw(`CAST(strftime('%m', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
20
20
|
table,
|
|
21
21
|
column,
|
|
22
22
|
]);
|
|
23
23
|
}
|
|
24
24
|
week(table, column, options) {
|
|
25
|
-
return this.knex.raw(`CAST(strftime('%W', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
25
|
+
return this.knex.raw(`CAST(strftime('%W', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
26
26
|
table,
|
|
27
27
|
column,
|
|
28
28
|
]);
|
|
29
29
|
}
|
|
30
30
|
day(table, column, options) {
|
|
31
|
-
return this.knex.raw(`CAST(strftime('%d', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
31
|
+
return this.knex.raw(`CAST(strftime('%d', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
32
32
|
table,
|
|
33
33
|
column,
|
|
34
34
|
]);
|
|
35
35
|
}
|
|
36
36
|
weekday(table, column, options) {
|
|
37
|
-
return this.knex.raw(`CAST(strftime('%w', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
37
|
+
return this.knex.raw(`CAST(strftime('%w', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
38
38
|
table,
|
|
39
39
|
column,
|
|
40
40
|
]);
|
|
41
41
|
}
|
|
42
42
|
hour(table, column, options) {
|
|
43
|
-
return this.knex.raw(`CAST(strftime('%H', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
43
|
+
return this.knex.raw(`CAST(strftime('%H', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
44
44
|
table,
|
|
45
45
|
column,
|
|
46
46
|
]);
|
|
47
47
|
}
|
|
48
48
|
minute(table, column, options) {
|
|
49
|
-
return this.knex.raw(`CAST(strftime('%M', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
49
|
+
return this.knex.raw(`CAST(strftime('%M', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
50
50
|
table,
|
|
51
51
|
column,
|
|
52
52
|
]);
|
|
53
53
|
}
|
|
54
54
|
second(table, column, options) {
|
|
55
|
-
return this.knex.raw(`CAST(strftime('%S', ??.?? / 1000, 'unixepoch'${parseLocaltime(options
|
|
55
|
+
return this.knex.raw(`CAST(strftime('%S', ??.?? / 1000, 'unixepoch'${parseLocaltime(options?.type)}) AS INTEGER)`, [
|
|
56
56
|
table,
|
|
57
57
|
column,
|
|
58
58
|
]);
|
|
59
59
|
}
|
|
60
60
|
count(table, column, options) {
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const type = (_e = (_d = (_c = (_b = (_a = this.schema.collections) === null || _a === void 0 ? void 0 : _a[collectionName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[column]) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : 'unknown';
|
|
61
|
+
const collectionName = options?.originalCollectionName || table;
|
|
62
|
+
const type = this.schema.collections?.[collectionName]?.fields?.[column]?.type ?? 'unknown';
|
|
64
63
|
if (type === 'json') {
|
|
65
64
|
return this.knex.raw(`json_array_length(??.??, '$')`, [table, column]);
|
|
66
65
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Query, SchemaOverview } from '@directus/shared/types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
1
|
+
import type { Query, SchemaOverview } from '@directus/shared/types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
3
|
import { DatabaseHelper } from '../types';
|
|
4
4
|
export type FnHelperOptions = {
|
|
5
|
-
type
|
|
6
|
-
query
|
|
7
|
-
originalCollectionName
|
|
5
|
+
type: string | undefined;
|
|
6
|
+
query: Query | undefined;
|
|
7
|
+
originalCollectionName: string | undefined;
|
|
8
8
|
};
|
|
9
9
|
export declare abstract class FnHelper extends DatabaseHelper {
|
|
10
10
|
protected knex: Knex;
|