@directus/api 28.0.3 → 29.1.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.
Files changed (141) hide show
  1. package/dist/auth/drivers/openid.js +12 -6
  2. package/dist/cli/commands/init/index.js +2 -2
  3. package/dist/cli/commands/init/questions.d.ts +1 -1
  4. package/dist/cli/commands/schema/apply.js +1 -1
  5. package/dist/cli/utils/create-db-connection.d.ts +1 -1
  6. package/dist/cli/utils/create-env/index.d.ts +1 -1
  7. package/dist/cli/utils/drivers.d.ts +1 -1
  8. package/dist/constants.d.ts +1 -1
  9. package/dist/controllers/assets.js +1 -1
  10. package/dist/controllers/extensions.js +4 -4
  11. package/dist/database/get-ast-from-query/lib/parse-fields.js +3 -1
  12. package/dist/database/helpers/index.d.ts +4 -4
  13. package/dist/database/helpers/schema/types.d.ts +1 -2
  14. package/dist/database/index.d.ts +1 -1
  15. package/dist/database/migrations/20210225A-add-relations-sort-field.js +1 -1
  16. package/dist/database/migrations/20240924B-populate-versioning-deltas.js +1 -1
  17. package/dist/database/migrations/20250718A-add-direction.d.ts +3 -0
  18. package/dist/database/migrations/20250718A-add-direction.js +10 -0
  19. package/dist/database/run-ast/lib/apply-query/filter/get-filter-type.d.ts +2 -2
  20. package/dist/database/run-ast/utils/apply-parent-filters.js +2 -0
  21. package/dist/database/run-ast/utils/get-field-alias.js +2 -0
  22. package/dist/database/run-ast/utils/remove-temporary-fields.js +8 -2
  23. package/dist/extensions/lib/get-extensions-settings.d.ts +1 -1
  24. package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.d.ts +1 -1
  25. package/dist/extensions/manager.d.ts +5 -13
  26. package/dist/extensions/manager.js +39 -28
  27. package/dist/flows.d.ts +1 -2
  28. package/dist/operations/throw-error/index.d.ts +7 -0
  29. package/dist/operations/throw-error/index.js +11 -0
  30. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +2 -1
  31. package/dist/permissions/utils/fetch-share-info.d.ts +1 -1
  32. package/dist/services/access.d.ts +1 -2
  33. package/dist/services/access.js +1 -1
  34. package/dist/services/activity.d.ts +1 -1
  35. package/dist/services/assets.d.ts +1 -3
  36. package/dist/services/authentication.d.ts +1 -2
  37. package/dist/services/collections.d.ts +3 -10
  38. package/dist/services/comments.d.ts +1 -2
  39. package/dist/services/dashboards.d.ts +1 -1
  40. package/dist/services/extensions.d.ts +2 -4
  41. package/dist/services/fields.d.ts +1 -2
  42. package/dist/services/fields.js +2 -8
  43. package/dist/services/files.d.ts +2 -3
  44. package/dist/services/flows.d.ts +1 -2
  45. package/dist/services/folders.d.ts +1 -1
  46. package/dist/services/graphql/errors/format.d.ts +1 -1
  47. package/dist/services/graphql/errors/format.js +0 -1
  48. package/dist/services/graphql/index.d.ts +1 -3
  49. package/dist/services/graphql/resolvers/system-admin.d.ts +1 -1
  50. package/dist/services/graphql/resolvers/system-global.d.ts +1 -1
  51. package/dist/services/graphql/resolvers/system.d.ts +1 -1
  52. package/dist/services/graphql/schema/get-types.d.ts +1 -1
  53. package/dist/services/graphql/schema/get-types.js +0 -1
  54. package/dist/services/import-export.d.ts +2 -4
  55. package/dist/services/import-export.js +5 -3
  56. package/dist/services/items.d.ts +2 -12
  57. package/dist/services/items.js +2 -1
  58. package/dist/services/mail/index.d.ts +2 -4
  59. package/dist/services/mail/index.js +11 -5
  60. package/dist/services/meta.d.ts +1 -2
  61. package/dist/services/notifications.d.ts +1 -2
  62. package/dist/services/operations.d.ts +1 -2
  63. package/dist/services/panels.d.ts +1 -1
  64. package/dist/services/payload.d.ts +9 -17
  65. package/dist/services/payload.js +1 -1
  66. package/dist/services/permissions.d.ts +1 -3
  67. package/dist/services/policies.d.ts +1 -2
  68. package/dist/services/policies.js +1 -1
  69. package/dist/services/presets.d.ts +1 -1
  70. package/dist/services/relations.d.ts +2 -3
  71. package/dist/services/revisions.d.ts +1 -2
  72. package/dist/services/roles.d.ts +1 -2
  73. package/dist/services/roles.js +1 -1
  74. package/dist/services/schema.d.ts +1 -2
  75. package/dist/services/server.d.ts +1 -2
  76. package/dist/services/settings.d.ts +1 -1
  77. package/dist/services/shares.d.ts +1 -2
  78. package/dist/services/specifications.d.ts +1 -2
  79. package/dist/services/tfa.d.ts +1 -2
  80. package/dist/services/translations.d.ts +1 -3
  81. package/dist/services/users.d.ts +1 -2
  82. package/dist/services/users.js +1 -1
  83. package/dist/services/utils.d.ts +1 -2
  84. package/dist/services/versions.d.ts +1 -2
  85. package/dist/services/webhooks.d.ts +1 -2
  86. package/dist/services/websocket.d.ts +1 -3
  87. package/dist/types/ast.d.ts +2 -0
  88. package/dist/types/auth.d.ts +0 -6
  89. package/dist/types/index.d.ts +0 -7
  90. package/dist/types/index.js +0 -7
  91. package/dist/utils/apply-diff.d.ts +1 -2
  92. package/dist/utils/apply-diff.js +1 -1
  93. package/dist/utils/apply-snapshot.d.ts +1 -2
  94. package/dist/utils/get-ip-from-req.js +1 -1
  95. package/dist/utils/get-service.d.ts +1 -1
  96. package/dist/utils/get-snapshot-diff.d.ts +1 -1
  97. package/dist/utils/get-snapshot-diff.js +1 -1
  98. package/dist/utils/get-snapshot.d.ts +1 -2
  99. package/dist/utils/get-snapshot.js +8 -3
  100. package/dist/utils/schedule.js +4 -1
  101. package/dist/utils/should-clear-cache.d.ts +1 -1
  102. package/dist/utils/transformations.d.ts +1 -2
  103. package/dist/utils/validate-diff.d.ts +1 -1
  104. package/dist/utils/validate-diff.js +1 -1
  105. package/dist/utils/validate-snapshot.d.ts +1 -1
  106. package/dist/utils/validate-snapshot.js +1 -1
  107. package/dist/utils/validate-user-count-integrity.d.ts +1 -8
  108. package/dist/utils/validate-user-count-integrity.js +1 -9
  109. package/dist/websocket/authenticate.d.ts +2 -1
  110. package/dist/websocket/authenticate.js +25 -4
  111. package/dist/websocket/controllers/base.d.ts +2 -1
  112. package/dist/websocket/controllers/base.js +12 -15
  113. package/dist/websocket/controllers/graphql.js +5 -3
  114. package/dist/websocket/controllers/logs.js +1 -1
  115. package/dist/websocket/controllers/rest.d.ts +1 -1
  116. package/dist/websocket/controllers/rest.js +1 -1
  117. package/dist/websocket/errors.d.ts +1 -1
  118. package/dist/websocket/handlers/heartbeat.d.ts +1 -1
  119. package/dist/websocket/handlers/heartbeat.js +1 -1
  120. package/dist/websocket/messages.d.ts +57 -308
  121. package/dist/websocket/messages.js +5 -10
  122. package/dist/websocket/utils/items.d.ts +1 -1
  123. package/dist/websocket/utils/wait-for-message.d.ts +1 -1
  124. package/dist/websocket/utils/wait-for-message.js +1 -1
  125. package/package.json +86 -85
  126. package/dist/extensions/types.d.ts +0 -19
  127. package/dist/extensions/types.js +0 -1
  128. package/dist/types/assets.d.ts +0 -22
  129. package/dist/types/assets.js +0 -51
  130. package/dist/types/database.d.ts +0 -3
  131. package/dist/types/database.js +0 -1
  132. package/dist/types/graphql.d.ts +0 -14
  133. package/dist/types/graphql.js +0 -1
  134. package/dist/types/items.d.ts +0 -52
  135. package/dist/types/items.js +0 -1
  136. package/dist/types/services.d.ts +0 -22
  137. package/dist/types/services.js +0 -1
  138. package/dist/types/snapshot.d.ts +0 -55
  139. package/dist/types/snapshot.js +0 -13
  140. package/dist/types/webhooks.d.ts +0 -15
  141. package/dist/types/webhooks.js +0 -1
