@directus/api 14.1.0 → 14.1.2
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/constants.js +1 -1
- package/dist/controllers/server.js +1 -1
- package/dist/database/system-data/fields/settings.yaml +4 -0
- package/dist/database/system-data/fields/users.yaml +4 -0
- package/dist/services/specifications.d.ts +3 -16
- package/dist/services/specifications.js +63 -64
- package/dist/types/services.d.ts +1 -1
- package/dist/utils/get-permissions.js +0 -3
- package/dist/utils/get-snapshot-diff.js +2 -1
- package/dist/utils/merge-permissions.js +19 -11
- package/package.json +13 -13
package/dist/constants.js
CHANGED
|
@@ -55,7 +55,7 @@ export const COOKIE_OPTIONS = {
|
|
|
55
55
|
secure: env['REFRESH_TOKEN_COOKIE_SECURE'] ?? false,
|
|
56
56
|
sameSite: env['REFRESH_TOKEN_COOKIE_SAME_SITE'] || 'strict',
|
|
57
57
|
};
|
|
58
|
-
export const OAS_REQUIRED_SCHEMAS = ['
|
|
58
|
+
export const OAS_REQUIRED_SCHEMAS = ['Query', 'x-metadata'];
|
|
59
59
|
/** Formats from which transformation is supported */
|
|
60
60
|
export const SUPPORTED_IMAGE_TRANSFORM_FORMATS = ['image/jpeg', 'image/png', 'image/webp', 'image/tiff', 'image/avif'];
|
|
61
61
|
/** Formats where metadata extraction is supported */
|
|
@@ -11,7 +11,7 @@ router.get('/specs/oas', asyncHandler(async (req, res, next) => {
|
|
|
11
11
|
accountability: req.accountability,
|
|
12
12
|
schema: req.schema,
|
|
13
13
|
});
|
|
14
|
-
res.locals['payload'] = await service.oas.generate();
|
|
14
|
+
res.locals['payload'] = await service.oas.generate(req.headers.host);
|
|
15
15
|
return next();
|
|
16
16
|
}), respond);
|
|
17
17
|
router.get('/specs/graphql/:scope?', asyncHandler(async (req, res) => {
|
|
@@ -120,6 +120,8 @@ fields:
|
|
|
120
120
|
- field: theme_light_overrides
|
|
121
121
|
width: full
|
|
122
122
|
interface: system-theme-overrides
|
|
123
|
+
options:
|
|
124
|
+
appearance: light
|
|
123
125
|
group: theming_group
|
|
124
126
|
special:
|
|
125
127
|
- cast-json
|
|
@@ -134,6 +136,8 @@ fields:
|
|
|
134
136
|
- field: theme_dark_overrides
|
|
135
137
|
width: full
|
|
136
138
|
interface: system-theme-overrides
|
|
139
|
+
options:
|
|
140
|
+
appearance: dark
|
|
137
141
|
group: theming_group
|
|
138
142
|
special:
|
|
139
143
|
- cast-json
|
|
@@ -124,6 +124,8 @@ fields:
|
|
|
124
124
|
- field: theme_light_overrides
|
|
125
125
|
width: full
|
|
126
126
|
interface: system-theme-overrides
|
|
127
|
+
options:
|
|
128
|
+
appearance: light
|
|
127
129
|
special:
|
|
128
130
|
- cast-json
|
|
129
131
|
|
|
@@ -137,6 +139,8 @@ fields:
|
|
|
137
139
|
- field: theme_dark_overrides
|
|
138
140
|
width: full
|
|
139
141
|
interface: system-theme-overrides
|
|
142
|
+
options:
|
|
143
|
+
appearance: dark
|
|
140
144
|
special:
|
|
141
145
|
- cast-json
|
|
142
146
|
|
|
@@ -2,20 +2,14 @@ import type { Accountability, SchemaOverview } from '@directus/types';
|
|
|
2
2
|
import type { Knex } from 'knex';
|
|
3
3
|
import type { OpenAPIObject } from 'openapi3-ts/oas30';
|
|
4
4
|
import type { AbstractServiceOptions } from '../types/index.js';
|
|
5
|
-
import { CollectionsService } from './collections.js';
|
|
6
|
-
import { FieldsService } from './fields.js';
|
|
7
5
|
import { GraphQLService } from './graphql/index.js';
|
|
8
|
-
import { RelationsService } from './relations.js';
|
|
9
6
|
export declare class SpecificationService {
|
|
10
7
|
accountability: Accountability | null;
|
|
11
8
|
knex: Knex;
|
|
12
9
|
schema: SchemaOverview;
|
|
13
|
-
fieldsService: FieldsService;
|
|
14
|
-
collectionsService: CollectionsService;
|
|
15
|
-
relationsService: RelationsService;
|
|
16
10
|
oas: OASSpecsService;
|
|
17
11
|
graphql: GraphQLSpecsService;
|
|
18
|
-
constructor(
|
|
12
|
+
constructor({ accountability, knex, schema }: AbstractServiceOptions);
|
|
19
13
|
}
|
|
20
14
|
interface SpecificationSubService {
|
|
21
15
|
generate: (_?: any) => Promise<any>;
|
|
@@ -24,15 +18,8 @@ declare class OASSpecsService implements SpecificationSubService {
|
|
|
24
18
|
accountability: Accountability | null;
|
|
25
19
|
knex: Knex;
|
|
26
20
|
schema: SchemaOverview;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
relationsService: RelationsService;
|
|
30
|
-
constructor(options: AbstractServiceOptions, { fieldsService, collectionsService, relationsService, }: {
|
|
31
|
-
fieldsService: FieldsService;
|
|
32
|
-
collectionsService: CollectionsService;
|
|
33
|
-
relationsService: RelationsService;
|
|
34
|
-
});
|
|
35
|
-
generate(): Promise<OpenAPIObject>;
|
|
21
|
+
constructor({ knex, schema, accountability }: AbstractServiceOptions);
|
|
22
|
+
generate(host?: string): Promise<OpenAPIObject>;
|
|
36
23
|
private generateTags;
|
|
37
24
|
private generatePaths;
|
|
38
25
|
private generateComponents;
|
|
@@ -6,57 +6,39 @@ import getDatabase from '../database/index.js';
|
|
|
6
6
|
import env from '../env.js';
|
|
7
7
|
import { getRelationType } from '../utils/get-relation-type.js';
|
|
8
8
|
import { version } from '../utils/package.js';
|
|
9
|
-
import { CollectionsService } from './collections.js';
|
|
10
|
-
import { FieldsService } from './fields.js';
|
|
11
9
|
import { GraphQLService } from './graphql/index.js';
|
|
12
|
-
import {
|
|
10
|
+
import { reduceSchema } from '../utils/reduce-schema.js';
|
|
13
11
|
export class SpecificationService {
|
|
14
12
|
accountability;
|
|
15
13
|
knex;
|
|
16
14
|
schema;
|
|
17
|
-
fieldsService;
|
|
18
|
-
collectionsService;
|
|
19
|
-
relationsService;
|
|
20
15
|
oas;
|
|
21
16
|
graphql;
|
|
22
|
-
constructor(
|
|
23
|
-
this.accountability =
|
|
24
|
-
this.knex =
|
|
25
|
-
this.schema =
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
28
|
-
this.relationsService = new RelationsService(options);
|
|
29
|
-
this.oas = new OASSpecsService(options, {
|
|
30
|
-
fieldsService: this.fieldsService,
|
|
31
|
-
collectionsService: this.collectionsService,
|
|
32
|
-
relationsService: this.relationsService,
|
|
33
|
-
});
|
|
34
|
-
this.graphql = new GraphQLSpecsService(options);
|
|
17
|
+
constructor({ accountability, knex, schema }) {
|
|
18
|
+
this.accountability = accountability || null;
|
|
19
|
+
this.knex = knex || getDatabase();
|
|
20
|
+
this.schema = schema;
|
|
21
|
+
this.oas = new OASSpecsService({ knex, schema, accountability });
|
|
22
|
+
this.graphql = new GraphQLSpecsService({ knex, schema });
|
|
35
23
|
}
|
|
36
24
|
}
|
|
37
25
|
class OASSpecsService {
|
|
38
26
|
accountability;
|
|
39
27
|
knex;
|
|
40
28
|
schema;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.knex = options.knex || getDatabase();
|
|
47
|
-
this.schema = options.schema;
|
|
48
|
-
this.fieldsService = fieldsService;
|
|
49
|
-
this.collectionsService = collectionsService;
|
|
50
|
-
this.relationsService = relationsService;
|
|
29
|
+
constructor({ knex, schema, accountability }) {
|
|
30
|
+
this.accountability = accountability || null;
|
|
31
|
+
this.knex = knex || getDatabase();
|
|
32
|
+
this.schema =
|
|
33
|
+
this.accountability?.admin === true ? schema : reduceSchema(schema, accountability?.permissions || null);
|
|
51
34
|
}
|
|
52
|
-
async generate() {
|
|
53
|
-
const collections = await this.collectionsService.readByQuery();
|
|
54
|
-
const fields = await this.fieldsService.readAll();
|
|
55
|
-
const relations = (await this.relationsService.readAll());
|
|
35
|
+
async generate(host) {
|
|
56
36
|
const permissions = this.accountability?.permissions ?? [];
|
|
57
|
-
const tags = await this.generateTags(
|
|
37
|
+
const tags = await this.generateTags();
|
|
58
38
|
const paths = await this.generatePaths(permissions, tags);
|
|
59
|
-
const components = await this.generateComponents(
|
|
39
|
+
const components = await this.generateComponents(tags);
|
|
40
|
+
const isDefaultPublicUrl = env['PUBLIC_URL'] === '/';
|
|
41
|
+
const url = isDefaultPublicUrl && host ? host : env['PUBLIC_URL'];
|
|
60
42
|
const spec = {
|
|
61
43
|
openapi: '3.0.1',
|
|
62
44
|
info: {
|
|
@@ -66,7 +48,7 @@ class OASSpecsService {
|
|
|
66
48
|
},
|
|
67
49
|
servers: [
|
|
68
50
|
{
|
|
69
|
-
url
|
|
51
|
+
url,
|
|
70
52
|
description: 'Your current Directus instance.',
|
|
71
53
|
},
|
|
72
54
|
],
|
|
@@ -78,11 +60,17 @@ class OASSpecsService {
|
|
|
78
60
|
spec.components = components;
|
|
79
61
|
return spec;
|
|
80
62
|
}
|
|
81
|
-
async generateTags(
|
|
63
|
+
async generateTags() {
|
|
82
64
|
const systemTags = cloneDeep(spec.tags);
|
|
65
|
+
const collections = Object.values(this.schema.collections);
|
|
83
66
|
const tags = [];
|
|
84
|
-
// System tags that don't have an associated collection are always readable to the user
|
|
85
67
|
for (const systemTag of systemTags) {
|
|
68
|
+
// Check if necessary authentication level is given
|
|
69
|
+
if (systemTag['x-authentication'] === 'admin' && !this.accountability?.admin)
|
|
70
|
+
continue;
|
|
71
|
+
if (systemTag['x-authentication'] === 'user' && !this.accountability?.user)
|
|
72
|
+
continue;
|
|
73
|
+
// Remaining system tags that don't have an associated collection are publicly available
|
|
86
74
|
if (!systemTag['x-collection']) {
|
|
87
75
|
tags.push(systemTag);
|
|
88
76
|
}
|
|
@@ -103,8 +91,8 @@ class OASSpecsService {
|
|
|
103
91
|
name: 'Items' + formatTitle(collection.collection).replace(/ /g, ''),
|
|
104
92
|
'x-collection': collection.collection,
|
|
105
93
|
};
|
|
106
|
-
if (collection.
|
|
107
|
-
tag.description = collection.
|
|
94
|
+
if (collection.note) {
|
|
95
|
+
tag.description = collection.note;
|
|
108
96
|
}
|
|
109
97
|
tags.push(tag);
|
|
110
98
|
}
|
|
@@ -256,33 +244,38 @@ class OASSpecsService {
|
|
|
256
244
|
}
|
|
257
245
|
return paths;
|
|
258
246
|
}
|
|
259
|
-
async generateComponents(
|
|
247
|
+
async generateComponents(tags) {
|
|
248
|
+
if (!tags)
|
|
249
|
+
return;
|
|
260
250
|
let components = cloneDeep(spec.components);
|
|
261
251
|
if (!components)
|
|
262
252
|
components = {};
|
|
263
253
|
components.schemas = {};
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
254
|
+
const tagSchemas = tags.reduce((schemas, tag) => [...schemas, ...(tag['x-schemas'] ? tag['x-schemas'] : [])], []);
|
|
255
|
+
const requiredSchemas = [...OAS_REQUIRED_SCHEMAS, ...tagSchemas];
|
|
256
|
+
for (const [name, schema] of Object.entries(spec.components?.schemas ?? {})) {
|
|
257
|
+
if (requiredSchemas.includes(name)) {
|
|
258
|
+
const collection = spec.tags?.find((tag) => tag.name === name)?.['x-collection'];
|
|
259
|
+
components.schemas[name] = {
|
|
260
|
+
...cloneDeep(schema),
|
|
261
|
+
...(collection && { 'x-collection': collection }),
|
|
262
|
+
};
|
|
270
263
|
}
|
|
271
264
|
}
|
|
272
|
-
|
|
273
|
-
return;
|
|
265
|
+
const collections = Object.values(this.schema.collections);
|
|
274
266
|
for (const collection of collections) {
|
|
275
267
|
const tag = tags.find((tag) => tag['x-collection'] === collection.collection);
|
|
276
268
|
if (!tag)
|
|
277
269
|
continue;
|
|
278
270
|
const isSystem = collection.collection.startsWith('directus_');
|
|
279
|
-
const fieldsInCollection =
|
|
271
|
+
const fieldsInCollection = Object.values(collection.fields);
|
|
280
272
|
if (isSystem) {
|
|
281
273
|
const schemaComponent = cloneDeep(spec.components.schemas[tag.name]);
|
|
282
274
|
schemaComponent.properties = {};
|
|
275
|
+
schemaComponent['x-collection'] = collection.collection;
|
|
283
276
|
for (const field of fieldsInCollection) {
|
|
284
277
|
schemaComponent.properties[field.field] =
|
|
285
|
-
cloneDeep(spec.components.schemas[tag.name].properties[field.field]) || this.generateField(
|
|
278
|
+
cloneDeep(spec.components.schemas[tag.name].properties[field.field]) || this.generateField(collection.collection, field, tags);
|
|
286
279
|
}
|
|
287
280
|
components.schemas[tag.name] = schemaComponent;
|
|
288
281
|
}
|
|
@@ -293,7 +286,7 @@ class OASSpecsService {
|
|
|
293
286
|
'x-collection': collection.collection,
|
|
294
287
|
};
|
|
295
288
|
for (const field of fieldsInCollection) {
|
|
296
|
-
schemaComponent.properties[field.field] = this.generateField(
|
|
289
|
+
schemaComponent.properties[field.field] = this.generateField(collection.collection, field, tags);
|
|
297
290
|
}
|
|
298
291
|
components.schemas[tag.name] = schemaComponent;
|
|
299
292
|
}
|
|
@@ -316,16 +309,14 @@ class OASSpecsService {
|
|
|
316
309
|
return 'read';
|
|
317
310
|
}
|
|
318
311
|
}
|
|
319
|
-
generateField(
|
|
312
|
+
generateField(collection, field, tags) {
|
|
320
313
|
let propertyObject = {};
|
|
321
|
-
|
|
322
|
-
|
|
314
|
+
propertyObject.nullable = field.nullable;
|
|
315
|
+
if (field.note) {
|
|
316
|
+
propertyObject.description = field.note;
|
|
323
317
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
const relation = relations.find((relation) => (relation.collection === field.collection && relation.field === field.field) ||
|
|
328
|
-
(relation.related_collection === field.collection && relation.meta?.one_field === field.field));
|
|
318
|
+
const relation = this.schema.relations.find((relation) => (relation.collection === collection && relation.field === field.field) ||
|
|
319
|
+
(relation.related_collection === collection && relation.meta?.one_field === field.field));
|
|
329
320
|
if (!relation) {
|
|
330
321
|
propertyObject = {
|
|
331
322
|
...propertyObject,
|
|
@@ -336,13 +327,17 @@ class OASSpecsService {
|
|
|
336
327
|
const relationType = getRelationType({
|
|
337
328
|
relation,
|
|
338
329
|
field: field.field,
|
|
339
|
-
collection:
|
|
330
|
+
collection: collection,
|
|
340
331
|
});
|
|
341
332
|
if (relationType === 'm2o') {
|
|
342
333
|
const relatedTag = tags.find((tag) => tag['x-collection'] === relation.related_collection);
|
|
343
|
-
|
|
344
|
-
|
|
334
|
+
if (!relatedTag ||
|
|
335
|
+
!relation.related_collection ||
|
|
336
|
+
relation.related_collection in this.schema.collections === false) {
|
|
345
337
|
return propertyObject;
|
|
338
|
+
}
|
|
339
|
+
const relatedCollection = this.schema.collections[relation.related_collection];
|
|
340
|
+
const relatedPrimaryKeyField = relatedCollection.fields[relatedCollection.primary];
|
|
346
341
|
propertyObject.oneOf = [
|
|
347
342
|
{
|
|
348
343
|
...this.fieldTypes[relatedPrimaryKeyField.type],
|
|
@@ -354,7 +349,11 @@ class OASSpecsService {
|
|
|
354
349
|
}
|
|
355
350
|
else if (relationType === 'o2m') {
|
|
356
351
|
const relatedTag = tags.find((tag) => tag['x-collection'] === relation.collection);
|
|
357
|
-
|
|
352
|
+
if (!relatedTag || !relation.related_collection || relation.collection in this.schema.collections === false) {
|
|
353
|
+
return propertyObject;
|
|
354
|
+
}
|
|
355
|
+
const relatedCollection = this.schema.collections[relation.collection];
|
|
356
|
+
const relatedPrimaryKeyField = relatedCollection.fields[relatedCollection.primary];
|
|
358
357
|
if (!relatedTag || !relatedPrimaryKeyField)
|
|
359
358
|
return propertyObject;
|
|
360
359
|
propertyObject.type = 'array';
|
package/dist/types/services.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Accountability, Query, SchemaOverview } from '@directus/types';
|
|
|
2
2
|
import type { Knex } from 'knex';
|
|
3
3
|
import type { Item, PrimaryKey } from './items.js';
|
|
4
4
|
export type AbstractServiceOptions = {
|
|
5
|
-
knex?: Knex;
|
|
5
|
+
knex?: Knex | undefined;
|
|
6
6
|
accountability?: Accountability | null | undefined;
|
|
7
7
|
schema: SchemaOverview;
|
|
8
8
|
};
|
|
@@ -86,9 +86,6 @@ function parsePermissions(permissions) {
|
|
|
86
86
|
if (permission.permissions && typeof permission.permissions === 'string') {
|
|
87
87
|
permission.permissions = parseJSON(permission.permissions);
|
|
88
88
|
}
|
|
89
|
-
else if (permission.permissions === null) {
|
|
90
|
-
permission.permissions = {};
|
|
91
|
-
}
|
|
92
89
|
if (permission.validation && typeof permission.validation === 'string') {
|
|
93
90
|
permission.validation = parseJSON(permission.validation);
|
|
94
91
|
}
|
|
@@ -55,7 +55,8 @@ export function getSnapshotDiff(current, after) {
|
|
|
55
55
|
}),
|
|
56
56
|
...after.relations
|
|
57
57
|
.filter((afterRelation) => {
|
|
58
|
-
const currentRelation = current.relations.find((currentRelation) => currentRelation.collection === afterRelation.collection &&
|
|
58
|
+
const currentRelation = current.relations.find((currentRelation) => currentRelation.collection === afterRelation.collection &&
|
|
59
|
+
afterRelation.field === currentRelation.field);
|
|
59
60
|
return !!currentRelation === false;
|
|
60
61
|
})
|
|
61
62
|
.map((afterRelation) => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flatten, intersection,
|
|
1
|
+
import { flatten, intersection, isEqual, merge, omit } from 'lodash-es';
|
|
2
2
|
export function mergePermissions(strategy, ...permissions) {
|
|
3
3
|
const allPermissions = flatten(permissions);
|
|
4
4
|
const mergedPermissions = allPermissions
|
|
@@ -27,11 +27,15 @@ export function mergePermission(strategy, currentPerm, newPerm) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
else if (currentPerm.permissions) {
|
|
30
|
-
permissions
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
// Empty {} supersedes other permissions in _OR merge
|
|
31
|
+
if (strategy === 'or' && (isEqual(currentPerm.permissions, {}) || isEqual(newPerm.permissions, {}))) {
|
|
32
|
+
permissions = {};
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
permissions = {
|
|
36
|
+
[logicalKey]: [currentPerm.permissions, newPerm.permissions],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
35
39
|
}
|
|
36
40
|
else {
|
|
37
41
|
permissions = {
|
|
@@ -49,11 +53,15 @@ export function mergePermission(strategy, currentPerm, newPerm) {
|
|
|
49
53
|
};
|
|
50
54
|
}
|
|
51
55
|
else if (currentPerm.validation) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// Empty {} supersedes other validations in _OR merge
|
|
57
|
+
if (strategy === 'or' && (isEqual(currentPerm.validation, {}) || isEqual(newPerm.validation, {}))) {
|
|
58
|
+
validation = {};
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
validation = {
|
|
62
|
+
[logicalKey]: [currentPerm.validation, newPerm.validation],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
57
65
|
}
|
|
58
66
|
else {
|
|
59
67
|
validation = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@directus/api",
|
|
3
|
-
"version": "14.1.
|
|
3
|
+
"version": "14.1.2",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -138,30 +138,30 @@
|
|
|
138
138
|
"stream-json": "1.7.5",
|
|
139
139
|
"strip-bom-stream": "5.0.0",
|
|
140
140
|
"tinypool": "0.8.1",
|
|
141
|
-
"tsx": "
|
|
141
|
+
"tsx": "4.1.4",
|
|
142
142
|
"uuid": "9.0.0",
|
|
143
143
|
"uuid-validate": "0.0.3",
|
|
144
144
|
"wellknown": "0.5.0",
|
|
145
145
|
"ws": "8.14.2",
|
|
146
146
|
"zod": "3.22.4",
|
|
147
147
|
"zod-validation-error": "1.0.1",
|
|
148
|
-
"@directus/app": "10.13.
|
|
149
|
-
"@directus/constants": "11.0.1",
|
|
148
|
+
"@directus/app": "10.13.2",
|
|
150
149
|
"@directus/errors": "0.2.0",
|
|
150
|
+
"@directus/constants": "11.0.1",
|
|
151
|
+
"@directus/extensions": "0.2.0",
|
|
151
152
|
"@directus/extensions-sdk": "10.2.0",
|
|
152
153
|
"@directus/pressure": "1.0.13",
|
|
153
|
-
"@directus/extensions": "0.2.0",
|
|
154
154
|
"@directus/schema": "11.0.0",
|
|
155
|
-
"@directus/specs": "10.2.
|
|
156
|
-
"@directus/storage": "10.0.7",
|
|
155
|
+
"@directus/specs": "10.2.4",
|
|
157
156
|
"@directus/storage-driver-azure": "10.0.14",
|
|
158
|
-
"@directus/storage-driver-gcs": "10.0.14",
|
|
159
157
|
"@directus/storage-driver-cloudinary": "10.0.14",
|
|
158
|
+
"@directus/storage-driver-gcs": "10.0.14",
|
|
159
|
+
"@directus/storage": "10.0.7",
|
|
160
160
|
"@directus/storage-driver-local": "10.0.14",
|
|
161
|
-
"@directus/storage-driver-s3": "10.0.14",
|
|
162
161
|
"@directus/storage-driver-supabase": "1.0.6",
|
|
163
|
-
"@directus/
|
|
164
|
-
"@directus/utils": "11.0.2"
|
|
162
|
+
"@directus/storage-driver-s3": "10.0.14",
|
|
163
|
+
"@directus/utils": "11.0.2",
|
|
164
|
+
"@directus/validation": "0.0.9"
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|
|
167
167
|
"@ngneat/falso": "6.4.0",
|
|
@@ -202,13 +202,13 @@
|
|
|
202
202
|
"@types/uuid-validate": "0.0.1",
|
|
203
203
|
"@types/wellknown": "0.5.4",
|
|
204
204
|
"@types/ws": "8.5.8",
|
|
205
|
-
"@vitest/coverage-
|
|
205
|
+
"@vitest/coverage-v8": "0.34.6",
|
|
206
206
|
"copyfiles": "2.4.1",
|
|
207
207
|
"form-data": "4.0.0",
|
|
208
208
|
"knex-mock-client": "2.0.0",
|
|
209
209
|
"supertest": "6.3.3",
|
|
210
210
|
"typescript": "5.2.2",
|
|
211
|
-
"vitest": "0.
|
|
211
|
+
"vitest": "0.34.6",
|
|
212
212
|
"@directus/random": "0.2.3",
|
|
213
213
|
"@directus/tsconfig": "1.0.1",
|
|
214
214
|
"@directus/types": "11.0.2"
|