@directus/api 13.1.1 → 13.2.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/app.js +4 -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 +1 -1
- 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 +11 -7
- 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/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/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/run-ast.js +1 -1
- package/dist/database/seeds/run.js +1 -1
- package/dist/extensions/get-extensions.d.ts +47 -0
- package/dist/extensions/get-extensions.js +9 -0
- package/dist/extensions/get-shared-deps-mapping.d.ts +1 -0
- package/dist/extensions/get-shared-deps-mapping.js +26 -0
- package/dist/extensions/index.d.ts +2 -0
- package/dist/extensions/index.js +9 -0
- package/dist/{extensions.d.ts → extensions/manager.d.ts} +4 -11
- package/dist/{extensions.js → extensions/manager.js} +28 -86
- package/dist/extensions/normalize-extension-info.d.ts +5 -0
- package/dist/extensions/normalize-extension-info.js +30 -0
- package/dist/extensions/types.d.ts +23 -0
- package/dist/extensions/wrap-embeds.d.ts +4 -0
- package/dist/extensions/wrap-embeds.js +8 -0
- package/dist/flows.d.ts +1 -1
- package/dist/flows.js +1 -1
- 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 +1 -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 +2 -2
- package/dist/services/authentication.js +2 -2
- package/dist/services/authorization.js +1 -1
- package/dist/services/collections.js +3 -3
- 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.js +2 -2
- 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 +1 -1
- package/dist/services/index.js +1 -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/shares.js +1 -1
- package/dist/services/tfa.js +1 -1
- package/dist/services/translations.js +1 -1
- package/dist/services/users.js +2 -2
- package/dist/services/utils.d.ts +1 -0
- package/dist/services/utils.js +8 -2
- package/dist/services/websocket.js +11 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/utils/apply-query.js +1 -1
- 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/jwt.js +1 -1
- package/dist/utils/redact-object.js +9 -3
- 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 +1 -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 +24 -22
- 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/types/files.d.ts +0 -29
- /package/dist/{types/files.js → extensions/types.js} +0 -0
|
@@ -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';
|
|
@@ -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 {
|
|
@@ -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 {};
|
package/dist/services/files.js
CHANGED
|
@@ -14,7 +14,7 @@ import url from 'url';
|
|
|
14
14
|
import { SUPPORTED_IMAGE_METADATA_FORMATS } from '../constants.js';
|
|
15
15
|
import emitter from '../emitter.js';
|
|
16
16
|
import env from '../env.js';
|
|
17
|
-
import { ForbiddenError, InvalidPayloadError, ServiceUnavailableError } from '
|
|
17
|
+
import { ForbiddenError, InvalidPayloadError, ServiceUnavailableError } from '@directus/errors';
|
|
18
18
|
import logger from '../logger.js';
|
|
19
19
|
import { getAxios } from '../request/index.js';
|
|
20
20
|
import { getStorage } from '../storage/index.js';
|
|
@@ -115,12 +115,12 @@ export class FilesService extends ItemsService {
|
|
|
115
115
|
}
|
|
116
116
|
const metadata = {};
|
|
117
117
|
if (sharpMetadata.orientation && sharpMetadata.orientation >= 5) {
|
|
118
|
-
metadata.height = sharpMetadata.width;
|
|
119
|
-
metadata.width = sharpMetadata.height;
|
|
118
|
+
metadata.height = sharpMetadata.width ?? null;
|
|
119
|
+
metadata.width = sharpMetadata.height ?? null;
|
|
120
120
|
}
|
|
121
121
|
else {
|
|
122
|
-
metadata.width = sharpMetadata.width;
|
|
123
|
-
metadata.height = sharpMetadata.height;
|
|
122
|
+
metadata.width = sharpMetadata.width ?? null;
|
|
123
|
+
metadata.height = sharpMetadata.height ?? null;
|
|
124
124
|
}
|
|
125
125
|
// Backward-compatible layout as it used to be with 'exifr'
|
|
126
126
|
const fullMetadata = {};
|
|
@@ -9,8 +9,8 @@ import { clearSystemCache, getCache } from '../../cache.js';
|
|
|
9
9
|
import { DEFAULT_AUTH_PROVIDER, GENERATE_SPECIAL } from '../../constants.js';
|
|
10
10
|
import getDatabase from '../../database/index.js';
|
|
11
11
|
import env from '../../env.js';
|
|
12
|
-
import { ErrorCode, ForbiddenError, InvalidPayloadError } from '
|
|
13
|
-
import { getExtensionManager } from '../../extensions.js';
|
|
12
|
+
import { ErrorCode, ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
13
|
+
import { getExtensionManager } from '../../extensions/index.js';
|
|
14
14
|
import { generateHash } from '../../utils/generate-hash.js';
|
|
15
15
|
import { getGraphQLType } from '../../utils/get-graphql-type.js';
|
|
16
16
|
import { getMilliseconds } from '../../utils/get-milliseconds.js';
|
|
@@ -2,7 +2,7 @@ import { EventEmitter, on } from 'events';
|
|
|
2
2
|
import { getMessenger } from '../../messenger.js';
|
|
3
3
|
import { getSchema } from '../../utils/get-schema.js';
|
|
4
4
|
import { refreshAccountability } from '../../websocket/authenticate.js';
|
|
5
|
-
import {
|
|
5
|
+
import { getPayload } from '../../websocket/utils/items.js';
|
|
6
6
|
const messages = createPubSub(new EventEmitter());
|
|
7
7
|
export function bindPubSub() {
|
|
8
8
|
const messenger = getMessenger();
|
|
@@ -35,7 +35,7 @@ export function createSubscriptionGenerator(self, event) {
|
|
|
35
35
|
if (eventData['action'] === 'create') {
|
|
36
36
|
try {
|
|
37
37
|
subscription.item = eventData['key'];
|
|
38
|
-
const result = await
|
|
38
|
+
const result = await getPayload(subscription, accountability, schema, eventData);
|
|
39
39
|
yield {
|
|
40
40
|
[event]: {
|
|
41
41
|
key: eventData['key'],
|
|
@@ -52,7 +52,7 @@ export function createSubscriptionGenerator(self, event) {
|
|
|
52
52
|
for (const key of eventData['keys']) {
|
|
53
53
|
try {
|
|
54
54
|
subscription.item = key;
|
|
55
|
-
const result = await
|
|
55
|
+
const result = await getPayload(subscription, accountability, schema, eventData);
|
|
56
56
|
yield {
|
|
57
57
|
[event]: {
|
|
58
58
|
key,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Accountability, SchemaOverview } from '@directus/types';
|
|
2
|
+
export type ImportWorkerData = {
|
|
3
|
+
collection: string;
|
|
4
|
+
mimeType: string;
|
|
5
|
+
filePath: string;
|
|
6
|
+
accountability: Accountability | undefined;
|
|
7
|
+
schema: SchemaOverview;
|
|
8
|
+
};
|
|
9
|
+
export default function ({ collection, mimeType, filePath, accountability, schema }: ImportWorkerData): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createReadStream } from 'node:fs';
|
|
2
|
+
import { ImportService } from './index.js';
|
|
3
|
+
export default async function ({ collection, mimeType, filePath, accountability, schema }) {
|
|
4
|
+
const service = new ImportService({
|
|
5
|
+
accountability: accountability,
|
|
6
|
+
schema: schema,
|
|
7
|
+
});
|
|
8
|
+
await service.import(collection, mimeType, createReadStream(filePath));
|
|
9
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import type { Accountability, Query, SchemaOverview } from '@directus/types';
|
|
2
|
+
import type { Accountability, File, Query, SchemaOverview } from '@directus/types';
|
|
3
3
|
import type { Knex } from 'knex';
|
|
4
4
|
import type { Readable } from 'node:stream';
|
|
5
|
-
import type { AbstractServiceOptions
|
|
5
|
+
import type { AbstractServiceOptions } from '../../types/index.js';
|
|
6
6
|
type ExportFormat = 'csv' | 'json' | 'xml' | 'yaml';
|
|
7
7
|
export declare class ImportService {
|
|
8
8
|
knex: Knex;
|
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
import { parseJSON, toArray } from '@directus/utils';
|
|
2
2
|
import { queue } from 'async';
|
|
3
|
-
import csv from 'csv-parser';
|
|
4
3
|
import destroyStream from 'destroy';
|
|
5
4
|
import { dump as toYAML } from 'js-yaml';
|
|
6
5
|
import { parse as toXML } from 'js2xmlparser';
|
|
7
6
|
import { Parser as CSVParser, transforms as CSVTransforms } from 'json2csv';
|
|
8
|
-
import { set, transform } from 'lodash-es';
|
|
9
7
|
import { createReadStream } from 'node:fs';
|
|
10
8
|
import { appendFile } from 'node:fs/promises';
|
|
9
|
+
import Papa from 'papaparse';
|
|
11
10
|
import StreamArray from 'stream-json/streamers/StreamArray.js';
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { UsersService } from './users.js';
|
|
25
|
-
import { Url } from '../utils/url.js';
|
|
11
|
+
import getDatabase from '../../database/index.js';
|
|
12
|
+
import emitter from '../../emitter.js';
|
|
13
|
+
import env from '../../env.js';
|
|
14
|
+
import { ForbiddenError, InvalidPayloadError, ServiceUnavailableError, UnsupportedMediaTypeError, } from '@directus/errors';
|
|
15
|
+
import logger from '../../logger.js';
|
|
16
|
+
import { getDateFormatted } from '../../utils/get-date-formatted.js';
|
|
17
|
+
import { Url } from '../../utils/url.js';
|
|
18
|
+
import { userName } from '../../utils/user-name.js';
|
|
19
|
+
import { FilesService } from '../files.js';
|
|
20
|
+
import { ItemsService } from '../items.js';
|
|
21
|
+
import { NotificationsService } from '../notifications.js';
|
|
22
|
+
import { UsersService } from '../users.js';
|
|
26
23
|
export class ImportService {
|
|
27
24
|
knex;
|
|
28
25
|
accountability;
|
|
@@ -97,30 +94,34 @@ export class ImportService {
|
|
|
97
94
|
const saveQueue = queue(async (value) => {
|
|
98
95
|
return await service.upsertOne(value, { bypassEmitAction: (action) => nestedActionEvents.push(action) });
|
|
99
96
|
});
|
|
97
|
+
const transform = (value) => {
|
|
98
|
+
if (value.length === 0)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
const parsedJson = parseJSON(value);
|
|
102
|
+
if (typeof parsedJson === 'number') {
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
return parsedJson;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const PapaOptions = {
|
|
112
|
+
header: true,
|
|
113
|
+
transform,
|
|
114
|
+
};
|
|
100
115
|
return new Promise((resolve, reject) => {
|
|
101
116
|
stream
|
|
102
|
-
.pipe(
|
|
103
|
-
.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
delete
|
|
117
|
+
.pipe(Papa.parse(Papa.NODE_STREAM_INPUT, PapaOptions))
|
|
118
|
+
.on('data', (obj) => {
|
|
119
|
+
// Filter out all undefined fields
|
|
120
|
+
for (const field in obj) {
|
|
121
|
+
if (obj[field] === undefined) {
|
|
122
|
+
delete obj[field];
|
|
108
123
|
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const parsedJson = parseJSON(value);
|
|
112
|
-
if (typeof parsedJson === 'number') {
|
|
113
|
-
set(result, key, value);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
set(result, key, parsedJson);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
set(result, key, value);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
+
}
|
|
124
125
|
saveQueue.push(obj);
|
|
125
126
|
})
|
|
126
127
|
.on('error', (err) => {
|
|
@@ -128,6 +129,9 @@ export class ImportService {
|
|
|
128
129
|
reject(new InvalidPayloadError({ reason: err.message }));
|
|
129
130
|
})
|
|
130
131
|
.on('end', () => {
|
|
132
|
+
// In case of empty CSV file
|
|
133
|
+
if (!saveQueue.started)
|
|
134
|
+
return resolve();
|
|
131
135
|
saveQueue.drain(() => {
|
|
132
136
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
133
137
|
emitter.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -157,7 +161,11 @@ export class ExportService {
|
|
|
157
161
|
* FilesService upload method.
|
|
158
162
|
*/
|
|
159
163
|
async exportToFile(collection, query, format, options) {
|
|
164
|
+
const { createTmpFile } = await import('@directus/utils/node');
|
|
165
|
+
const tmpFile = await createTmpFile().catch(() => null);
|
|
160
166
|
try {
|
|
167
|
+
if (!tmpFile)
|
|
168
|
+
throw new Error('Failed to create temporary file for export');
|
|
161
169
|
const mimeTypes = {
|
|
162
170
|
csv: 'text/csv',
|
|
163
171
|
json: 'application/json',
|
|
@@ -165,7 +173,6 @@ export class ExportService {
|
|
|
165
173
|
yaml: 'text/yaml',
|
|
166
174
|
};
|
|
167
175
|
const database = getDatabase();
|
|
168
|
-
const { path, cleanup } = await createTmpFile();
|
|
169
176
|
await database.transaction(async (trx) => {
|
|
170
177
|
const service = new ItemsService(collection, {
|
|
171
178
|
accountability: this.accountability,
|
|
@@ -185,7 +192,7 @@ export class ExportService {
|
|
|
185
192
|
},
|
|
186
193
|
})
|
|
187
194
|
.then((result) => Number(result?.[0]?.['count'] ?? 0));
|
|
188
|
-
const count = query.limit ? Math.min(totalCount, query.limit) : totalCount;
|
|
195
|
+
const count = query.limit && query.limit > -1 ? Math.min(totalCount, query.limit) : totalCount;
|
|
189
196
|
const requestedLimit = query.limit ?? -1;
|
|
190
197
|
const batchesRequired = Math.ceil(count / env['EXPORT_BATCH_SIZE']);
|
|
191
198
|
let readCount = 0;
|
|
@@ -202,7 +209,7 @@ export class ExportService {
|
|
|
202
209
|
});
|
|
203
210
|
readCount += result.length;
|
|
204
211
|
if (result.length) {
|
|
205
|
-
await appendFile(path, this.transform(result, format, {
|
|
212
|
+
await appendFile(tmpFile.path, this.transform(result, format, {
|
|
206
213
|
includeHeader: batch === 0,
|
|
207
214
|
includeFooter: batch + 1 === batchesRequired,
|
|
208
215
|
}));
|
|
@@ -223,7 +230,7 @@ export class ExportService {
|
|
|
223
230
|
storage: options?.file?.storage ?? storage,
|
|
224
231
|
type: mimeTypes[format],
|
|
225
232
|
};
|
|
226
|
-
const savedFile = await filesService.uploadOne(createReadStream(path), fileWithDefaults);
|
|
233
|
+
const savedFile = await filesService.uploadOne(createReadStream(tmpFile.path), fileWithDefaults);
|
|
227
234
|
if (this.accountability?.user) {
|
|
228
235
|
const notificationsService = new NotificationsService({
|
|
229
236
|
accountability: this.accountability,
|
|
@@ -250,7 +257,6 @@ Your export of ${collection} is ready. <a href="${href}">Click here to view.</a>
|
|
|
250
257
|
item: savedFile,
|
|
251
258
|
});
|
|
252
259
|
}
|
|
253
|
-
await cleanup();
|
|
254
260
|
}
|
|
255
261
|
catch (err) {
|
|
256
262
|
logger.error(err, `Couldn't export ${collection}: ${err.message}`);
|
|
@@ -267,6 +273,9 @@ Your export of ${collection} is ready. <a href="${href}">Click here to view.</a>
|
|
|
267
273
|
});
|
|
268
274
|
}
|
|
269
275
|
}
|
|
276
|
+
finally {
|
|
277
|
+
await tmpFile?.cleanup();
|
|
278
|
+
}
|
|
270
279
|
}
|
|
271
280
|
/**
|
|
272
281
|
* Transform a given input object / array to the given type
|
package/dist/services/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export * from './files.js';
|
|
|
9
9
|
export * from './flows.js';
|
|
10
10
|
export * from './folders.js';
|
|
11
11
|
export * from './graphql/index.js';
|
|
12
|
-
export * from './import-export.js';
|
|
12
|
+
export * from './import-export/index.js';
|
|
13
13
|
export * from './items.js';
|
|
14
14
|
export * from './mail/index.js';
|
|
15
15
|
export * from './meta.js';
|
package/dist/services/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export * from './files.js';
|
|
|
9
9
|
export * from './flows.js';
|
|
10
10
|
export * from './folders.js';
|
|
11
11
|
export * from './graphql/index.js';
|
|
12
|
-
export * from './import-export.js';
|
|
12
|
+
export * from './import-export/index.js';
|
|
13
13
|
export * from './items.js';
|
|
14
14
|
export * from './mail/index.js';
|
|
15
15
|
export * from './meta.js';
|
package/dist/services/items.js
CHANGED
|
@@ -6,9 +6,9 @@ import getDatabase from '../database/index.js';
|
|
|
6
6
|
import runAST from '../database/run-ast.js';
|
|
7
7
|
import emitter from '../emitter.js';
|
|
8
8
|
import env from '../env.js';
|
|
9
|
-
import { ForbiddenError } from '
|
|
9
|
+
import { ForbiddenError } from '@directus/errors';
|
|
10
10
|
import { translateDatabaseError } from '../database/errors/translate.js';
|
|
11
|
-
import { InvalidPayloadError } from '
|
|
11
|
+
import { InvalidPayloadError } from '@directus/errors';
|
|
12
12
|
import getASTFromQuery from '../utils/get-ast-from-query.js';
|
|
13
13
|
import { shouldClearCache } from '../utils/should-clear-cache.js';
|
|
14
14
|
import { validateKeys } from '../utils/validate-keys.js';
|
|
@@ -4,7 +4,7 @@ import path from 'path';
|
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import getDatabase from '../../database/index.js';
|
|
6
6
|
import env from '../../env.js';
|
|
7
|
-
import { InvalidPayloadError } from '
|
|
7
|
+
import { InvalidPayloadError } from '@directus/errors';
|
|
8
8
|
import logger from '../../logger.js';
|
|
9
9
|
import getMailer from '../../mailer.js';
|
|
10
10
|
import { Url } from '../../utils/url.js';
|
package/dist/services/meta.js
CHANGED
package/dist/services/payload.js
CHANGED
|
@@ -7,7 +7,7 @@ import { v4 as uuid } from 'uuid';
|
|
|
7
7
|
import { parse as wktToGeoJSON } from 'wellknown';
|
|
8
8
|
import { getHelpers } from '../database/helpers/index.js';
|
|
9
9
|
import getDatabase from '../database/index.js';
|
|
10
|
-
import { ForbiddenError, InvalidPayloadError } from '
|
|
10
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
11
11
|
import { generateHash } from '../utils/generate-hash.js';
|
|
12
12
|
import { ItemsService } from './items.js';
|
|
13
13
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PermissionsAction, Query } from '@directus/types';
|
|
2
2
|
import type Keyv from 'keyv';
|
|
3
|
-
import type { QueryOptions } from '
|
|
4
|
-
import { ItemsService } from '
|
|
3
|
+
import type { QueryOptions } from './items.js';
|
|
4
|
+
import { ItemsService } from './items.js';
|
|
5
5
|
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types/index.js';
|
|
6
6
|
export declare class PermissionsService extends ItemsService {
|
|
7
7
|
systemCache: Keyv<any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clearSystemCache, getCache } from '../cache.js';
|
|
2
2
|
import { appAccessMinimalPermissions } from '../database/system-data/app-access-permissions/index.js';
|
|
3
|
-
import { ItemsService } from '
|
|
3
|
+
import { ItemsService } from './items.js';
|
|
4
4
|
import { filterItems } from '../utils/filter-items.js';
|
|
5
5
|
export class PermissionsService extends ItemsService {
|
|
6
6
|
systemCache;
|
|
@@ -5,7 +5,7 @@ import { getHelpers } from '../database/helpers/index.js';
|
|
|
5
5
|
import getDatabase, { getSchemaInspector } from '../database/index.js';
|
|
6
6
|
import { systemRelationRows } from '../database/system-data/relations/index.js';
|
|
7
7
|
import emitter from '../emitter.js';
|
|
8
|
-
import { ForbiddenError, InvalidPayloadError } from '
|
|
8
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
9
9
|
import { getDefaultIndexName } from '../utils/get-default-index-name.js';
|
|
10
10
|
import { getSchema } from '../utils/get-schema.js';
|
|
11
11
|
import { ItemsService } from './items.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ForbiddenError, InvalidPayloadError } from '
|
|
1
|
+
import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
|
|
2
2
|
import { ItemsService } from './items.js';
|
|
3
3
|
export class RevisionsService extends ItemsService {
|
|
4
4
|
constructor(options) {
|
package/dist/services/roles.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ForbiddenError, UnprocessableContentError } from '
|
|
1
|
+
import { ForbiddenError, UnprocessableContentError } from '@directus/errors';
|
|
2
2
|
import { ItemsService } from './items.js';
|
|
3
3
|
import { PermissionsService } from './permissions.js';
|
|
4
4
|
import { PresetsService } from './presets.js';
|
package/dist/services/schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import getDatabase from '../database/index.js';
|
|
2
|
-
import { ForbiddenError } from '
|
|
2
|
+
import { ForbiddenError } from '@directus/errors';
|
|
3
3
|
import { applyDiff } from '../utils/apply-diff.js';
|
|
4
4
|
import { getSnapshotDiff } from '../utils/get-snapshot-diff.js';
|
|
5
5
|
import { getSnapshot } from '../utils/get-snapshot.js';
|