@@ -1,16 +1,9 @@
1
- import type { SchemaInspector, Table } from '@directus/schema';
2
- import { type BaseCollectionMeta } from '@directus/system-data';
3
- import type { Accountability, RawField, SchemaOverview } from '@directus/types';
1
+ import type { SchemaInspector } from '@directus/schema';
2
+ import type { AbstractServiceOptions, Accountability, MutationOptions, SchemaOverview, RawCollection } from '@directus/types';
4
3
  import type Keyv from 'keyv';
5
4
  import type { Knex } from 'knex';
6
5
  import type { Helpers } from '../database/helpers/index.js';
7
- import type { AbstractServiceOptions, Collection, MutationOptions } from '../types/index.js';
8
- export type RawCollection = {
9
- collection: string;
10
- fields?: RawField[];
11
- schema?: Partial<Table> | null;
12
- meta?: Partial<BaseCollectionMeta> | null;
13
- };
6
+ import type { Collection } from '../types/index.js';
14
7
  export declare class CollectionsService {
15
8
  knex: Knex;
16
9
  helpers: Helpers;
@@ -1,5 +1,4 @@
1
- import type { Comment, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Comment, MutationOptions, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  import { NotificationsService } from './notifications.js';
5
4
  import { UsersService } from './users.js';
@@ -1,4 +1,4 @@
1
- import type { AbstractServiceOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions } from '@directus/types';
2
2
  import { ItemsService } from './items.js';
3
3
  export declare class DashboardsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,8 +1,6 @@
1
- import type { ApiOutput, ExtensionSettings } from '@directus/extensions';
2
- import type { Accountability, DeepPartial, SchemaOverview } from '@directus/types';
1
+ import type { ApiOutput, ExtensionSettings, ExtensionManager } from '@directus/types';
2
+ import type { AbstractServiceOptions, Accountability, DeepPartial, SchemaOverview } from '@directus/types';
3
3
  import type { Knex } from 'knex';
4
- import type { ExtensionManager } from '../extensions/manager.js';
5
- import type { AbstractServiceOptions } from '../types/index.js';
6
4
  import { ItemsService } from './items.js';
7
5
  export declare class ExtensionReadError extends Error {
8
6
  originalError: unknown;
@@ -1,9 +1,8 @@
1
1
  import type { Column, SchemaInspector } from '@directus/schema';
2
- import type { Accountability, Field, RawField, SchemaOverview, Type } from '@directus/types';
2
+ import type { AbstractServiceOptions, Accountability, Field, MutationOptions, RawField, SchemaOverview, Type } from '@directus/types';
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 type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
7
6
  import { ItemsService } from './items.js';
8
7
  import { PayloadService } from './payload.js';
9
8
  export declare class FieldsService {
@@ -148,7 +148,7 @@ export class FieldsService {
148
148
  return data;
149
149
  });
150
150
  const knownCollections = Object.keys(this.schema.collections);
151
- const result = [...columnsWithSystem, ...aliasFieldsAsField].filter((field) => knownCollections.includes(field.collection));
151
+ let result = [...columnsWithSystem, ...aliasFieldsAsField].filter((field) => knownCollections.includes(field.collection));
152
152
  // Filter the result so we only return the fields you have read access to
153
153
  if (this.accountability && this.accountability.admin !== true) {
154
154
  const policies = await fetchPolicies(this.accountability, { knex: this.knex, schema: this.schema });
@@ -176,7 +176,7 @@ export class FieldsService {
176
176
  if (collection && collection in allowedFieldsInCollection === false) {
177
177
  throw new ForbiddenError();
178
178
  }
179
- return result.filter((field) => {
179
+ result = result.filter((field) => {
180
180
  if (field.collection in allowedFieldsInCollection === false)
181
181
  return false;
182
182
  const allowedFields = allowedFieldsInCollection[field.collection];
@@ -187,12 +187,6 @@ export class FieldsService {
187
187
  }
188
188
  // Update specific database type overrides
189
189
  for (const field of result) {
190
- if (field.meta?.special?.includes('cast-timestamp')) {
191
- field.type = 'timestamp';
192
- }
193
- else if (field.meta?.special?.includes('cast-datetime')) {
194
- field.type = 'dateTime';
195
- }
196
190
  field.type = this.helpers.schema.processFieldType(field);
197
191
  }
198
192
  return result;
@@ -1,7 +1,6 @@
1
- import type { BusboyFileStream, File, PrimaryKey, Query } from '@directus/types';
1
+ import type { AbstractServiceOptions, BusboyFileStream, File, MutationOptions, PrimaryKey, Query, QueryOptions } from '@directus/types';
2
2
  import type { Readable } from 'node:stream';
3
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
4
- import { ItemsService, type QueryOptions } from './items.js';
3
+ import { ItemsService } from './items.js';
5
4
  export declare class FilesService extends ItemsService<File> {
6
5
  constructor(options: AbstractServiceOptions);
7
6
  /**
@@ -1,5 +1,4 @@
1
- import type { FlowRaw, Item, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, FlowRaw, Item, MutationOptions, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class FlowsService extends ItemsService<FlowRaw> {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,4 +1,4 @@
1
- import type { AbstractServiceOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions } from '@directus/types';
2
2
  import { ItemsService } from './items.js';
3
3
  export declare class FoldersService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,4 +1,4 @@
1
- import { type DirectusError } from '@directus/errors';
1
+ import type { DirectusError } from '@directus/errors';
2
2
  import { GraphQLError } from 'graphql';
3
3
  /**
4
4
  * Convert Directus-Exception into a GraphQL format, so it can be returned by GraphQL properly.
@@ -1,4 +1,3 @@
1
- import {} from '@directus/errors';
2
1
  import { GraphQLError } from 'graphql';
3
2
  import { set } from 'lodash-es';
4
3
  /**
@@ -1,8 +1,6 @@
1
- import type { Accountability, Item, Query, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, GraphQLParams, GQLScope, Item, Query, SchemaOverview } from '@directus/types';
2
2
  import type { FormattedExecutionResult, GraphQLSchema } from 'graphql';
3
3
  import type { Knex } from 'knex';
4
- import type { AbstractServiceOptions, GraphQLParams } from '../../types/index.js';
5
- export type GQLScope = 'items' | 'system';
6
4
  export declare class GraphQLService {
7
5
  accountability: Accountability | null;
8
6
  knex: Knex;
@@ -1,5 +1,5 @@
1
+ import type { GraphQLParams } from '@directus/types';
1
2
  import { SchemaComposer } from 'graphql-compose';
2
- import type { GraphQLParams } from '../../../types/index.js';
3
3
  import { GraphQLService } from '../index.js';
4
4
  import type { Schema } from '../schema/index.js';
5
5
  export declare function resolveSystemAdmin(gql: GraphQLService, schema: Schema, schemaComposer: SchemaComposer<GraphQLParams['contextValue']>): void;
@@ -1,5 +1,5 @@
1
+ import type { GraphQLParams } from '@directus/types';
1
2
  import { SchemaComposer } from 'graphql-compose';
2
- import type { GraphQLParams } from '../../../types/index.js';
3
3
  import { GraphQLService } from '../index.js';
4
4
  /**
5
5
  * Globally available mutations
@@ -1,5 +1,5 @@
1
+ import type { GraphQLParams } from '@directus/types';
1
2
  import { SchemaComposer } from 'graphql-compose';
2
- import type { GraphQLParams } from '../../../types/index.js';
3
3
  import { GraphQLService } from '../index.js';
4
4
  import { type CollectionTypes, type Schema } from '../schema/index.js';
5
5
  export declare function injectSystemResolvers(gql: GraphQLService, schemaComposer: SchemaComposer<GraphQLParams['contextValue']>, { CreateCollectionTypes, ReadCollectionTypes, UpdateCollectionTypes }: CollectionTypes, schema: Schema): SchemaComposer<any>;
@@ -1,6 +1,6 @@
1
1
  import type { SchemaComposer } from 'graphql-compose';
2
2
  import { ObjectTypeComposer } from 'graphql-compose';
3
- import { type GQLScope } from '../index.js';
3
+ import type { GQLScope } from '@directus/types';
4
4
  import { type InconsistentFields, type Schema } from './index.js';
5
5
  /**
6
6
  * Construct an object of types for every collection, using the permitted fields per action type
@@ -3,7 +3,6 @@ import { GraphQLJSON, ObjectTypeComposer } from 'graphql-compose';
3
3
  import { mapKeys, pick } from 'lodash-es';
4
4
  import { GENERATE_SPECIAL } from '../../../constants.js';
5
5
  import { getGraphQLType } from '../../../utils/get-graphql-type.js';
6
- import {} from '../index.js';
7
6
  import { SYSTEM_DENY_LIST } from './index.js';
8
7
  /**
9
8
  * Construct an object of types for every collection, using the permitted fields per action type
@@ -1,8 +1,7 @@
1
- import type { Accountability, File, Query, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, ExportFormat, File, Query, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
3
  import type { Readable } from 'node:stream';
4
- import type { AbstractServiceOptions, FunctionFieldNode, FieldNode, NestedCollectionNode } from '../types/index.js';
5
- type ExportFormat = 'csv' | 'json' | 'xml' | 'yaml';
4
+ import type { FunctionFieldNode, FieldNode, NestedCollectionNode } from '../types/index.js';
6
5
  export declare class ImportService {
7
6
  knex: Knex;
8
7
  accountability: Accountability | null;
@@ -35,4 +34,3 @@ export declare class ExportService {
35
34
  }): string;
36
35
  }
37
36
  export declare function getHeadingsForCsvExport(nodes: (NestedCollectionNode | FieldNode | FunctionFieldNode)[] | undefined, prefix?: string): string[];
38
- export {};
@@ -25,6 +25,7 @@ import { FilesService } from './files.js';
25
25
  import { NotificationsService } from './notifications.js';
26
26
  import { UsersService } from './users.js';
27
27
  import { parseFields } from '../database/get-ast-from-query/lib/parse-fields.js';
28
+ import { set } from 'lodash-es';
28
29
  const env = useEnv();
29
30
  const logger = useLogger();
30
31
  export class ImportService {
@@ -166,13 +167,14 @@ export class ImportService {
166
167
  fileReadStream
167
168
  .pipe(Papa.parse(Papa.NODE_STREAM_INPUT, PapaOptions))
168
169
  .on('data', (obj) => {
170
+ const result = {};
169
171
  // Filter out all undefined fields
170
172
  for (const field in obj) {
171
- if (obj[field] === undefined) {
172
- delete obj[field];
173
+ if (obj[field] !== undefined) {
174
+ set(result, field, obj[field]);
173
175
  }
174
176
  }
175
- saveQueue.push(obj);
177
+ saveQueue.push(result);
176
178
  })
177
179
  .on('error', (error) => {
178
180
  cleanup();
@@ -1,17 +1,7 @@
1
- import type { Accountability, Item as AnyItem, PermissionsAction, PrimaryKey, Query, SchemaOverview } from '@directus/types';
1
+ import type { AbstractService, AbstractServiceOptions, Accountability, Item as AnyItem, MutationTracker, MutationOptions, PrimaryKey, Query, QueryOptions, SchemaOverview } from '@directus/types';
2
2
  import type Keyv from 'keyv';
3
3
  import type { Knex } from 'knex';
4
- import type { AbstractService, AbstractServiceOptions, MutationOptions } from '../types/index.js';
5
- export type QueryOptions = {
6
- stripNonRequested?: boolean;
7
- permissionsAction?: PermissionsAction;
8
- emitEvents?: boolean;
9
- };
10
- export type MutationTracker = {
11
- trackMutations: (count: number) => void;
12
- getCount: () => number;
13
- };
14
- export declare class ItemsService<Item extends AnyItem = AnyItem, Collection extends string = string> implements AbstractService {
4
+ export declare class ItemsService<Item extends AnyItem = AnyItem, Collection extends string = string> implements AbstractService<Item> {
15
5
  collection: Collection;
16
6
  knex: Knex;
17
7
  accountability: Accountability | null;
@@ -2,6 +2,7 @@ import { Action } from '@directus/constants';
2
2
  import { useEnv } from '@directus/env';
3
3
  import { ErrorCode, ForbiddenError, InvalidPayloadError, isDirectusError } from '@directus/errors';
4
4
  import { isSystemCollection } from '@directus/system-data';
5
+ import { UserIntegrityCheckFlag } from '@directus/types';
5
6
  import { assign, clone, cloneDeep, omit, pick, without } from 'lodash-es';
6
7
  import { getCache } from '../cache.js';
7
8
  import { translateDatabaseError } from '../database/errors/translate.js';
@@ -16,7 +17,7 @@ import { validateAccess } from '../permissions/modules/validate-access/validate-
16
17
  import { shouldClearCache } from '../utils/should-clear-cache.js';
17
18
  import { transaction } from '../utils/transaction.js';
18
19
  import { validateKeys } from '../utils/validate-keys.js';
19
- import { UserIntegrityCheckFlag, validateUserCountIntegrity } from '../utils/validate-user-count-integrity.js';
20
+ import { validateUserCountIntegrity } from '../utils/validate-user-count-integrity.js';
20
21
  import { PayloadService } from './payload.js';
21
22
  const env = useEnv();
22
23
  export class ItemsService {
@@ -1,9 +1,7 @@
1
- import type { Accountability, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
3
  import type { SendMailOptions, Transporter } from 'nodemailer';
4
- import type { AbstractServiceOptions } from '../../types/index.js';
5
- export type EmailOptions = Omit<SendMailOptions, 'from'> & {
6
- from?: string;
4
+ export type EmailOptions = SendMailOptions & {
7
5
  template?: {
8
6
  name: string;
9
7
  data: Record<string, any>;
@@ -1,14 +1,15 @@
1
1
  import { useEnv } from '@directus/env';
2
2
  import { InvalidPayloadError } from '@directus/errors';
3
+ import { isObject } from '@directus/utils';
3
4
  import fse from 'fs-extra';
4
5
  import { Liquid } from 'liquidjs';
5
6
  import path from 'path';
6
7
  import { fileURLToPath } from 'url';
7
8
  import getDatabase from '../../database/index.js';
9
+ import emitter from '../../emitter.js';
8
10
  import { useLogger } from '../../logger/index.js';
9
11
  import getMailer from '../../mailer.js';
10
12
  import { Url } from '../../utils/url.js';
11
- import emitter from '../../emitter.js';
12
13
  const env = useEnv();
13
14
  const logger = useLogger();
14
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -42,10 +43,15 @@ export class MailService {
42
43
  const { template, ...emailOptions } = payload;
43
44
  let { html } = options;
44
45
  const defaultTemplateData = await this.getDefaultTemplateData();
45
- const from = {
46
- name: defaultTemplateData.projectName,
47
- address: options.from || env['EMAIL_FROM'],
48
- };
46
+ if (isObject(emailOptions.from) && (!emailOptions.from.name || !emailOptions.from.address)) {
47
+ throw new InvalidPayloadError({ reason: 'A name and address property are required in the "from" object' });
48
+ }
49
+ const from = isObject(emailOptions.from)
50
+ ? emailOptions.from
51
+ : {
52
+ name: defaultTemplateData.projectName,
53
+ address: emailOptions.from || env['EMAIL_FROM'],
54
+ };
49
55
  if (template) {
50
56
  let templateData = template.data;
51
57
  templateData = {
@@ -1,6 +1,5 @@
1
- import type { Accountability, Query, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, Query, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
- import type { AbstractServiceOptions } from '../types/index.js';
4
3
  export declare class MetaService {
5
4
  knex: Knex;
6
5
  accountability: Accountability | null;
@@ -1,5 +1,4 @@
1
- import type { Notification, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, MutationOptions, Notification, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class NotificationsService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,4 @@
1
- import type { Item, OperationRaw, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, OperationRaw, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class OperationsService extends ItemsService<OperationRaw> {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,4 +1,4 @@
1
- import type { AbstractServiceOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions } from '@directus/types';
2
2
  import { ItemsService } from './items.js';
3
3
  export declare class PanelsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,12 +1,9 @@
1
- import type { Accountability, Aggregate, FieldOverview, Item, PrimaryKey, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, Aggregate, FieldOverview, Item, MutationOptions, PayloadAction, PayloadServiceProcessRelationResult, PrimaryKey, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
3
  import type { Helpers } from '../database/helpers/index.js';
4
- import type { AbstractServiceOptions, ActionEventParams, MutationOptions } from '../types/index.js';
5
- import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
6
- type Action = 'create' | 'read' | 'update';
7
4
  type Transformers = {
8
5
  [type: string]: (context: {
9
- action: Action;
6
+ action: PayloadAction;
10
7
  value: any;
11
8
  payload: Partial<Item>;
12
9
  accountability: Accountability | null;
@@ -14,11 +11,6 @@ type Transformers = {
14
11
  helpers: Helpers;
15
12
  }) => Promise<any>;
16
13
  };
17
- type PayloadServiceProcessRelationResult = {
18
- revisions: PrimaryKey[];
19
- nestedActionEvents: ActionEventParams[];
20
- userIntegrityCheckFlags: UserIntegrityCheckFlag;
21
- };
22
14
  /**
23
15
  * Process a given payload for a collection to ensure the special fields (hash, uuid, date etc) are
24
16
  * handled correctly.
@@ -32,24 +24,24 @@ export declare class PayloadService {
32
24
  nested: string[];
33
25
  constructor(collection: string, options: AbstractServiceOptions);
34
26
  transformers: Transformers;
35
- processValues(action: Action, payloads: Partial<Item>[]): Promise<Partial<Item>[]>;
36
- processValues(action: Action, payload: Partial<Item>): Promise<Partial<Item>>;
37
- processValues(action: Action, payloads: Partial<Item>[], aliasMap: Record<string, string>, aggregate: Aggregate): Promise<Partial<Item>[]>;
38
- processValues(action: Action, payload: Partial<Item>, aliasMap: Record<string, string>, aggregate: Aggregate): Promise<Partial<Item>>;
27
+ processValues(action: PayloadAction, payloads: Partial<Item>[]): Promise<Partial<Item>[]>;
28
+ processValues(action: PayloadAction, payload: Partial<Item>): Promise<Partial<Item>>;
29
+ processValues(action: PayloadAction, payloads: Partial<Item>[], aliasMap: Record<string, string>, aggregate: Aggregate): Promise<Partial<Item>[]>;
30
+ processValues(action: PayloadAction, payload: Partial<Item>, aliasMap: Record<string, string>, aggregate: Aggregate): Promise<Partial<Item>>;
39
31
  processAggregates(payload: Partial<Item>[], aggregate?: Aggregate): void;
40
- processField(field: SchemaOverview['collections'][string]['fields'][string], payload: Partial<Item>, action: Action, accountability: Accountability | null): Promise<any>;
32
+ processField(field: SchemaOverview['collections'][string]['fields'][string], payload: Partial<Item>, action: PayloadAction, accountability: Accountability | null): Promise<any>;
41
33
  /**
42
34
  * Native geometries are stored in custom binary format. We need to insert them with
43
35
  * the function st_geomfromtext. For this to work, that function call must not be
44
36
  * escaped. It's therefore placed as a Knex.Raw object in the payload. Thus the need
45
37
  * to check if the value is a raw instance before stringifying it in the next step.
46
38
  */
47
- processGeometries<T extends Partial<Record<string, any>>[]>(fieldEntries: [string, FieldOverview][], payloads: T, action: Action): T;
39
+ processGeometries<T extends Partial<Record<string, any>>[]>(fieldEntries: [string, FieldOverview][], payloads: T, action: PayloadAction): T;
48
40
  /**
49
41
  * Knex returns `datetime` and `date` columns as Date.. This is wrong for date / datetime, as those
50
42
  * shouldn't return with time / timezone info respectively
51
43
  */
52
- processDates(fieldEntries: [string, FieldOverview][], payloads: Partial<Record<string, any>>[], action: Action, aliasMap?: Record<string, string>, aggregate?: Aggregate): Partial<Record<string, any>>[];
44
+ processDates(fieldEntries: [string, FieldOverview][], payloads: Partial<Record<string, any>>[], action: PayloadAction, aliasMap?: Record<string, string>, aggregate?: Aggregate): Partial<Record<string, any>>[];
53
45
  /**
54
46
  * Recursively save/update all nested related Any-to-One items
55
47
  */
@@ -1,4 +1,5 @@
1
1
  import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
2
+ import { UserIntegrityCheckFlag } from '@directus/types';
2
3
  import { parseJSON, toArray } from '@directus/utils';
3
4
  import { format, isValid, parseISO } from 'date-fns';
4
5
  import { unflatten } from 'flat';
@@ -9,7 +10,6 @@ import { parse as wktToGeoJSON } from 'wellknown';
9
10
  import { getHelpers } from '../database/helpers/index.js';
10
11
  import getDatabase from '../database/index.js';
11
12
  import { generateHash } from '../utils/generate-hash.js';
12
- import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
13
13
  /**
14
14
  * Process a given payload for a collection to ensure the special fields (hash, uuid, date etc) are
15
15
  * handled correctly.
@@ -1,6 +1,4 @@
1
- import type { Item, ItemPermissions, PrimaryKey, Query } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
3
- import type { QueryOptions } from './items.js';
1
+ import type { AbstractServiceOptions, Item, ItemPermissions, MutationOptions, PrimaryKey, Query, QueryOptions } from '@directus/types';
4
2
  import { ItemsService } from './items.js';
5
3
  export declare class PermissionsService extends ItemsService {
6
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,4 @@
1
- import type { Policy, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, MutationOptions, Policy, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class PoliciesService extends ItemsService<Policy> {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,8 +1,8 @@
1
1
  import { InvalidPayloadError } from '@directus/errors';
2
+ import { UserIntegrityCheckFlag } from '@directus/types';
2
3
  import { getMatch } from 'ip-matching';
3
4
  import { clearSystemCache } from '../cache.js';
4
5
  import { clearCache as clearPermissionsCache } from '../permissions/cache.js';
5
- import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
6
6
  import { ItemsService } from './items.js';
7
7
  export class PoliciesService extends ItemsService {
8
8
  constructor(options) {
@@ -1,4 +1,4 @@
1
- import type { AbstractServiceOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions } from '@directus/types';
2
2
  import { ItemsService } from './items.js';
3
3
  export declare class PresetsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,10 +1,9 @@
1
1
  import type { ForeignKey, SchemaInspector } from '@directus/schema';
2
- import type { Accountability, Relation, RelationMeta, SchemaOverview } from '@directus/types';
2
+ import type { AbstractServiceOptions, Accountability, MutationOptions, QueryOptions, Relation, RelationMeta, SchemaOverview } from '@directus/types';
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 type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
7
- import { ItemsService, type QueryOptions } from './items.js';
6
+ import { ItemsService } from './items.js';
8
7
  export declare class RelationsService {
9
8
  knex: Knex;
10
9
  schemaInspector: SchemaInspector;
@@ -1,5 +1,4 @@
1
- import type { Item, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class RevisionsService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,4 @@
1
- import type { Item, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class RolesService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,8 +1,8 @@
1
1
  import { InvalidPayloadError } from '@directus/errors';
2
+ import { UserIntegrityCheckFlag } from '@directus/types';
2
3
  import { clearSystemCache } from '../cache.js';
3
4
  import { fetchRolesTree } from '../permissions/lib/fetch-roles-tree.js';
4
5
  import { transaction } from '../utils/transaction.js';
5
- import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
6
6
  import { ItemsService } from './items.js';
7
7
  import { AccessService } from './access.js';
8
8
  import { PresetsService } from './presets.js';
@@ -1,6 +1,5 @@
1
- import type { Accountability } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, Snapshot, SnapshotDiff, SnapshotDiffWithHash, SnapshotWithHash } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
- import type { AbstractServiceOptions, Snapshot, SnapshotDiff, SnapshotDiffWithHash, SnapshotWithHash } from '../types/index.js';
4
3
  export declare class SchemaService {
5
4
  knex: Knex;
6
5
  accountability: Accountability | null;
@@ -1,6 +1,5 @@
1
- import type { Accountability, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
- import type { AbstractServiceOptions } from '../types/index.js';
4
3
  import { SettingsService } from './settings.js';
5
4
  export declare class ServerService {
6
5
  knex: Knex;
@@ -1,4 +1,4 @@
1
- import type { AbstractServiceOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions } from '@directus/types';
2
2
  import { ItemsService } from './items.js';
3
3
  export declare class SettingsService extends ItemsService {
4
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,4 @@
1
- import type { Item, PrimaryKey } from '@directus/types';
2
- import type { AbstractServiceOptions, LoginResult, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, LoginResult, MutationOptions, PrimaryKey } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class SharesService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,7 +1,6 @@
1
- import type { Accountability, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
3
  import type { OpenAPIObject } from 'openapi3-ts/oas30';
4
- import type { AbstractServiceOptions } from '../types/index.js';
5
4
  import { GraphQLService } from './graphql/index.js';
6
5
  export declare class SpecificationService {
7
6
  accountability: Accountability | null;
@@ -1,6 +1,5 @@
1
- import type { PrimaryKey } from '@directus/types';
1
+ import type { AbstractServiceOptions, PrimaryKey } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
- import type { AbstractServiceOptions } from '../types/index.js';
4
3
  import { ItemsService } from './items.js';
5
4
  export declare class TFAService {
6
5
  knex: Knex;
@@ -1,6 +1,4 @@
1
- import type { Item, PrimaryKey } from '@directus/types';
2
- import type { MutationOptions } from '../types/items.js';
3
- import type { AbstractServiceOptions } from '../types/services.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '@directus/types';
4
2
  import { ItemsService } from './items.js';
5
3
  export declare class TranslationsService extends ItemsService {
6
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,4 @@
1
- import type { Item, PrimaryKey, RegisterUserInput } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey, RegisterUserInput } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class UsersService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);
@@ -1,5 +1,6 @@
1
1
  import { useEnv } from '@directus/env';
2
2
  import { ForbiddenError, InvalidPayloadError, RecordNotUniqueError } from '@directus/errors';
3
+ import { UserIntegrityCheckFlag } from '@directus/types';
3
4
  import { getSimpleHash, toArray, validatePayload } from '@directus/utils';
4
5
  import { FailedValidationError, joiValidationErrorItemToErrorExtensions } from '@directus/validation';
5
6
  import Joi from 'joi';
@@ -16,7 +17,6 @@ import isUrlAllowed from '../utils/is-url-allowed.js';
16
17
  import { verifyJWT } from '../utils/jwt.js';
17
18
  import { stall } from '../utils/stall.js';
18
19
  import { Url } from '../utils/url.js';
19
- import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
20
20
  import { ItemsService } from './items.js';
21
21
  import { MailService } from './mail/index.js';
22
22
  import { SettingsService } from './settings.js';
@@ -1,6 +1,5 @@
1
- import type { Accountability, PrimaryKey, SchemaOverview } from '@directus/types';
1
+ import type { AbstractServiceOptions, Accountability, PrimaryKey, SchemaOverview } from '@directus/types';
2
2
  import type { Knex } from 'knex';
3
- import type { AbstractServiceOptions } from '../types/index.js';
4
3
  export declare class UtilsService {
5
4
  knex: Knex;
6
5
  accountability: Accountability | null;
@@ -1,5 +1,4 @@
1
- import type { Item, PrimaryKey, Query } from '@directus/types';
2
- import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
1
+ import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey, Query } from '@directus/types';
3
2
  import { ItemsService } from './items.js';
4
3
  export declare class VersionsService extends ItemsService {
5
4
  constructor(options: AbstractServiceOptions);