@directus/api 17.0.0 → 17.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 (79) hide show
  1. package/dist/controllers/fields.js +0 -3
  2. package/dist/controllers/items.js +8 -7
  3. package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.d.ts +1 -1
  4. package/dist/flows.js +2 -1
  5. package/dist/middleware/collection-exists.js +6 -6
  6. package/dist/operations/item-update/index.js +4 -1
  7. package/dist/operations/request/index.js +5 -5
  8. package/dist/request/agent-with-ip-validation.d.ts +11 -0
  9. package/dist/request/agent-with-ip-validation.js +34 -0
  10. package/dist/request/index.js +6 -5
  11. package/dist/request/is-denied-ip.d.ts +1 -0
  12. package/dist/request/{validate-ip.js → is-denied-ip.js} +10 -12
  13. package/dist/services/collections.d.ts +3 -2
  14. package/dist/services/collections.js +1 -1
  15. package/dist/services/fields.js +8 -1
  16. package/dist/services/files.js +4 -3
  17. package/dist/services/graphql/index.js +3 -2
  18. package/dist/services/import-export.js +62 -26
  19. package/dist/services/items.js +2 -1
  20. package/dist/services/permissions.js +1 -1
  21. package/dist/services/relations.js +1 -1
  22. package/dist/services/roles.d.ts +9 -4
  23. package/dist/services/roles.js +50 -2
  24. package/dist/services/specifications.js +4 -3
  25. package/dist/services/utils.js +1 -1
  26. package/dist/telemetry/utils/get-user-item-count.js +2 -1
  27. package/dist/types/collection.d.ts +2 -13
  28. package/dist/utils/get-field-system-rows.d.ts +2 -0
  29. package/dist/utils/get-field-system-rows.js +17 -0
  30. package/dist/utils/get-permissions.js +1 -1
  31. package/dist/utils/get-schema.js +3 -2
  32. package/dist/utils/merge-permissions-for-share.js +1 -1
  33. package/dist/utils/should-skip-cache.js +1 -1
  34. package/dist/websocket/controllers/hooks.js +1 -1
  35. package/dist/websocket/handlers/items.js +2 -1
  36. package/dist/websocket/messages.d.ts +18 -18
  37. package/package.json +42 -41
  38. package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +0 -107
  39. package/dist/database/system-data/app-access-permissions/index.d.ts +0 -3
  40. package/dist/database/system-data/app-access-permissions/index.js +0 -17
  41. package/dist/database/system-data/app-access-permissions/schema-access-permissions.yaml +0 -17
  42. package/dist/database/system-data/collections/collections.yaml +0 -103
  43. package/dist/database/system-data/collections/index.d.ts +0 -2
  44. package/dist/database/system-data/collections/index.js +0 -9
  45. package/dist/database/system-data/fields/_defaults.yaml +0 -16
  46. package/dist/database/system-data/fields/activity.yaml +0 -83
  47. package/dist/database/system-data/fields/collections.yaml +0 -249
  48. package/dist/database/system-data/fields/dashboards.yaml +0 -20
  49. package/dist/database/system-data/fields/extensions.yaml +0 -10
  50. package/dist/database/system-data/fields/fields.yaml +0 -104
  51. package/dist/database/system-data/fields/files.yaml +0 -160
  52. package/dist/database/system-data/fields/flows.yaml +0 -26
  53. package/dist/database/system-data/fields/folders.yaml +0 -14
  54. package/dist/database/system-data/fields/index.d.ts +0 -2
  55. package/dist/database/system-data/fields/index.js +0 -33
  56. package/dist/database/system-data/fields/migrations.yaml +0 -10
  57. package/dist/database/system-data/fields/notifications.yaml +0 -15
  58. package/dist/database/system-data/fields/operations.yaml +0 -23
  59. package/dist/database/system-data/fields/panels.yaml +0 -29
  60. package/dist/database/system-data/fields/permissions.yaml +0 -37
  61. package/dist/database/system-data/fields/presets.yaml +0 -56
  62. package/dist/database/system-data/fields/relations.yaml +0 -34
  63. package/dist/database/system-data/fields/revisions.yaml +0 -30
  64. package/dist/database/system-data/fields/roles.yaml +0 -61
  65. package/dist/database/system-data/fields/sessions.yaml +0 -16
  66. package/dist/database/system-data/fields/settings.yaml +0 -471
  67. package/dist/database/system-data/fields/shares.yaml +0 -83
  68. package/dist/database/system-data/fields/translations.yaml +0 -27
  69. package/dist/database/system-data/fields/users.yaml +0 -224
  70. package/dist/database/system-data/fields/versions.yaml +0 -38
  71. package/dist/database/system-data/fields/webhooks.yaml +0 -141
  72. package/dist/database/system-data/relations/index.d.ts +0 -2
  73. package/dist/database/system-data/relations/index.js +0 -9
  74. package/dist/database/system-data/relations/relations.yaml +0 -197
  75. package/dist/request/request-interceptor.d.ts +0 -2
  76. package/dist/request/request-interceptor.js +0 -28
  77. package/dist/request/response-interceptor.d.ts +0 -2
  78. package/dist/request/response-interceptor.js +0 -5
  79. package/dist/request/validate-ip.d.ts +0 -1
