@directus/api 13.1.1 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__utils__/snapshots.js +9 -0
- package/dist/app.js +6 -4
- package/dist/auth/drivers/ldap.js +3 -2
- package/dist/auth/drivers/local.js +1 -1
- package/dist/auth/drivers/oauth2.js +1 -1
- package/dist/auth/drivers/openid.js +1 -1
- package/dist/auth/drivers/saml.js +1 -1
- package/dist/auth.js +1 -1
- package/dist/cli/index.js +7 -4
- package/dist/controllers/activity.js +1 -1
- package/dist/controllers/assets.js +2 -2
- package/dist/controllers/auth.js +1 -1
- package/dist/controllers/collections.js +1 -1
- package/dist/controllers/dashboards.js +1 -1
- package/dist/controllers/extensions.js +29 -16
- package/dist/controllers/fields.js +1 -1
- package/dist/controllers/files.js +1 -1
- package/dist/controllers/flows.js +1 -1
- package/dist/controllers/folders.js +1 -1
- package/dist/controllers/items.js +1 -1
- package/dist/controllers/not-found.js +1 -1
- package/dist/controllers/notifications.js +1 -1
- package/dist/controllers/operations.js +1 -1
- package/dist/controllers/panels.js +1 -1
- package/dist/controllers/permissions.js +1 -1
- package/dist/controllers/presets.js +1 -1
- package/dist/controllers/relations.js +1 -1
- package/dist/controllers/roles.js +1 -1
- package/dist/controllers/schema.js +1 -1
- package/dist/controllers/server.js +1 -1
- package/dist/controllers/settings.js +1 -1
- package/dist/controllers/shares.js +1 -1
- package/dist/controllers/translations.js +1 -1
- package/dist/controllers/users.js +1 -1
- package/dist/controllers/utils.js +37 -18
- package/dist/controllers/versions.d.ts +2 -0
- package/dist/controllers/versions.js +188 -0
- package/dist/controllers/webhooks.js +1 -1
- package/dist/database/errors/dialects/mssql.js +1 -1
- package/dist/database/errors/dialects/mysql.js +1 -1
- package/dist/database/errors/dialects/oracle.js +1 -1
- package/dist/database/errors/dialects/postgres.js +1 -1
- package/dist/database/errors/dialects/sqlite.js +1 -1
- package/dist/database/helpers/schema/dialects/mysql.js +1 -1
- package/dist/database/helpers/sequence/dialects/postgres.d.ts +5 -2
- package/dist/database/helpers/sequence/dialects/postgres.js +6 -3
- package/dist/database/migrations/20230823A-add-content-versioning.d.ts +3 -0
- package/dist/database/migrations/20230823A-add-content-versioning.js +36 -0
- package/dist/database/migrations/20230927A-themes.d.ts +3 -0
- package/dist/database/migrations/20230927A-themes.js +49 -0
- package/dist/database/migrations/20231009A-update-csv-fields-to-text.d.ts +3 -0
- package/dist/database/migrations/20231009A-update-csv-fields-to-text.js +44 -0
- package/dist/database/migrations/20231009B-update-panel-options.d.ts +3 -0
- package/dist/database/migrations/20231009B-update-panel-options.js +77 -0
- package/dist/database/migrations/20231010A-add-extensions.d.ts +3 -0
- package/dist/database/migrations/20231010A-add-extensions.js +9 -0
- package/dist/database/run-ast.js +2 -2
- package/dist/database/seeds/run.js +1 -1
- package/dist/database/system-data/collections/collections.yaml +6 -0
- package/dist/database/system-data/fields/activity.yaml +4 -4
- package/dist/database/system-data/fields/collections.yaml +19 -0
- package/dist/database/system-data/fields/extensions.yaml +10 -0
- package/dist/database/system-data/fields/revisions.yaml +3 -0
- package/dist/database/system-data/fields/settings.yaml +73 -17
- package/dist/database/system-data/fields/users.yaml +48 -12
- package/dist/database/system-data/fields/versions.yaml +38 -0
- package/dist/database/system-data/fields/webhooks.yaml +9 -9
- package/dist/database/system-data/relations/relations.yaml +88 -20
- package/dist/env.js +4 -0
- package/dist/extensions/index.d.ts +2 -0
- package/dist/extensions/index.js +9 -0
- package/dist/extensions/lib/get-extensions-settings.d.ts +7 -0
- package/dist/extensions/lib/get-extensions-settings.js +39 -0
- package/dist/extensions/lib/get-extensions.d.ts +1 -0
- package/dist/extensions/lib/get-extensions.js +11 -0
- package/dist/extensions/lib/get-shared-deps-mapping.d.ts +1 -0
- package/dist/extensions/lib/get-shared-deps-mapping.js +26 -0
- package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.d.ts +31 -0
- package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.js +80 -0
- package/dist/extensions/lib/sandbox/generate-host-function-reference.d.ts +11 -0
- package/dist/extensions/lib/sandbox/generate-host-function-reference.js +28 -0
- package/dist/extensions/lib/sandbox/register/action.d.ts +6 -0
- package/dist/extensions/lib/sandbox/register/action.js +18 -0
- package/dist/extensions/lib/sandbox/register/call-reference.d.ts +5 -0
- package/dist/extensions/lib/sandbox/register/call-reference.js +20 -0
- package/dist/extensions/lib/sandbox/register/filter.d.ts +6 -0
- package/dist/extensions/lib/sandbox/register/filter.js +21 -0
- package/dist/extensions/lib/sandbox/register/index.d.ts +5 -0
- package/dist/extensions/lib/sandbox/register/index.js +5 -0
- package/dist/extensions/lib/sandbox/register/operation.d.ts +6 -0
- package/dist/extensions/lib/sandbox/register/operation.js +19 -0
- package/dist/extensions/lib/sandbox/register/route.d.ts +17 -0
- package/dist/extensions/lib/sandbox/register/route.js +44 -0
- package/dist/extensions/lib/sandbox/sdk/generators/index.d.ts +3 -0
- package/dist/extensions/lib/sandbox/sdk/generators/index.js +3 -0
- package/dist/extensions/lib/sandbox/sdk/generators/log.d.ts +3 -0
- package/dist/extensions/lib/sandbox/sdk/generators/log.js +11 -0
- package/dist/extensions/lib/sandbox/sdk/generators/request.d.ts +12 -0
- package/dist/extensions/lib/sandbox/sdk/generators/request.js +49 -0
- package/dist/extensions/lib/sandbox/sdk/generators/sleep.d.ts +3 -0
- package/dist/extensions/lib/sandbox/sdk/generators/sleep.js +11 -0
- package/dist/extensions/lib/sandbox/sdk/index.d.ts +2 -0
- package/dist/extensions/lib/sandbox/sdk/index.js +2 -0
- package/dist/extensions/lib/sandbox/sdk/instantiate.d.ts +11 -0
- package/dist/extensions/lib/sandbox/sdk/instantiate.js +28 -0
- package/dist/extensions/lib/sandbox/sdk/sdk.d.ts +20 -0
- package/dist/extensions/lib/sandbox/sdk/sdk.js +11 -0
- package/dist/extensions/lib/sandbox/sdk/utils/index.d.ts +1 -0
- package/dist/extensions/lib/sandbox/sdk/utils/index.js +1 -0
- package/dist/extensions/lib/sandbox/sdk/utils/wrap.d.ts +11 -0
- package/dist/extensions/lib/sandbox/sdk/utils/wrap.js +17 -0
- package/dist/extensions/lib/wrap-embeds.d.ts +4 -0
- package/dist/extensions/lib/wrap-embeds.js +8 -0
- package/dist/extensions/manager.d.ts +158 -0
- package/dist/extensions/manager.js +604 -0
- package/dist/extensions/types.d.ts +19 -0
- package/dist/flows.d.ts +2 -2
- package/dist/flows.js +7 -7
- package/dist/middleware/check-ip.js +1 -1
- package/dist/middleware/collection-exists.js +1 -1
- package/dist/middleware/error-handler.js +1 -1
- package/dist/middleware/graphql.js +1 -1
- package/dist/middleware/rate-limiter-global.js +1 -1
- package/dist/middleware/rate-limiter-ip.js +1 -1
- package/dist/middleware/respond.js +13 -1
- package/dist/middleware/validate-batch.js +1 -1
- package/dist/operations/condition/index.d.ts +1 -1
- package/dist/operations/condition/index.js +2 -1
- package/dist/operations/exec/index.d.ts +1 -1
- package/dist/operations/exec/index.js +1 -1
- package/dist/operations/item-create/index.d.ts +1 -1
- package/dist/operations/item-create/index.js +2 -1
- package/dist/operations/item-delete/index.d.ts +1 -1
- package/dist/operations/item-delete/index.js +2 -1
- package/dist/operations/item-read/index.d.ts +1 -1
- package/dist/operations/item-read/index.js +2 -1
- package/dist/operations/item-update/index.d.ts +1 -1
- package/dist/operations/item-update/index.js +2 -1
- package/dist/operations/json-web-token/index.d.ts +1 -1
- package/dist/operations/json-web-token/index.js +2 -1
- package/dist/operations/log/index.d.ts +1 -1
- package/dist/operations/log/index.js +2 -1
- package/dist/operations/mail/index.d.ts +1 -1
- package/dist/operations/mail/index.js +1 -1
- package/dist/operations/notification/index.d.ts +1 -1
- package/dist/operations/notification/index.js +2 -1
- package/dist/operations/request/index.d.ts +1 -1
- package/dist/operations/request/index.js +3 -2
- package/dist/operations/sleep/index.d.ts +1 -1
- package/dist/operations/sleep/index.js +1 -1
- package/dist/operations/transform/index.d.ts +1 -1
- package/dist/operations/transform/index.js +2 -1
- package/dist/operations/trigger/index.d.ts +1 -1
- package/dist/operations/trigger/index.js +2 -1
- package/dist/services/activity.js +1 -1
- package/dist/services/assets.d.ts +1 -1
- package/dist/services/assets.js +3 -3
- package/dist/services/authentication.js +2 -2
- package/dist/services/authorization.js +1 -1
- package/dist/services/collections.js +3 -3
- package/dist/services/extensions.d.ts +31 -0
- package/dist/services/extensions.js +121 -0
- package/dist/services/fields.d.ts +2 -2
- package/dist/services/fields.js +4 -4
- package/dist/services/files.d.ts +4 -1
- package/dist/services/files.js +5 -5
- package/dist/services/graphql/index.d.ts +1 -1
- package/dist/services/graphql/index.js +87 -24
- package/dist/services/graphql/subscription.js +3 -3
- package/dist/services/import-export/import-worker.d.ts +9 -0
- package/dist/services/import-export/import-worker.js +9 -0
- package/dist/services/{import-export.d.ts → import-export/index.d.ts} +2 -2
- package/dist/services/{import-export.js → import-export/index.js} +51 -42
- package/dist/services/index.d.ts +3 -1
- package/dist/services/index.js +3 -1
- package/dist/services/items.js +2 -2
- package/dist/services/mail/index.js +1 -1
- package/dist/services/meta.js +1 -1
- package/dist/services/payload.js +1 -1
- package/dist/services/permissions.d.ts +2 -2
- package/dist/services/permissions.js +1 -1
- package/dist/services/relations.js +1 -1
- package/dist/services/revisions.js +1 -1
- package/dist/services/roles.js +1 -1
- package/dist/services/schema.js +1 -1
- package/dist/services/server.js +3 -1
- package/dist/services/shares.js +1 -1
- package/dist/services/tfa.js +1 -1
- package/dist/services/translations.js +1 -1
- package/dist/services/users.js +4 -2
- package/dist/services/utils.d.ts +1 -0
- package/dist/services/utils.js +8 -2
- package/dist/services/versions.d.ts +21 -0
- package/dist/services/versions.js +232 -0
- package/dist/services/websocket.js +11 -1
- package/dist/types/collection.d.ts +1 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/utils/apply-query.d.ts +1 -1
- package/dist/utils/apply-query.js +31 -3
- package/dist/utils/delete-from-require-cache.d.ts +1 -0
- package/dist/utils/delete-from-require-cache.js +5 -0
- package/dist/utils/get-accountability-for-token.js +1 -1
- package/dist/utils/get-ast-from-query.js +1 -1
- package/dist/utils/get-column-path.js +1 -1
- package/dist/utils/get-column.js +1 -1
- package/dist/utils/get-default-value.d.ts +1 -2
- package/dist/utils/get-permissions.js +1 -1
- package/dist/utils/get-service.js +3 -1
- package/dist/utils/import-file-url.d.ts +5 -0
- package/dist/utils/import-file-url.js +6 -0
- package/dist/utils/job-queue.d.ts +2 -3
- package/dist/utils/jwt.js +1 -1
- package/dist/utils/redact-object.js +9 -3
- package/dist/utils/sanitize-query.js +3 -0
- package/dist/utils/transformations.d.ts +2 -1
- package/dist/utils/validate-diff.js +1 -1
- package/dist/utils/validate-keys.js +1 -1
- package/dist/utils/validate-query.js +2 -1
- package/dist/utils/validate-snapshot.js +1 -1
- package/dist/websocket/controllers/base.js +1 -1
- package/dist/websocket/controllers/index.d.ts +1 -1
- package/dist/websocket/controllers/index.js +0 -7
- package/dist/websocket/handlers/heartbeat.js +6 -1
- package/dist/websocket/handlers/subscribe.js +11 -16
- package/dist/websocket/utils/items.d.ts +4 -14
- package/dist/websocket/utils/items.js +59 -64
- package/dist/worker-pool.d.ts +2 -0
- package/dist/worker-pool.js +11 -0
- package/package.json +34 -31
- package/dist/errors/codes.d.ts +0 -29
- package/dist/errors/codes.js +0 -30
- package/dist/errors/contains-null-values.d.ts +0 -7
- package/dist/errors/contains-null-values.js +0 -4
- package/dist/errors/content-too-large.d.ts +0 -1
- package/dist/errors/content-too-large.js +0 -3
- package/dist/errors/forbidden.d.ts +0 -1
- package/dist/errors/forbidden.js +0 -3
- package/dist/errors/hit-rate-limit.d.ts +0 -6
- package/dist/errors/hit-rate-limit.js +0 -8
- package/dist/errors/illegal-asset-transformation.d.ts +0 -4
- package/dist/errors/illegal-asset-transformation.js +0 -3
- package/dist/errors/index.d.ts +0 -28
- package/dist/errors/index.js +0 -28
- package/dist/errors/invalid-credentials.d.ts +0 -1
- package/dist/errors/invalid-credentials.js +0 -3
- package/dist/errors/invalid-foreign-key.d.ts +0 -6
- package/dist/errors/invalid-foreign-key.js +0 -14
- package/dist/errors/invalid-ip.d.ts +0 -1
- package/dist/errors/invalid-ip.js +0 -3
- package/dist/errors/invalid-otp.d.ts +0 -1
- package/dist/errors/invalid-otp.js +0 -3
- package/dist/errors/invalid-payload.d.ts +0 -5
- package/dist/errors/invalid-payload.js +0 -4
- package/dist/errors/invalid-provider-config.d.ts +0 -5
- package/dist/errors/invalid-provider-config.js +0 -3
- package/dist/errors/invalid-provider.d.ts +0 -1
- package/dist/errors/invalid-provider.js +0 -3
- package/dist/errors/invalid-query.d.ts +0 -5
- package/dist/errors/invalid-query.js +0 -4
- package/dist/errors/invalid-token.d.ts +0 -1
- package/dist/errors/invalid-token.js +0 -3
- package/dist/errors/method-not-allowed.d.ts +0 -6
- package/dist/errors/method-not-allowed.js +0 -6
- package/dist/errors/not-null-violation.d.ts +0 -6
- package/dist/errors/not-null-violation.js +0 -14
- package/dist/errors/range-not-satisfiable.d.ts +0 -7
- package/dist/errors/range-not-satisfiable.js +0 -7
- package/dist/errors/record-not-unique.d.ts +0 -6
- package/dist/errors/record-not-unique.js +0 -14
- package/dist/errors/route-not-found.d.ts +0 -5
- package/dist/errors/route-not-found.js +0 -4
- package/dist/errors/service-unavailable.d.ts +0 -7
- package/dist/errors/service-unavailable.js +0 -4
- package/dist/errors/token-expired.d.ts +0 -1
- package/dist/errors/token-expired.js +0 -3
- package/dist/errors/unexpected-response.d.ts +0 -1
- package/dist/errors/unexpected-response.js +0 -3
- package/dist/errors/unprocessable-content.d.ts +0 -5
- package/dist/errors/unprocessable-content.js +0 -4
- package/dist/errors/unsupported-media-type.d.ts +0 -6
- package/dist/errors/unsupported-media-type.js +0 -4
- package/dist/errors/user-suspended.d.ts +0 -1
- package/dist/errors/user-suspended.js +0 -3
- package/dist/errors/value-out-of-range.d.ts +0 -6
- package/dist/errors/value-out-of-range.js +0 -14
- package/dist/errors/value-too-long.d.ts +0 -6
- package/dist/errors/value-too-long.js +0 -14
- package/dist/extensions.d.ts +0 -51
- package/dist/extensions.js +0 -487
- package/dist/types/files.d.ts +0 -29
- /package/dist/{types/files.js → extensions/types.js} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Check if requested collection exists, and save it to req.collection
|
|
3
3
|
*/
|
|
4
4
|
import { systemCollectionRows } from '../database/system-data/collections/index.js';
|
|
5
|
-
import { ForbiddenError } from '
|
|
5
|
+
import { ForbiddenError } from '@directus/errors';
|
|
6
6
|
import asyncHandler from '../utils/async-handler.js';
|
|
7
7
|
const collectionExists = asyncHandler(async (req, _res, next) => {
|
|
8
8
|
if (!req.params['collection'])
|
|
@@ -3,7 +3,7 @@ import { toArray } from '@directus/utils';
|
|
|
3
3
|
import getDatabase from '../database/index.js';
|
|
4
4
|
import emitter from '../emitter.js';
|
|
5
5
|
import env from '../env.js';
|
|
6
|
-
import { ErrorCode, MethodNotAllowedError } from '
|
|
6
|
+
import { ErrorCode, MethodNotAllowedError } from '@directus/errors';
|
|
7
7
|
import logger from '../logger.js';
|
|
8
8
|
// Note: keep all 4 parameters here. That's how Express recognizes it's the error handler, even if
|
|
9
9
|
// we don't use next
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseJSON } from '@directus/utils';
|
|
2
2
|
import { getOperationAST, parse, Source } from 'graphql';
|
|
3
|
-
import { InvalidPayloadError, InvalidQueryError, MethodNotAllowedError } from '
|
|
3
|
+
import { InvalidPayloadError, InvalidQueryError, MethodNotAllowedError } from '@directus/errors';
|
|
4
4
|
import { GraphQLValidationError } from '../services/graphql/errors/validation.js';
|
|
5
5
|
import asyncHandler from '../utils/async-handler.js';
|
|
6
6
|
export const parseGraphQL = asyncHandler(async (req, res, next) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import env from '../env.js';
|
|
2
|
-
import { HitRateLimitError } from '
|
|
2
|
+
import { HitRateLimitError } from '@directus/errors';
|
|
3
3
|
import logger from '../logger.js';
|
|
4
4
|
import { createRateLimiter } from '../rate-limiter.js';
|
|
5
5
|
import asyncHandler from '../utils/async-handler.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import env from '../env.js';
|
|
2
|
-
import { HitRateLimitError } from '
|
|
2
|
+
import { HitRateLimitError } from '@directus/errors';
|
|
3
3
|
import { createRateLimiter } from '../rate-limiter.js';
|
|
4
4
|
import asyncHandler from '../utils/async-handler.js';
|
|
5
5
|
import { getIPFromReq } from '../utils/get-ip-from-req.js';
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { parse as parseBytesConfiguration } from 'bytes';
|
|
2
|
+
import { assign } from 'lodash-es';
|
|
2
3
|
import { getCache, setCacheValue } from '../cache.js';
|
|
3
4
|
import env from '../env.js';
|
|
4
5
|
import logger from '../logger.js';
|
|
5
|
-
import { ExportService } from '../services/import-export.js';
|
|
6
|
+
import { ExportService } from '../services/import-export/index.js';
|
|
7
|
+
import { VersionsService } from '../services/versions.js';
|
|
6
8
|
import asyncHandler from '../utils/async-handler.js';
|
|
7
9
|
import { getCacheControlHeader } from '../utils/get-cache-headers.js';
|
|
8
10
|
import { getCacheKey } from '../utils/get-cache-key.js';
|
|
@@ -39,6 +41,16 @@ export const respond = asyncHandler(async (req, res) => {
|
|
|
39
41
|
res.setHeader('Cache-Control', 'no-cache');
|
|
40
42
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
41
43
|
}
|
|
44
|
+
if (req.sanitizedQuery.version &&
|
|
45
|
+
req.collection &&
|
|
46
|
+
(req.singleton || req.params['pk']) &&
|
|
47
|
+
'data' in res.locals['payload']) {
|
|
48
|
+
const versionsService = new VersionsService({ accountability: req.accountability ?? null, schema: req.schema });
|
|
49
|
+
const saves = await versionsService.getVersionSaves(req.sanitizedQuery.version, req.collection, req.params['pk']);
|
|
50
|
+
if (saves) {
|
|
51
|
+
assign(res.locals['payload'].data, ...saves);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
42
54
|
if (req.sanitizedQuery.export) {
|
|
43
55
|
const exportService = new ExportService({ accountability: req.accountability ?? null, schema: req.schema });
|
|
44
56
|
let filename = '';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Joi from 'joi';
|
|
2
|
-
import { InvalidPayloadError } from '
|
|
2
|
+
import { InvalidPayloadError } from '@directus/errors';
|
|
3
3
|
import asyncHandler from '../utils/async-handler.js';
|
|
4
4
|
import { sanitizeQuery } from '../utils/sanitize-query.js';
|
|
5
5
|
export const validateBatch = (scope) => asyncHandler(async (req, _res, next) => {
|
|
@@ -2,5 +2,5 @@ import type { Filter } from '@directus/types';
|
|
|
2
2
|
type Options = {
|
|
3
3
|
filter: Filter;
|
|
4
4
|
};
|
|
5
|
-
declare const _default: import("@directus/
|
|
5
|
+
declare const _default: import("@directus/extensions").OperationApiConfig<Options>;
|
|
6
6
|
export default _default;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validatePayload } from '@directus/utils';
|
|
2
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
3
|
export default defineOperationApi({
|
|
3
4
|
id: 'condition',
|
|
4
5
|
handler: ({ filter }, { data }) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject, toArray } from '@directus/utils';
|
|
2
3
|
import { ItemsService } from '../../services/items.js';
|
|
3
4
|
import { getAccountabilityForRole } from '../../utils/get-accountability-for-role.js';
|
|
4
5
|
export default defineOperationApi({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject, toArray } from '@directus/utils';
|
|
2
3
|
import { ItemsService } from '../../services/items.js';
|
|
3
4
|
import { getAccountabilityForRole } from '../../utils/get-accountability-for-role.js';
|
|
4
5
|
import { sanitizeQuery } from '../../utils/sanitize-query.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject, toArray } from '@directus/utils';
|
|
2
3
|
import { ItemsService } from '../../services/items.js';
|
|
3
4
|
import { getAccountabilityForRole } from '../../utils/get-accountability-for-role.js';
|
|
4
5
|
import { sanitizeQuery } from '../../utils/sanitize-query.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject, toArray } from '@directus/utils';
|
|
2
3
|
import { ItemsService } from '../../services/items.js';
|
|
3
4
|
import { getAccountabilityForRole } from '../../utils/get-accountability-for-role.js';
|
|
4
5
|
import { sanitizeQuery } from '../../utils/sanitize-query.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject, optionToString } from '@directus/utils';
|
|
2
3
|
import jwt from 'jsonwebtoken';
|
|
3
4
|
export default defineOperationApi({
|
|
4
5
|
id: 'json-web-token',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToString } from '@directus/utils';
|
|
2
3
|
import logger from '../../logger.js';
|
|
3
4
|
export default defineOperationApi({
|
|
4
5
|
id: 'log',
|
|
@@ -6,5 +6,5 @@ export type Options = {
|
|
|
6
6
|
type: 'wysiwyg' | 'markdown' | 'template';
|
|
7
7
|
subject: string;
|
|
8
8
|
};
|
|
9
|
-
declare const _default: import("@directus/
|
|
9
|
+
declare const _default: import("@directus/extensions").OperationApiConfig<Options>;
|
|
10
10
|
export default _default;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToString, toArray } from '@directus/utils';
|
|
2
3
|
import { NotificationsService } from '../../services/notifications.js';
|
|
3
4
|
import { getAccountabilityForRole } from '../../utils/get-accountability-for-role.js';
|
|
4
5
|
export default defineOperationApi({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { isValidJSON } from '@directus/utils';
|
|
3
|
+
import { isAxiosError } from 'axios';
|
|
2
4
|
import encodeUrl from 'encodeurl';
|
|
3
5
|
import { getAxios } from '../../request/index.js';
|
|
4
|
-
import { isAxiosError } from 'axios';
|
|
5
6
|
export default defineOperationApi({
|
|
6
7
|
id: 'request',
|
|
7
8
|
handler: async ({ url, method, body, headers }) => {
|
|
@@ -4,5 +4,5 @@ type Options = {
|
|
|
4
4
|
iterationMode?: 'serial' | 'batch' | 'parallel';
|
|
5
5
|
batchSize?: number;
|
|
6
6
|
};
|
|
7
|
-
declare const _default: import("@directus/
|
|
7
|
+
declare const _default: import("@directus/extensions").OperationApiConfig<Options>;
|
|
8
8
|
export default _default;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineOperationApi
|
|
1
|
+
import { defineOperationApi } from '@directus/extensions';
|
|
2
|
+
import { optionToObject } from '@directus/utils';
|
|
2
3
|
import { omit } from 'lodash-es';
|
|
3
4
|
import { getFlowManager } from '../../flows.js';
|
|
4
5
|
export default defineOperationApi({
|
|
@@ -3,7 +3,7 @@ import { isDirectusError } from '@directus/errors';
|
|
|
3
3
|
import { uniq } from 'lodash-es';
|
|
4
4
|
import validateUUID from 'uuid-validate';
|
|
5
5
|
import env from '../env.js';
|
|
6
|
-
import { ErrorCode } from '
|
|
6
|
+
import { ErrorCode } from '@directus/errors';
|
|
7
7
|
import logger from '../logger.js';
|
|
8
8
|
import { getPermissions } from '../utils/get-permissions.js';
|
|
9
9
|
import { Url } from '../utils/url.js';
|
|
@@ -10,7 +10,7 @@ export declare class AssetsService {
|
|
|
10
10
|
accountability: Accountability | null;
|
|
11
11
|
authorizationService: AuthorizationService;
|
|
12
12
|
constructor(options: AbstractServiceOptions);
|
|
13
|
-
getAsset(id: string, transformation
|
|
13
|
+
getAsset(id: string, transformation?: TransformationSet, range?: Range): Promise<{
|
|
14
14
|
stream: Readable;
|
|
15
15
|
file: any;
|
|
16
16
|
stat: Stat;
|
package/dist/services/assets.js
CHANGED
|
@@ -7,7 +7,7 @@ import validateUUID from 'uuid-validate';
|
|
|
7
7
|
import { SUPPORTED_IMAGE_TRANSFORM_FORMATS } from '../constants.js';
|
|
8
8
|
import getDatabase from '../database/index.js';
|
|
9
9
|
import env from '../env.js';
|
|
10
|
-
import { ForbiddenError, IllegalAssetTransformationError, RangeNotSatisfiableError, ServiceUnavailableError, } from '
|
|
10
|
+
import { ForbiddenError, IllegalAssetTransformationError, RangeNotSatisfiableError, ServiceUnavailableError, } from '@directus/errors';
|
|
11
11
|
import logger from '../logger.js';
|
|
12
12
|
import { getStorage } from '../storage/index.js';
|
|
13
13
|
import { getMilliseconds } from '../utils/get-milliseconds.js';
|
|
@@ -25,7 +25,7 @@ export class AssetsService {
|
|
|
25
25
|
async getAsset(id, transformation, range) {
|
|
26
26
|
const storage = await getStorage();
|
|
27
27
|
const publicSettings = await this.knex
|
|
28
|
-
.select('project_logo', 'public_background', 'public_foreground')
|
|
28
|
+
.select('project_logo', 'public_background', 'public_foreground', 'public_favicon')
|
|
29
29
|
.from('directus_settings')
|
|
30
30
|
.first();
|
|
31
31
|
const systemPublicKeys = Object.values(publicSettings || {});
|
|
@@ -78,7 +78,7 @@ export class AssetsService {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
const type = file.type;
|
|
81
|
-
const transforms = TransformationUtils.resolvePreset(transformation, file);
|
|
81
|
+
const transforms = transformation ? TransformationUtils.resolvePreset(transformation, file) : [];
|
|
82
82
|
if (type && transforms.length > 0 && SUPPORTED_IMAGE_TRANSFORM_FORMATS.includes(type)) {
|
|
83
83
|
const maybeNewFormat = TransformationUtils.maybeExtractFormat(transforms);
|
|
84
84
|
const assetFilename = path.basename(file.filename_disk, path.extname(file.filename_disk)) +
|
|
@@ -7,8 +7,8 @@ import { DEFAULT_AUTH_PROVIDER } from '../constants.js';
|
|
|
7
7
|
import getDatabase from '../database/index.js';
|
|
8
8
|
import emitter from '../emitter.js';
|
|
9
9
|
import env from '../env.js';
|
|
10
|
-
import { InvalidCredentialsError, InvalidProviderError, UserSuspendedError } from '
|
|
11
|
-
import { InvalidOtpError } from '
|
|
10
|
+
import { InvalidCredentialsError, InvalidProviderError, UserSuspendedError } from '@directus/errors';
|
|
11
|
+
import { InvalidOtpError } from '@directus/errors';
|
|
12
12
|
import { createRateLimiter } from '../rate-limiter.js';
|
|
13
13
|
import { getMilliseconds } from '../utils/get-milliseconds.js';
|
|
14
14
|
import { stall } from '../utils/stall.js';
|
|
@@ -3,7 +3,7 @@ import { FailedValidationError, joiValidationErrorItemToErrorExtensions } from '
|
|
|
3
3
|
import { cloneDeep, flatten, isArray, isNil, merge, reduce, uniq, uniqWith } from 'lodash-es';
|
|
4
4
|
import { GENERATE_SPECIAL } from '../constants.js';
|
|
5
5
|
import getDatabase from '../database/index.js';
|
|
6
|
-
import { ForbiddenError } from '
|
|
6
|
+
import { ForbiddenError } from '@directus/errors';
|
|
7
7
|
import { getRelationInfo } from '../utils/get-relation-info.js';
|
|
8
8
|
import { stripFunction } from '../utils/strip-function.js';
|
|
9
9
|
import { ItemsService } from './items.js';
|
|
@@ -8,9 +8,9 @@ import getDatabase, { getSchemaInspector } from '../database/index.js';
|
|
|
8
8
|
import { systemCollectionRows } from '../database/system-data/collections/index.js';
|
|
9
9
|
import emitter from '../emitter.js';
|
|
10
10
|
import env from '../env.js';
|
|
11
|
-
import { ForbiddenError, InvalidPayloadError } from '
|
|
12
|
-
import { FieldsService } from '
|
|
13
|
-
import { ItemsService } from '
|
|
11
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
12
|
+
import { FieldsService } from './fields.js';
|
|
13
|
+
import { ItemsService } from './items.js';
|
|
14
14
|
import { getSchema } from '../utils/get-schema.js';
|
|
15
15
|
import { shouldClearCache } from '../utils/should-clear-cache.js';
|
|
16
16
|
export class CollectionsService {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ApiOutput, ExtensionSettings } from '@directus/extensions';
|
|
2
|
+
import type { SchemaInspector } from '@directus/schema';
|
|
3
|
+
import type { Accountability, DeepPartial, SchemaOverview } from '@directus/types';
|
|
4
|
+
import type Keyv from 'keyv';
|
|
5
|
+
import type { Knex } from 'knex';
|
|
6
|
+
import type { Helpers } from '../database/helpers/index.js';
|
|
7
|
+
import type { ExtensionManager } from '../extensions/manager.js';
|
|
8
|
+
import type { AbstractServiceOptions } from '../types/index.js';
|
|
9
|
+
import { ItemsService } from './items.js';
|
|
10
|
+
import { PermissionsService } from './permissions.js';
|
|
11
|
+
export declare class ExtensionsService {
|
|
12
|
+
knex: Knex;
|
|
13
|
+
permissionsService: PermissionsService;
|
|
14
|
+
schemaInspector: SchemaInspector;
|
|
15
|
+
accountability: Accountability | null;
|
|
16
|
+
schema: SchemaOverview;
|
|
17
|
+
extensionsItemService: ItemsService<ExtensionSettings>;
|
|
18
|
+
systemCache: Keyv<any>;
|
|
19
|
+
helpers: Helpers;
|
|
20
|
+
extensionsManager: ExtensionManager;
|
|
21
|
+
constructor(options: AbstractServiceOptions);
|
|
22
|
+
readAll(): Promise<ApiOutput[]>;
|
|
23
|
+
readOne(bundle: string | null, name: string): Promise<ApiOutput>;
|
|
24
|
+
updateOne(bundle: string | null, name: string, data: DeepPartial<ApiOutput>): Promise<void>;
|
|
25
|
+
private getKey;
|
|
26
|
+
/**
|
|
27
|
+
* Combine the settings stored in the database with the information available from the installed
|
|
28
|
+
* extensions into the standardized extensions api output
|
|
29
|
+
*/
|
|
30
|
+
private stitch;
|
|
31
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
2
|
+
import { createInspector } from '@directus/schema';
|
|
3
|
+
import Joi from 'joi';
|
|
4
|
+
import { omit, pick } from 'lodash-es';
|
|
5
|
+
import { getCache } from '../cache.js';
|
|
6
|
+
import { getHelpers } from '../database/helpers/index.js';
|
|
7
|
+
import getDatabase, { getSchemaInspector } from '../database/index.js';
|
|
8
|
+
import { getExtensionManager } from '../extensions/index.js';
|
|
9
|
+
import { ItemsService } from './items.js';
|
|
10
|
+
import { PermissionsService } from './permissions.js';
|
|
11
|
+
export class ExtensionsService {
|
|
12
|
+
knex;
|
|
13
|
+
permissionsService;
|
|
14
|
+
schemaInspector;
|
|
15
|
+
accountability;
|
|
16
|
+
schema;
|
|
17
|
+
extensionsItemService;
|
|
18
|
+
systemCache;
|
|
19
|
+
helpers;
|
|
20
|
+
extensionsManager;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.knex = options.knex || getDatabase();
|
|
23
|
+
this.permissionsService = new PermissionsService(options);
|
|
24
|
+
this.schemaInspector = options.knex ? createInspector(options.knex) : getSchemaInspector();
|
|
25
|
+
this.schema = options.schema;
|
|
26
|
+
this.accountability = options.accountability || null;
|
|
27
|
+
this.extensionsManager = getExtensionManager();
|
|
28
|
+
this.extensionsItemService = new ItemsService('directus_extensions', {
|
|
29
|
+
knex: this.knex,
|
|
30
|
+
schema: this.schema,
|
|
31
|
+
// No accountability here, as every other method is hardcoded to be admin only
|
|
32
|
+
});
|
|
33
|
+
this.systemCache = getCache().systemCache;
|
|
34
|
+
this.helpers = getHelpers(this.knex);
|
|
35
|
+
}
|
|
36
|
+
async readAll() {
|
|
37
|
+
if (this.accountability?.admin !== true) {
|
|
38
|
+
throw new ForbiddenError();
|
|
39
|
+
}
|
|
40
|
+
const installedExtensions = this.extensionsManager.getExtensions();
|
|
41
|
+
const configuredExtensions = await this.extensionsItemService.readByQuery({ limit: -1 });
|
|
42
|
+
return this.stitch(installedExtensions, configuredExtensions);
|
|
43
|
+
}
|
|
44
|
+
async readOne(bundle, name) {
|
|
45
|
+
if (this.accountability?.admin !== true) {
|
|
46
|
+
throw new ForbiddenError();
|
|
47
|
+
}
|
|
48
|
+
const key = this.getKey(bundle, name);
|
|
49
|
+
const schema = this.extensionsManager.getExtensions().find((extension) => extension.name === bundle ?? name);
|
|
50
|
+
const meta = await this.extensionsItemService.readOne(key);
|
|
51
|
+
const stitched = this.stitch(schema ? [schema] : [], [meta])[0];
|
|
52
|
+
if (stitched)
|
|
53
|
+
return stitched;
|
|
54
|
+
throw new ForbiddenError();
|
|
55
|
+
}
|
|
56
|
+
async updateOne(bundle, name, data) {
|
|
57
|
+
if (this.accountability?.admin !== true) {
|
|
58
|
+
throw new ForbiddenError();
|
|
59
|
+
}
|
|
60
|
+
const key = this.getKey(bundle, name);
|
|
61
|
+
const updateExtensionSchema = Joi.object({
|
|
62
|
+
meta: Joi.object({
|
|
63
|
+
enabled: Joi.boolean(),
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
const { error } = updateExtensionSchema.validate(data);
|
|
67
|
+
if (error) {
|
|
68
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
69
|
+
}
|
|
70
|
+
if ('meta' in data && 'enabled' in data.meta) {
|
|
71
|
+
await this.knex('directus_extensions').update({ enabled: data.meta.enabled }).where({ name: key });
|
|
72
|
+
this.extensionsManager.reload();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
getKey(bundle, name) {
|
|
76
|
+
return bundle ? `${bundle}/${name}` : name;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Combine the settings stored in the database with the information available from the installed
|
|
80
|
+
* extensions into the standardized extensions api output
|
|
81
|
+
*/
|
|
82
|
+
stitch(installed, configured) {
|
|
83
|
+
/**
|
|
84
|
+
* On startup, the extensions manager will automatically create the rows for installed
|
|
85
|
+
* extensions that don't have configured settings yet, so there should always be equal or more
|
|
86
|
+
* settings rows than installed extensions.
|
|
87
|
+
*/
|
|
88
|
+
return configured.map((meta) => {
|
|
89
|
+
let bundleName = null;
|
|
90
|
+
let name = meta.name;
|
|
91
|
+
if (name.includes('/')) {
|
|
92
|
+
[bundleName, name] = name.split('/');
|
|
93
|
+
}
|
|
94
|
+
let schema;
|
|
95
|
+
if (bundleName) {
|
|
96
|
+
const bundle = installed.find((extension) => extension.name === bundleName);
|
|
97
|
+
if (bundle && 'entries' in bundle) {
|
|
98
|
+
const entry = bundle.entries.find((entry) => entry.name === name) ?? null;
|
|
99
|
+
if (entry) {
|
|
100
|
+
schema = {
|
|
101
|
+
type: entry.type,
|
|
102
|
+
local: bundle.local,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
schema = null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
schema = installed.find((extension) => extension.name === name) ?? null;
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
name,
|
|
115
|
+
bundle: bundleName,
|
|
116
|
+
schema: schema ? pick(schema, 'type', 'local') : null,
|
|
117
|
+
meta: omit(meta, 'name'),
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -3,8 +3,8 @@ import type { Accountability, Field, RawField, SchemaOverview, Type } from '@dir
|
|
|
3
3
|
import type Keyv from 'keyv';
|
|
4
4
|
import type { Knex } from 'knex';
|
|
5
5
|
import type { Helpers } from '../database/helpers/index.js';
|
|
6
|
-
import { ItemsService } from '
|
|
7
|
-
import { PayloadService } from '
|
|
6
|
+
import { ItemsService } from './items.js';
|
|
7
|
+
import { PayloadService } from './payload.js';
|
|
8
8
|
import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
|
|
9
9
|
export declare class FieldsService {
|
|
10
10
|
knex: Knex;
|
package/dist/services/fields.js
CHANGED
|
@@ -9,9 +9,9 @@ import { getHelpers } from '../database/helpers/index.js';
|
|
|
9
9
|
import getDatabase, { getSchemaInspector } from '../database/index.js';
|
|
10
10
|
import { systemFieldRows } from '../database/system-data/fields/index.js';
|
|
11
11
|
import emitter from '../emitter.js';
|
|
12
|
-
import { ForbiddenError, InvalidPayloadError } from '
|
|
13
|
-
import { ItemsService } from '
|
|
14
|
-
import { PayloadService } from '
|
|
12
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
13
|
+
import { ItemsService } from './items.js';
|
|
14
|
+
import { PayloadService } from './payload.js';
|
|
15
15
|
import getDefaultValue from '../utils/get-default-value.js';
|
|
16
16
|
import getLocalType from '../utils/get-local-type.js';
|
|
17
17
|
import { getSchema } from '../utils/get-schema.js';
|
|
@@ -541,7 +541,7 @@ export class FieldsService {
|
|
|
541
541
|
column = table[type](field.field, field.schema?.numeric_precision ?? 10, field.schema?.numeric_scale ?? 5);
|
|
542
542
|
}
|
|
543
543
|
else if (field.type === 'csv') {
|
|
544
|
-
column = table.
|
|
544
|
+
column = table.text(field.field);
|
|
545
545
|
}
|
|
546
546
|
else if (field.type === 'hash') {
|
|
547
547
|
column = table.string(field.field, 255);
|
package/dist/services/files.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import type { File } from '@directus/types';
|
|
2
3
|
import type { Readable } from 'node:stream';
|
|
3
|
-
import type { AbstractServiceOptions,
|
|
4
|
+
import type { AbstractServiceOptions, MutationOptions, PrimaryKey } from '../types/index.js';
|
|
4
5
|
import { ItemsService } from './items.js';
|
|
6
|
+
type Metadata = Partial<Pick<File, 'height' | 'width' | 'description' | 'title' | 'tags' | 'metadata'>>;
|
|
5
7
|
export declare class FilesService extends ItemsService {
|
|
6
8
|
constructor(options: AbstractServiceOptions);
|
|
7
9
|
/**
|
|
@@ -32,3 +34,4 @@ export declare class FilesService extends ItemsService {
|
|
|
32
34
|
*/
|
|
33
35
|
deleteMany(keys: PrimaryKey[]): Promise<PrimaryKey[]>;
|
|
34
36
|
}
|
|
37
|
+
export {};
|