@@ -1,4 +1,5 @@
1
- import { ForbiddenError, UnprocessableContentError } from '@directus/errors';
1
+ import { ForbiddenError, InvalidPayloadError, UnprocessableContentError } from '@directus/errors';
2
+ import { getMatch } from 'ip-matching';
2
3
  import { ItemsService } from './items.js';
3
4
  import { PermissionsService } from './permissions.js';
4
5
  import { PresetsService } from './presets.js';
@@ -74,7 +75,7 @@ export class RolesService extends ItemsService {
74
75
  .count('*', { as: 'count' })
75
76
  .from('directus_users')
76
77
  .leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
77
- .whereNotIn('directus_users.id', usersAdded)
78
+ .whereNotIn('directus_users.id', usersAdded.map((user) => user.id))
78
79
  .andWhere({ 'directus_roles.admin_access': true, status: 'active' })
79
80
  .first();
80
81
  const otherAdminUsersCount = Number(otherAdminUsers?.count ?? 0);
@@ -121,7 +122,46 @@ export class RolesService extends ItemsService {
121
122
  }
122
123
  return;
123
124
  }
125
+ isIpAccessValid(value) {
126
+ if (value === undefined)
127
+ return false;
128
+ if (value === null)
129
+ return true;
130
+ if (Array.isArray(value) && value.length === 0)
131
+ return true;
132
+ for (const ip of value) {
133
+ if (typeof ip !== 'string' || ip.includes('*'))
134
+ return false;
135
+ try {
136
+ const match = getMatch(ip);
137
+ if (match.type == 'IPMask')
138
+ return false;
139
+ }
140
+ catch {
141
+ return false;
142
+ }
143
+ }
144
+ return true;
145
+ }
146
+ assertValidIpAccess(partialItem) {
147
+ if ('ip_access' in partialItem && !this.isIpAccessValid(partialItem['ip_access'])) {
148
+ throw new InvalidPayloadError({
149
+ reason: 'IP Access contains an incorrect value. Valid values are: IP addresses, IP ranges and CIDR blocks',
150
+ });
151
+ }
152
+ }
153
+ async createOne(data, opts) {
154
+ this.assertValidIpAccess(data);
155
+ return super.createOne(data, opts);
156
+ }
157
+ async createMany(data, opts) {
158
+ for (const partialItem of data) {
159
+ this.assertValidIpAccess(partialItem);
160
+ }
161
+ return super.createMany(data, opts);
162
+ }
124
163
  async updateOne(key, data, opts) {
164
+ this.assertValidIpAccess(data);
125
165
  try {
126
166
  if ('users' in data) {
127
167
  await this.checkForOtherAdminUsers(key, data['users']);
@@ -133,6 +173,9 @@ export class RolesService extends ItemsService {
133
173
  return super.updateOne(key, data, opts);
134
174
  }
135
175
  async updateBatch(data, opts) {
176
+ for (const partialItem of data) {
177
+ this.assertValidIpAccess(partialItem);
178
+ }
136
179
  const primaryKeyField = this.schema.collections[this.collection].primary;
137
180
  const keys = data.map((item) => item[primaryKeyField]);
138
181
  const setsToNoAdmin = data.some((item) => item['admin_access'] === false);
@@ -147,6 +190,7 @@ export class RolesService extends ItemsService {
147
190
  return super.updateBatch(data, opts);
148
191
  }
149
192
  async updateMany(keys, data, opts) {
193
+ this.assertValidIpAccess(data);
150
194
  try {
151
195
  if ('admin_access' in data && data['admin_access'] === false) {
152
196
  await this.checkForOtherAdminRoles(keys);
@@ -157,6 +201,10 @@ export class RolesService extends ItemsService {
157
201
  }
158
202
  return super.updateMany(keys, data, opts);
159
203
  }
204
+ async updateByQuery(query, data, opts) {
205
+ this.assertValidIpAccess(data);
206
+ return super.updateByQuery(query, data, opts);
207
+ }
160
208
  async deleteOne(key) {
161
209
  await this.deleteMany([key]);
162
210
  return key;
@@ -8,6 +8,7 @@ import getDatabase from '../database/index.js';
8
8
  import { getRelationType } from '../utils/get-relation-type.js';
9
9
  import { reduceSchema } from '../utils/reduce-schema.js';
10
10
  import { GraphQLService } from './graphql/index.js';
11
+ import { isSystemCollection } from '@directus/system-data';
11
12
  const env = useEnv();
12
13
  export class SpecificationService {
13
14
  accountability;
@@ -77,7 +78,7 @@ class OASSpecsService {
77
78
  }
78
79
  }
79
80
  for (const collection of collections) {
80
- const isSystem = collection.collection.startsWith('directus_');
81
+ const isSystem = isSystemCollection(collection.collection);
81
82
  // If the collection is one of the system collections, pull the tag from the static spec
82
83
  if (isSystem) {
83
84
  for (const tag of spec.tags) {
@@ -106,7 +107,7 @@ class OASSpecsService {
106
107
  if (!tags)
107
108
  return paths;
108
109
  for (const tag of tags) {
109
- const isSystem = 'x-collection' in tag === false || tag['x-collection'].startsWith('directus_');
110
+ const isSystem = 'x-collection' in tag === false || isSystemCollection(tag['x-collection']);
110
111
  if (isSystem) {
111
112
  for (const [path, pathItem] of Object.entries(spec.paths)) {
112
113
  for (const [method, operation] of Object.entries(pathItem)) {
@@ -268,7 +269,7 @@ class OASSpecsService {
268
269
  const tag = tags.find((tag) => tag['x-collection'] === collection.collection);
269
270
  if (!tag)
270
271
  continue;
271
- const isSystem = collection.collection.startsWith('directus_');
272
+ const isSystem = isSystemCollection(collection.collection);
272
273
  const fieldsInCollection = Object.values(collection.fields);
273
274
  if (isSystem) {
274
275
  const schemaComponent = cloneDeep(spec.components.schemas[tag.name]);
@@ -1,6 +1,6 @@
1
1
  import { flushCaches, getCache } from '../cache.js';
2
2
  import getDatabase from '../database/index.js';
3
- import { systemCollectionRows } from '../database/system-data/collections/index.js';
3
+ import { systemCollectionRows } from '@directus/system-data';
4
4
  import emitter from '../emitter.js';
5
5
  import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
6
6
  import { shouldClearCache } from '../utils/should-clear-cache.js';
@@ -1,6 +1,7 @@
1
1
  import {} from 'knex';
2
2
  import { getSchema } from '../../utils/get-schema.js';
3
3
  import { getItemCount } from './get-item-count.js';
4
+ import { isSystemCollection } from '@directus/system-data';
4
5
  /**
5
6
  * Sum all passed values together. Meant to be used with .reduce()
6
7
  */
@@ -10,7 +11,7 @@ export const sum = (acc, val) => (acc += val);
10
11
  */
11
12
  export const getUserItemCount = async (db) => {
12
13
  const schema = await getSchema({ database: db });
13
- const userCollections = Object.keys(schema.collections).filter((collection) => collection.startsWith('directus_') === false);
14
+ const userCollections = Object.keys(schema.collections).filter((collection) => isSystemCollection(collection) === false);
14
15
  const counts = await getItemCount(db, userCollections);
15
16
  const collections = userCollections.length;
16
17
  const items = Object.values(counts).reduce(sum, 0);
@@ -1,20 +1,9 @@
1
1
  import type { Field } from '@directus/types';
2
2
  import type { Table } from '@directus/schema';
3
- export type CollectionMeta = {
4
- collection: string;
5
- note: string | null;
6
- hidden: boolean;
7
- singleton: boolean;
8
- icon: string | null;
9
- translations: Record<string, string>;
10
- versioning: boolean;
11
- item_duplication_fields: string[] | null;
12
- accountability: 'all' | 'accountability' | null;
13
- group: string | null;
14
- };
3
+ import type { BaseCollectionMeta } from '@directus/system-data';
15
4
  export type Collection = {
16
5
  collection: string;
17
6
  fields?: Field[];
18
- meta: CollectionMeta | null;
7
+ meta: BaseCollectionMeta | null;
19
8
  schema: Table | null;
20
9
  };
@@ -0,0 +1,2 @@
1
+ import type { FieldMeta } from '@directus/types';
2
+ export declare function getSystemFieldRowsWithAuthProviders(): FieldMeta[];
@@ -0,0 +1,17 @@
1
+ import { systemFieldRows } from '@directus/system-data';
2
+ import formatTitle from '@directus/format-title';
3
+ import { getAuthProviders } from './get-auth-providers.js';
4
+ // Dynamically populate auth providers field
5
+ export function getSystemFieldRowsWithAuthProviders() {
6
+ return systemFieldRows.map((systemField) => {
7
+ if (systemField.collection === 'directus_users' && systemField.field === 'provider') {
8
+ if (!systemField.options)
9
+ systemField.options = {};
10
+ systemField.options['choices'] = getAuthProviders().map(({ name }) => ({
11
+ text: formatTitle(name),
12
+ value: name,
13
+ }));
14
+ }
15
+ return systemField;
16
+ });
17
+ }
@@ -4,7 +4,7 @@ import { cloneDeep } from 'lodash-es';
4
4
  import hash from 'object-hash';
5
5
  import { getCache, getCacheValue, getSystemCache, setCacheValue, setSystemCache } from '../cache.js';
6
6
  import getDatabase from '../database/index.js';
7
- import { appAccessMinimalPermissions } from '../database/system-data/app-access-permissions/index.js';
7
+ import { appAccessMinimalPermissions } from '@directus/system-data';
8
8
  import { useLogger } from '../logger.js';
9
9
  import { RolesService } from '../services/roles.js';
10
10
  import { UsersService } from '../services/users.js';
@@ -5,12 +5,12 @@ import { mapValues } from 'lodash-es';
5
5
  import { getSchemaCache, setSchemaCache } from '../cache.js';
6
6
  import { ALIAS_TYPES } from '../constants.js';
7
7
  import getDatabase from '../database/index.js';
8
- import { systemCollectionRows } from '../database/system-data/collections/index.js';
9
- import { systemFieldRows } from '../database/system-data/fields/index.js';
10
8
  import { useLogger } from '../logger.js';
11
9
  import { RelationsService } from '../services/relations.js';
12
10
  import getDefaultValue from './get-default-value.js';
13
11
  import getLocalType from './get-local-type.js';
12
+ import { systemCollectionRows } from '@directus/system-data';
13
+ import { getSystemFieldRowsWithAuthProviders } from './get-field-system-rows.js';
14
14
  const logger = useLogger();
15
15
  export async function getSchema(options) {
16
16
  const env = useEnv();
@@ -49,6 +49,7 @@ async function getDatabaseSchema(database, schemaInspector) {
49
49
  collections: {},
50
50
  relations: [],
51
51
  };
52
+ const systemFieldRows = getSystemFieldRowsWithAuthProviders();
52
53
  const schemaOverview = await schemaInspector.overview();
53
54
  const collections = [
54
55
  ...(await database
@@ -1,5 +1,5 @@
1
1
  import { assign, set, uniq } from 'lodash-es';
2
- import { schemaPermissions } from '../database/system-data/app-access-permissions/index.js';
2
+ import { schemaPermissions } from '@directus/system-data';
3
3
  import { mergePermissions } from './merge-permissions.js';
4
4
  import { reduceSchema } from './reduce-schema.js';
5
5
  export function mergePermissionsForShare(currentPermissions, accountability, schema) {
@@ -1,7 +1,7 @@
1
1
  import { useEnv } from '@directus/env';
2
- import { getEndpoint } from '@directus/utils';
3
2
  import url from 'url';
4
3
  import { Url } from './url.js';
4
+ import { getEndpoint } from '@directus/utils';
5
5
  /**
6
6
  * Whether to skip caching for the current request
7
7
  *
@@ -130,7 +130,7 @@ function registerSortHooks() {
130
130
  */
131
131
  function registerAction(event, transform) {
132
132
  const messenger = useBus();
133
- emitter.onAction(event, async (data) => {
133
+ emitter.onAction(event, (data) => {
134
134
  // push the event through the Redis pub/sub
135
135
  messenger.publish('websocket.event', transform(data));
136
136
  });
@@ -1,6 +1,7 @@
1
1
  import emitter from '../../emitter.js';
2
2
  import { ItemsService, MetaService } from '../../services/index.js';
3
3
  import { getSchema } from '../../utils/get-schema.js';
4
+ import { isSystemCollection } from '@directus/system-data';
4
5
  import { sanitizeQuery } from '../../utils/sanitize-query.js';
5
6
  import { WebSocketError, handleWebSocketError } from '../errors.js';
6
7
  import { WebSocketItemsMessage } from '../messages.js';
@@ -26,7 +27,7 @@ export class ItemsHandler {
26
27
  const uid = message.uid;
27
28
  const accountability = client.accountability;
28
29
  const schema = await getSchema();
29
- if (!schema.collections[message.collection] || message.collection.startsWith('directus_')) {
30
+ if (!schema.collections[message.collection] || isSystemCollection(message.collection)) {
30
31
  throw new WebSocketError('items', 'INVALID_COLLECTION', 'The provided collection does not exists or is not accessible.', uid);
31
32
  }
32
33
  const isSingleton = !!schema.collections[message.collection]?.singleton;
@@ -163,53 +163,53 @@ export declare const WebSocketSubscribeMessage: z.ZodDiscriminatedUnion<"type",
163
163
  }, z.ZodTypeAny, "passthrough">>]>;
164
164
  export type WebSocketSubscribeMessage = z.infer<typeof WebSocketSubscribeMessage>;
165
165
  export declare const WebSocketItemsMessage: z.ZodUnion<[z.ZodObject<{
166
- type: z.ZodLiteral<"items">;
167
166
  collection: z.ZodString;
167
+ type: z.ZodLiteral<"items">;
168
168
  uid: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
169
169
  action: z.ZodLiteral<"create">;
170
170
  data: z.ZodUnion<[z.ZodArray<z.ZodType<Partial<Item>, z.ZodTypeDef, Partial<Item>>, "many">, z.ZodType<Partial<Item>, z.ZodTypeDef, Partial<Item>>]>;
171
171
  query: z.ZodOptional<z.ZodType<Query, z.ZodTypeDef, Query>>;
172
172
  }, "strip", z.ZodTypeAny, {
173
+ collection: string;
173
174
  type: "items";
174
175
  action: "create";
175
176
  data: (Partial<Item> | Partial<Item>[]) & (Partial<Item> | Partial<Item>[] | undefined);
176
- collection: string;
177
177
  uid?: string | number | undefined;
178
178
  query?: Query | undefined;
179
179
  }, {
180
+ collection: string;
180
181
  type: "items";
181
182
  action: "create";
182
183
  data: (Partial<Item> | Partial<Item>[]) & (Partial<Item> | Partial<Item>[] | undefined);
183
- collection: string;
184
184
  uid?: string | number | undefined;
185
185
  query?: Query | undefined;
186
186
  }>, z.ZodObject<{
187
- type: z.ZodLiteral<"items">;
188
187
  collection: z.ZodString;
188
+ type: z.ZodLiteral<"items">;
189
189
  uid: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
190
190
  action: z.ZodLiteral<"read">;
191
191
  ids: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
192
192
  id: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
193
193
  query: z.ZodOptional<z.ZodType<Query, z.ZodTypeDef, Query>>;
194
194
  }, "strip", z.ZodTypeAny, {
195
+ collection: string;
195
196
  type: "items";
196
197
  action: "read";
197
- collection: string;
198
198
  uid?: string | number | undefined;
199
199
  ids?: (string | number)[] | undefined;
200
200
  id?: string | number | undefined;
201
201
  query?: Query | undefined;
202
202
  }, {
203
+ collection: string;
203
204
  type: "items";
204
205
  action: "read";
205
- collection: string;
206
206
  uid?: string | number | undefined;
207
207
  ids?: (string | number)[] | undefined;
208
208
  id?: string | number | undefined;
209
209
  query?: Query | undefined;
210
210
  }>, z.ZodObject<{
211
- type: z.ZodLiteral<"items">;
212
211
  collection: z.ZodString;
212
+ type: z.ZodLiteral<"items">;
213
213
  uid: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
214
214
  action: z.ZodLiteral<"update">;
215
215
  data: z.ZodType<Partial<Item>, z.ZodTypeDef, Partial<Item>>;
@@ -217,43 +217,43 @@ export declare const WebSocketItemsMessage: z.ZodUnion<[z.ZodObject<{
217
217
  id: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
218
218
  query: z.ZodOptional<z.ZodType<Query, z.ZodTypeDef, Query>>;
219
219
  }, "strip", z.ZodTypeAny, {
220
+ collection: string;
220
221
  type: "items";
221
222
  action: "update";
222
223
  data: Partial<Item>;
223
- collection: string;
224
224
  uid?: string | number | undefined;
225
225
  ids?: (string | number)[] | undefined;
226
226
  id?: string | number | undefined;
227
227
  query?: Query | undefined;
228
228
  }, {
229
+ collection: string;
229
230
  type: "items";
230
231
  action: "update";
231
232
  data: Partial<Item>;
232
- collection: string;
233
233
  uid?: string | number | undefined;
234
234
  ids?: (string | number)[] | undefined;
235
235
  id?: string | number | undefined;
236
236
  query?: Query | undefined;
237
237
  }>, z.ZodObject<{
238
- type: z.ZodLiteral<"items">;
239
238
  collection: z.ZodString;
239
+ type: z.ZodLiteral<"items">;
240
240
  uid: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
241
241
  action: z.ZodLiteral<"delete">;
242
242
  ids: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
243
243
  id: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
244
244
  query: z.ZodOptional<z.ZodType<Query, z.ZodTypeDef, Query>>;
245
245
  }, "strip", z.ZodTypeAny, {
246
+ collection: string;
246
247
  type: "items";
247
248
  action: "delete";
248
- collection: string;
249
249
  uid?: string | number | undefined;
250
250
  ids?: (string | number)[] | undefined;
251
251
  id?: string | number | undefined;
252
252
  query?: Query | undefined;
253
253
  }, {
254
+ collection: string;
254
255
  type: "items";
255
256
  action: "delete";
256
- collection: string;
257
257
  uid?: string | number | undefined;
258
258
  ids?: (string | number)[] | undefined;
259
259
  id?: string | number | undefined;
@@ -266,14 +266,14 @@ export declare const WebSocketEvent: z.ZodDiscriminatedUnion<"action", [z.ZodObj
266
266
  payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
267
267
  key: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
268
268
  }, "strip", z.ZodTypeAny, {
269
+ collection: string;
269
270
  key: string | number;
270
271
  action: "create";
271
- collection: string;
272
272
  payload?: Record<string, any> | undefined;
273
273
  }, {
274
+ collection: string;
274
275
  key: string | number;
275
276
  action: "create";
276
- collection: string;
277
277
  payload?: Record<string, any> | undefined;
278
278
  }>, z.ZodObject<{
279
279
  action: z.ZodLiteral<"update">;
@@ -281,14 +281,14 @@ export declare const WebSocketEvent: z.ZodDiscriminatedUnion<"action", [z.ZodObj
281
281
  payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
282
282
  keys: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">;
283
283
  }, "strip", z.ZodTypeAny, {
284
+ collection: string;
284
285
  action: "update";
285
286
  keys: (string | number)[];
286
- collection: string;
287
287
  payload?: Record<string, any> | undefined;
288
288
  }, {
289
+ collection: string;
289
290
  action: "update";
290
291
  keys: (string | number)[];
291
- collection: string;
292
292
  payload?: Record<string, any> | undefined;
293
293
  }>, z.ZodObject<{
294
294
  action: z.ZodLiteral<"delete">;
@@ -296,14 +296,14 @@ export declare const WebSocketEvent: z.ZodDiscriminatedUnion<"action", [z.ZodObj
296
296
  payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
297
297
  keys: z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">;
298
298
  }, "strip", z.ZodTypeAny, {
299
+ collection: string;
299
300
  action: "delete";
300
301
  keys: (string | number)[];
301
- collection: string;
302
302
  payload?: Record<string, any> | undefined;
303
303
  }, {
304
+ collection: string;
304
305
  action: "delete";
305
306
  keys: (string | number)[];
306
- collection: string;
307
307
  payload?: Record<string, any> | undefined;
308
308
  }>]>;
309
309
  export type WebSocketEvent = z.infer<typeof WebSocketEvent>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@directus/api",
3
- "version": "17.0.0",
3
+ "version": "17.1.0",
4
4
  "description": "Directus is a real-time API and App dashboard for managing SQL database content",
5
5
  "keywords": [
6
6
  "directus",
@@ -59,7 +59,7 @@
59
59
  ],
60
60
  "dependencies": {
61
61
  "@authenio/samlify-node-xmllint": "2.0.0",
62
- "@aws-sdk/client-ses": "3.511.0",
62
+ "@aws-sdk/client-ses": "3.513.0",
63
63
  "@directus/format-title": "10.1.0",
64
64
  "@godaddy/terminus": "4.12.1",
65
65
  "@rollup/plugin-alias": "5.1.0",
@@ -72,8 +72,8 @@
72
72
  "bytes": "3.1.2",
73
73
  "camelcase": "8.0.0",
74
74
  "chalk": "5.3.0",
75
- "chokidar": "3.5.3",
76
- "commander": "11.1.0",
75
+ "chokidar": "3.6.0",
76
+ "commander": "12.0.0",
77
77
  "content-disposition": "0.5.4",
78
78
  "cookie-parser": "1.4.6",
79
79
  "cors": "2.8.5",
@@ -81,7 +81,7 @@
81
81
  "date-fns": "3.3.1",
82
82
  "deep-diff": "1.0.2",
83
83
  "destroy": "1.2.0",
84
- "dotenv": "16.4.1",
84
+ "dotenv": "16.4.4",
85
85
  "encodeurl": "1.0.2",
86
86
  "eventemitter2": "6.4.9",
87
87
  "execa": "8.0.1",
@@ -92,14 +92,14 @@
92
92
  "glob-to-regexp": "0.4.1",
93
93
  "graphql": "16.8.1",
94
94
  "graphql-compose": "9.0.10",
95
- "graphql-ws": "5.14.3",
95
+ "graphql-ws": "5.15.0",
96
96
  "helmet": "7.1.0",
97
97
  "icc": "3.0.0",
98
- "inquirer": "9.2.14",
98
+ "inquirer": "9.2.15",
99
99
  "ioredis": "5.3.2",
100
100
  "ip-matching": "2.1.2",
101
101
  "isolated-vm": "4.7.2",
102
- "joi": "17.12.0",
102
+ "joi": "17.12.1",
103
103
  "js-yaml": "4.1.0",
104
104
  "js2xmlparser": "5.0.0",
105
105
  "json2csv": "5.0.7",
@@ -107,14 +107,14 @@
107
107
  "keyv": "4.5.4",
108
108
  "knex": "3.1.0",
109
109
  "ldapjs": "2.3.3",
110
- "liquidjs": "10.10.0",
110
+ "liquidjs": "10.10.1",
111
111
  "lodash-es": "4.17.21",
112
- "marked": "11.2.0",
112
+ "marked": "12.0.0",
113
113
  "micromustache": "8.0.3",
114
114
  "mime-types": "2.1.35",
115
115
  "minimatch": "9.0.3",
116
116
  "ms": "2.1.3",
117
- "nanoid": "5.0.5",
117
+ "nanoid": "5.0.6",
118
118
  "node-machine-id": "1.1.12",
119
119
  "node-schedule": "2.1.1",
120
120
  "nodemailer": "6.9.9",
@@ -126,48 +126,49 @@
126
126
  "p-limit": "5.0.0",
127
127
  "p-queue": "8.0.1",
128
128
  "papaparse": "5.4.1",
129
- "pino": "8.18.0",
129
+ "pino": "8.19.0",
130
130
  "pino-http": "9.0.0",
131
131
  "pino-http-print": "3.1.0",
132
132
  "pino-pretty": "10.3.1",
133
133
  "qs": "6.11.2",
134
134
  "rate-limiter-flexible": "4.0.1",
135
- "rollup": "4.9.6",
135
+ "rollup": "4.10.0",
136
136
  "samlify": "2.8.10",
137
- "sanitize-html": "2.11.0",
137
+ "sanitize-html": "2.12.0",
138
138
  "sharp": "0.33.2",
139
139
  "snappy": "7.2.2",
140
140
  "stream-json": "1.8.0",
141
- "tsx": "4.7.0",
141
+ "tsx": "4.7.1",
142
142
  "uuid": "9.0.1",
143
143
  "uuid-validate": "0.0.3",
144
144
  "wellknown": "0.5.0",
145
145
  "ws": "8.16.0",
146
146
  "zod": "3.22.4",
147
- "zod-validation-error": "3.0.0",
148
- "@directus/app": "10.15.0",
149
- "@directus/env": "1.0.1",
150
- "@directus/extensions": "0.3.1",
151
- "@directus/errors": "0.2.2",
147
+ "zod-validation-error": "3.0.2",
148
+ "@directus/app": "10.15.2",
152
149
  "@directus/constants": "11.0.3",
153
- "@directus/extensions-sdk": "10.3.2",
154
- "@directus/memory": "1.0.1",
155
- "@directus/pressure": "1.0.15",
150
+ "@directus/errors": "0.2.3",
151
+ "@directus/env": "1.0.2",
152
+ "@directus/extensions": "0.3.3",
153
+ "@directus/extensions-sdk": "10.3.4",
154
+ "@directus/memory": "1.0.3",
156
155
  "@directus/schema": "11.0.1",
157
156
  "@directus/specs": "10.2.6",
158
- "@directus/storage": "10.0.9",
159
- "@directus/storage-driver-azure": "10.0.16",
160
- "@directus/storage-driver-cloudinary": "10.0.16",
161
- "@directus/storage-driver-gcs": "10.0.16",
162
- "@directus/storage-driver-local": "10.0.16",
163
- "@directus/storage-driver-supabase": "1.0.8",
164
- "@directus/storage-driver-s3": "10.0.16",
165
- "@directus/validation": "0.0.11",
166
- "@directus/utils": "11.0.4",
167
- "directus": "10.9.1"
157
+ "@directus/pressure": "1.0.16",
158
+ "@directus/storage-driver-azure": "10.0.17",
159
+ "@directus/storage": "10.0.10",
160
+ "@directus/storage-driver-cloudinary": "10.0.17",
161
+ "@directus/storage-driver-gcs": "10.0.17",
162
+ "@directus/storage-driver-s3": "10.0.18",
163
+ "@directus/storage-driver-local": "10.0.17",
164
+ "@directus/storage-driver-supabase": "1.0.9",
165
+ "@directus/system-data": "1.0.0",
166
+ "@directus/utils": "11.0.5",
167
+ "directus": "10.9.3",
168
+ "@directus/validation": "0.0.12"
168
169
  },
169
170
  "devDependencies": {
170
- "@ngneat/falso": "7.1.1",
171
+ "@ngneat/falso": "7.2.0",
171
172
  "@types/async": "3.2.24",
172
173
  "@types/busboy": "1.5.3",
173
174
  "@types/bytes": "3.1.4",
@@ -189,7 +190,7 @@
189
190
  "@types/lodash-es": "4.17.12",
190
191
  "@types/mime-types": "2.1.4",
191
192
  "@types/ms": "0.7.34",
192
- "@types/node": "18.19.14",
193
+ "@types/node": "18.19.17",
193
194
  "@types/node-schedule": "2.1.6",
194
195
  "@types/nodemailer": "6.4.14",
195
196
  "@types/object-hash": "3.0.6",
@@ -201,15 +202,15 @@
201
202
  "@types/uuid-validate": "0.0.3",
202
203
  "@types/wellknown": "0.5.8",
203
204
  "@types/ws": "8.5.10",
204
- "@vitest/coverage-v8": "1.2.2",
205
+ "@vitest/coverage-v8": "1.3.1",
205
206
  "copyfiles": "2.4.1",
206
207
  "form-data": "4.0.0",
207
208
  "knex-mock-client": "2.0.1",
208
209
  "typescript": "5.3.3",
209
- "vitest": "1.2.2",
210
- "@directus/random": "0.2.5",
210
+ "vitest": "1.3.0",
211
211
  "@directus/tsconfig": "1.0.1",
212
- "@directus/types": "11.0.5"
212
+ "@directus/random": "0.2.6",
213
+ "@directus/types": "11.0.6"
213
214
  },
214
215
  "optionalDependencies": {
215
216
  "@keyv/redis": "2.8.4",
@@ -219,10 +220,10 @@
219
220
  "oracledb": "6.3.0",
220
221
  "pg": "8.11.3",
221
222
  "sqlite3": "5.1.7",
222
- "tedious": "16.6.1"
223
+ "tedious": "16.7.1"
223
224
  },
224
225
  "engines": {
225
- "node": ">=18.0.0"
226
+ "node": ">=18.17.0"
226
227
  },
227
228
  "scripts": {
228
229
  "build": "tsc --project tsconfig.prod.json && copyfiles \"src/**/*.{yaml,liquid}\" -u 1 dist",