directus 9.4.2 → 9.5.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/README.md +1 -1
- package/dist/app.js +9 -0
- package/dist/auth/auth.d.ts +2 -1
- package/dist/auth/drivers/oauth2.js +10 -20
- package/dist/auth/drivers/openid.js +18 -8
- package/dist/cli/commands/init/index.js +8 -0
- package/dist/cli/commands/init/questions.d.ts +3 -0
- package/dist/cli/commands/init/questions.js +2 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +11 -1
- package/dist/cli/utils/drivers.d.ts +1 -0
- package/dist/cli/utils/drivers.js +2 -1
- package/dist/controllers/extensions.js +1 -1
- package/dist/controllers/files.js +3 -0
- package/dist/controllers/utils.js +2 -0
- package/dist/database/helpers/date/index.d.ts +1 -0
- package/dist/database/helpers/date/index.js +3 -1
- package/dist/database/helpers/geometry/index.d.ts +1 -0
- package/dist/database/helpers/geometry/index.js +3 -1
- package/dist/database/helpers/index.d.ts +2 -0
- package/dist/database/helpers/index.js +2 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +16 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.js +16 -0
- package/dist/database/helpers/schema/dialects/default.d.ts +3 -0
- package/dist/database/helpers/schema/dialects/default.js +7 -0
- package/dist/database/helpers/schema/dialects/oracle.d.ts +12 -0
- package/dist/database/helpers/schema/dialects/oracle.js +13 -0
- package/dist/database/helpers/schema/index.d.ts +7 -0
- package/dist/database/helpers/schema/index.js +17 -0
- package/dist/database/helpers/schema/types.d.ts +25 -0
- package/dist/database/helpers/schema/types.js +89 -0
- package/dist/database/index.d.ts +1 -1
- package/dist/database/index.js +66 -20
- package/dist/database/migrations/20201105B-change-webhook-url-type.js +6 -25
- package/dist/database/migrations/20210312A-webhooks-collections-text.js +6 -25
- package/dist/database/migrations/20210415A-make-filesize-nullable.js +9 -4
- package/dist/database/migrations/20210506A-rename-interfaces.js +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.js +12 -4
- package/dist/database/migrations/20210525A-add-insights.js +2 -2
- package/dist/database/migrations/20210626A-change-filesize-bigint.js +5 -7
- package/dist/database/migrations/20210903A-add-auth-provider.js +11 -2
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +6 -20
- package/dist/database/migrations/20210920A-webhooks-url-not-null.js +10 -14
- package/dist/database/migrations/20211211A-add-shares.js +2 -2
- package/dist/database/migrations/run.js +1 -1
- package/dist/database/run-ast.d.ts +1 -1
- package/dist/database/seeds/01-collections.yaml +1 -0
- package/dist/database/seeds/02-roles.yaml +1 -0
- package/dist/database/seeds/03-users.yaml +1 -0
- package/dist/database/system-data/app-access-permissions/app-access-permissions.yaml +8 -2
- package/dist/database/system-data/fields/collections.yaml +2 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +3 -4
- package/dist/emitter.js +2 -8
- package/dist/env.js +1 -0
- package/dist/exceptions/database/translate.js +1 -0
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +1 -0
- package/dist/exceptions/unsupported-media-type.d.ts +4 -0
- package/dist/exceptions/unsupported-media-type.js +10 -0
- package/dist/extensions.d.ts +14 -8
- package/dist/extensions.js +136 -69
- package/dist/logger.js +22 -1
- package/dist/middleware/extract-token.js +1 -1
- package/dist/services/assets.js +3 -3
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +7 -2
- package/dist/services/authorization.d.ts +2 -3
- package/dist/services/collections.d.ts +2 -2
- package/dist/services/collections.js +20 -18
- package/dist/services/fields.d.ts +2 -3
- package/dist/services/fields.js +14 -10
- package/dist/services/graphql.d.ts +2 -1
- package/dist/services/graphql.js +4 -4
- package/dist/services/import.d.ts +2 -2
- package/dist/services/import.js +2 -1
- package/dist/services/items.d.ts +2 -2
- package/dist/services/items.js +22 -18
- package/dist/services/mail/index.d.ts +2 -2
- package/dist/services/meta.d.ts +2 -2
- package/dist/services/payload.d.ts +2 -2
- package/dist/services/payload.js +7 -3
- package/dist/services/relations.d.ts +2 -2
- package/dist/services/relations.js +4 -0
- package/dist/services/server.d.ts +2 -2
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/users.d.ts +2 -3
- package/dist/services/utils.d.ts +2 -2
- package/dist/types/ast.d.ts +1 -2
- package/dist/types/auth.d.ts +1 -3
- package/dist/types/index.d.ts +0 -3
- package/dist/types/index.js +0 -3
- package/dist/types/services.d.ts +1 -3
- package/dist/types/snapshot.d.ts +1 -2
- package/dist/utils/apply-query.d.ts +1 -2
- package/dist/utils/apply-query.js +1 -1
- package/dist/utils/apply-snapshot.d.ts +2 -1
- package/dist/utils/get-ast-from-query.d.ts +2 -3
- package/dist/utils/get-local-type.js +1 -1
- package/dist/utils/get-permissions.d.ts +1 -2
- package/dist/utils/get-permissions.js +1 -1
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-schema.d.ts +1 -2
- package/dist/utils/get-snapshot.d.ts +2 -1
- package/dist/utils/md.js +1 -1
- package/dist/utils/merge-permissions-for-share.d.ts +1 -2
- package/dist/utils/reduce-schema.d.ts +1 -2
- package/example.env +8 -0
- package/package.json +23 -17
- package/dist/cli/index.test.d.ts +0 -1
- package/dist/cli/index.test.js +0 -58
- package/dist/middleware/cache.test.d.ts +0 -1
- package/dist/middleware/cache.test.js +0 -62
- package/dist/tests/database/migrations/run.test.d.ts +0 -1
- package/dist/tests/database/migrations/run.test.js +0 -29
- package/dist/types/extensions.d.ts +0 -43
- package/dist/types/extensions.js +0 -2
- package/dist/types/relation.d.ts +0 -21
- package/dist/types/relation.js +0 -2
- package/dist/types/schema.d.ts +0 -32
- package/dist/types/schema.js +0 -2
- package/dist/utils/get-cache-key.test.d.ts +0 -1
- package/dist/utils/get-cache-key.test.js +0 -53
|
@@ -66,24 +66,7 @@ class CollectionsService {
|
|
|
66
66
|
// permission problems. This might not work reliably in MySQL, as it doesn't support DDL in
|
|
67
67
|
// transactions.
|
|
68
68
|
await this.knex.transaction(async (trx) => {
|
|
69
|
-
if (payload.meta) {
|
|
70
|
-
const collectionItemsService = new items_1.ItemsService('directus_collections', {
|
|
71
|
-
knex: trx,
|
|
72
|
-
accountability: this.accountability,
|
|
73
|
-
schema: this.schema,
|
|
74
|
-
});
|
|
75
|
-
await collectionItemsService.createOne({
|
|
76
|
-
...payload.meta,
|
|
77
|
-
collection: payload.collection,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
69
|
if (payload.schema) {
|
|
81
|
-
const fieldsService = new fields_1.FieldsService({ knex: trx, schema: this.schema });
|
|
82
|
-
const fieldItemsService = new items_1.ItemsService('directus_fields', {
|
|
83
|
-
knex: trx,
|
|
84
|
-
accountability: this.accountability,
|
|
85
|
-
schema: this.schema,
|
|
86
|
-
});
|
|
87
70
|
// Directus heavily relies on the primary key of a collection, so we have to make sure that
|
|
88
71
|
// every collection that is created has a primary key. If no primary key field is created
|
|
89
72
|
// while making the collection, we default to an auto incremented id named `id`
|
|
@@ -114,6 +97,7 @@ class CollectionsService {
|
|
|
114
97
|
}
|
|
115
98
|
return field;
|
|
116
99
|
});
|
|
100
|
+
const fieldsService = new fields_1.FieldsService({ knex: trx, schema: this.schema });
|
|
117
101
|
await trx.schema.createTable(payload.collection, (table) => {
|
|
118
102
|
for (const field of payload.fields) {
|
|
119
103
|
if (field.type && constants_1.ALIAS_TYPES.includes(field.type) === false) {
|
|
@@ -121,9 +105,25 @@ class CollectionsService {
|
|
|
121
105
|
}
|
|
122
106
|
}
|
|
123
107
|
});
|
|
108
|
+
const fieldItemsService = new items_1.ItemsService('directus_fields', {
|
|
109
|
+
knex: trx,
|
|
110
|
+
accountability: this.accountability,
|
|
111
|
+
schema: this.schema,
|
|
112
|
+
});
|
|
124
113
|
const fieldPayloads = payload.fields.filter((field) => field.meta).map((field) => field.meta);
|
|
125
114
|
await fieldItemsService.createMany(fieldPayloads);
|
|
126
115
|
}
|
|
116
|
+
if (payload.meta) {
|
|
117
|
+
const collectionItemsService = new items_1.ItemsService('directus_collections', {
|
|
118
|
+
knex: trx,
|
|
119
|
+
accountability: this.accountability,
|
|
120
|
+
schema: this.schema,
|
|
121
|
+
});
|
|
122
|
+
await collectionItemsService.createOne({
|
|
123
|
+
...payload.meta,
|
|
124
|
+
collection: payload.collection,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
127
|
return payload.collection;
|
|
128
128
|
});
|
|
129
129
|
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
@@ -316,6 +316,9 @@ class CollectionsService {
|
|
|
316
316
|
}
|
|
317
317
|
await this.knex.transaction(async (trx) => {
|
|
318
318
|
var _a;
|
|
319
|
+
if (collectionToBeDeleted.schema) {
|
|
320
|
+
await trx.schema.dropTable(collectionKey);
|
|
321
|
+
}
|
|
319
322
|
// Make sure this collection isn't used as a group in any other collections
|
|
320
323
|
await trx('directus_collections').update({ group: null }).where({ group: collectionKey });
|
|
321
324
|
if (collectionToBeDeleted.meta) {
|
|
@@ -371,7 +374,6 @@ class CollectionsService {
|
|
|
371
374
|
.update({ one_allowed_collections: newAllowedCollections })
|
|
372
375
|
.where({ id: relation.meta.id });
|
|
373
376
|
}
|
|
374
|
-
await trx.schema.dropTable(collectionKey);
|
|
375
377
|
}
|
|
376
378
|
});
|
|
377
379
|
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
@@ -3,9 +3,8 @@ import { Knex } from 'knex';
|
|
|
3
3
|
import { Column } from 'knex-schema-inspector/dist/types/column';
|
|
4
4
|
import { ItemsService } from '../services/items';
|
|
5
5
|
import { PayloadService } from '../services/payload';
|
|
6
|
-
import { AbstractServiceOptions
|
|
7
|
-
import { Accountability } from '@directus/shared/types';
|
|
8
|
-
import { Field, RawField, Type } from '@directus/shared/types';
|
|
6
|
+
import { AbstractServiceOptions } from '../types';
|
|
7
|
+
import { Field, RawField, Type, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
9
8
|
import { Helpers } from '../database/helpers';
|
|
10
9
|
import Keyv from 'keyv';
|
|
11
10
|
export declare class FieldsService {
|
package/dist/services/fields.js
CHANGED
|
@@ -325,6 +325,13 @@ class FieldsService {
|
|
|
325
325
|
});
|
|
326
326
|
await this.knex.transaction(async (trx) => {
|
|
327
327
|
var _a, _b;
|
|
328
|
+
if (this.schema.collections[collection] &&
|
|
329
|
+
field in this.schema.collections[collection].fields &&
|
|
330
|
+
this.schema.collections[collection].fields[field].alias === false) {
|
|
331
|
+
await trx.schema.table(collection, (table) => {
|
|
332
|
+
table.dropColumn(field);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
328
335
|
const relations = this.schema.relations.filter((relation) => {
|
|
329
336
|
var _a;
|
|
330
337
|
return ((relation.collection === collection && relation.field === field) ||
|
|
@@ -384,13 +391,6 @@ class FieldsService {
|
|
|
384
391
|
.where({ group: metaRow.field, collection: metaRow.collection });
|
|
385
392
|
}
|
|
386
393
|
await trx('directus_fields').delete().where({ collection, field });
|
|
387
|
-
if (this.schema.collections[collection] &&
|
|
388
|
-
field in this.schema.collections[collection].fields &&
|
|
389
|
-
this.schema.collections[collection].fields[field].alias === false) {
|
|
390
|
-
await trx.schema.table(collection, (table) => {
|
|
391
|
-
table.dropColumn(field);
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
394
|
});
|
|
395
395
|
if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
|
|
396
396
|
await this.cache.clear();
|
|
@@ -452,11 +452,15 @@ class FieldsService {
|
|
|
452
452
|
column.defaultTo(field.schema.default_value);
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
|
-
if (((_g = field.schema) === null || _g === void 0 ? void 0 : _g.is_nullable)
|
|
456
|
-
|
|
455
|
+
if (((_g = field.schema) === null || _g === void 0 ? void 0 : _g.is_nullable) === false) {
|
|
456
|
+
if (!alter || alter.is_nullable === true) {
|
|
457
|
+
column.notNullable();
|
|
458
|
+
}
|
|
457
459
|
}
|
|
458
460
|
else {
|
|
459
|
-
|
|
461
|
+
if (!alter || alter.is_nullable === false) {
|
|
462
|
+
column.nullable();
|
|
463
|
+
}
|
|
460
464
|
}
|
|
461
465
|
if ((_h = field.schema) === null || _h === void 0 ? void 0 : _h.is_primary_key) {
|
|
462
466
|
column.primary().notNullable();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLScalarType, GraphQLSchema, ObjectFieldNode, SelectionNode } from 'graphql';
|
|
2
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
2
3
|
import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
|
|
3
4
|
import { Knex } from 'knex';
|
|
4
5
|
import { BaseException } from '@directus/shared/exceptions';
|
|
5
6
|
import { Accountability, Query } from '@directus/shared/types';
|
|
6
|
-
import { AbstractServiceOptions, GraphQLParams, Item
|
|
7
|
+
import { AbstractServiceOptions, GraphQLParams, Item } from '../types';
|
|
7
8
|
import { ItemsService } from './items';
|
|
8
9
|
export declare const GraphQLGeoJSON: GraphQLScalarType;
|
|
9
10
|
export declare const GraphQLDate: GraphQLScalarType;
|
package/dist/services/graphql.js
CHANGED
|
@@ -1397,10 +1397,10 @@ class GraphQLService {
|
|
|
1397
1397
|
resolve: async () => {
|
|
1398
1398
|
const extensionManager = (0, extensions_1.getExtensionManager)();
|
|
1399
1399
|
return {
|
|
1400
|
-
interfaces: extensionManager.
|
|
1401
|
-
displays: extensionManager.
|
|
1402
|
-
layouts: extensionManager.
|
|
1403
|
-
modules: extensionManager.
|
|
1400
|
+
interfaces: extensionManager.getExtensionsList('interface'),
|
|
1401
|
+
displays: extensionManager.getExtensionsList('display'),
|
|
1402
|
+
layouts: extensionManager.getExtensionsList('layout'),
|
|
1403
|
+
modules: extensionManager.getExtensionsList('module'),
|
|
1404
1404
|
};
|
|
1405
1405
|
},
|
|
1406
1406
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
|
-
import { AbstractServiceOptions
|
|
4
|
-
import { Accountability } from '@directus/shared/types';
|
|
3
|
+
import { AbstractServiceOptions } from '../types';
|
|
4
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
5
|
export declare class ImportService {
|
|
6
6
|
knex: Knex;
|
|
7
7
|
accountability: Accountability | null;
|
package/dist/services/import.js
CHANGED
|
@@ -31,9 +31,10 @@ class ImportService {
|
|
|
31
31
|
case 'application/json':
|
|
32
32
|
return await this.importJSON(collection, stream);
|
|
33
33
|
case 'text/csv':
|
|
34
|
+
case 'application/vnd.ms-excel':
|
|
34
35
|
return await this.importCSV(collection, stream);
|
|
35
36
|
default:
|
|
36
|
-
throw new exceptions_1.
|
|
37
|
+
throw new exceptions_1.UnsupportedMediaTypeException(`Can't import files of type "${mimetype}"`);
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
importJSON(collection, stream) {
|
package/dist/services/items.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import Keyv from 'keyv';
|
|
3
|
-
import { Accountability, Query, PermissionsAction } from '@directus/shared/types';
|
|
4
|
-
import { AbstractService, AbstractServiceOptions, Item as AnyItem, PrimaryKey,
|
|
3
|
+
import { Accountability, Query, PermissionsAction, SchemaOverview } from '@directus/shared/types';
|
|
4
|
+
import { AbstractService, AbstractServiceOptions, Item as AnyItem, PrimaryKey, MutationOptions } from '../types';
|
|
5
5
|
export declare type QueryOptions = {
|
|
6
6
|
stripNonRequested?: boolean;
|
|
7
7
|
permissionsAction?: PermissionsAction;
|
package/dist/services/items.js
CHANGED
|
@@ -70,7 +70,9 @@ class ItemsService {
|
|
|
70
70
|
// Run all hooks that are attached to this event so the end user has the chance to augment the
|
|
71
71
|
// item that is about to be saved
|
|
72
72
|
const payloadAfterHooks = (opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false
|
|
73
|
-
? await emitter_1.default.emitFilter(
|
|
73
|
+
? await emitter_1.default.emitFilter(this.eventScope === 'items'
|
|
74
|
+
? ['items.create', `${this.collection}.items.create`]
|
|
75
|
+
: `${this.eventScope}.create`, payload, {
|
|
74
76
|
collection: this.collection,
|
|
75
77
|
}, {
|
|
76
78
|
database: trx,
|
|
@@ -85,7 +87,7 @@ class ItemsService {
|
|
|
85
87
|
const { payload: payloadWithA2O, revisions: revisionsA2O } = await payloadService.processA2O(payloadWithM2O);
|
|
86
88
|
const payloadWithoutAliases = (0, lodash_1.pick)(payloadWithA2O, (0, lodash_1.without)(fields, ...aliases));
|
|
87
89
|
const payloadWithTypeCasting = await payloadService.processValues('create', payloadWithoutAliases);
|
|
88
|
-
// In case of manual string / UUID primary keys,
|
|
90
|
+
// In case of manual string / UUID primary keys, the PK already exists in the object we're saving.
|
|
89
91
|
let primaryKey = payloadWithTypeCasting[primaryKeyField];
|
|
90
92
|
try {
|
|
91
93
|
const result = await trx.insert(payloadWithoutAliases).into(this.collection).returning(primaryKeyField);
|
|
@@ -146,14 +148,14 @@ class ItemsService {
|
|
|
146
148
|
return primaryKey;
|
|
147
149
|
});
|
|
148
150
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
149
|
-
emitter_1.default.emitAction(`${this.eventScope}.create`, {
|
|
151
|
+
emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.create', `${this.collection}.items.create`] : `${this.eventScope}.create`, {
|
|
150
152
|
payload,
|
|
151
153
|
key: primaryKey,
|
|
152
154
|
collection: this.collection,
|
|
153
155
|
}, {
|
|
154
156
|
// This hook is called async. If we would pass the transaction here, the hook can be
|
|
155
157
|
// called after the transaction is done #5460
|
|
156
|
-
database: (0, database_1.default)(),
|
|
158
|
+
database: this.knex || (0, database_1.default)(),
|
|
157
159
|
schema: this.schema,
|
|
158
160
|
accountability: this.accountability,
|
|
159
161
|
});
|
|
@@ -189,11 +191,6 @@ class ItemsService {
|
|
|
189
191
|
* Get items by query
|
|
190
192
|
*/
|
|
191
193
|
async readByQuery(query, opts) {
|
|
192
|
-
const authorizationService = new authorization_1.AuthorizationService({
|
|
193
|
-
accountability: this.accountability,
|
|
194
|
-
knex: this.knex,
|
|
195
|
-
schema: this.schema,
|
|
196
|
-
});
|
|
197
194
|
let ast = await (0, get_ast_from_query_1.default)(this.collection, query, this.schema, {
|
|
198
195
|
accountability: this.accountability,
|
|
199
196
|
// By setting the permissions action, you can read items using the permissions for another
|
|
@@ -203,6 +200,11 @@ class ItemsService {
|
|
|
203
200
|
knex: this.knex,
|
|
204
201
|
});
|
|
205
202
|
if (this.accountability && this.accountability.admin !== true) {
|
|
203
|
+
const authorizationService = new authorization_1.AuthorizationService({
|
|
204
|
+
accountability: this.accountability,
|
|
205
|
+
knex: this.knex,
|
|
206
|
+
schema: this.schema,
|
|
207
|
+
});
|
|
206
208
|
ast = await authorizationService.processAST(ast, opts === null || opts === void 0 ? void 0 : opts.permissionsAction);
|
|
207
209
|
}
|
|
208
210
|
const records = await (0, run_ast_1.default)(ast, this.schema, {
|
|
@@ -213,7 +215,7 @@ class ItemsService {
|
|
|
213
215
|
if (records === null) {
|
|
214
216
|
throw new exceptions_1.ForbiddenException();
|
|
215
217
|
}
|
|
216
|
-
const filteredRecords = await emitter_1.default.emitFilter(`${this.eventScope}.read`, records, {
|
|
218
|
+
const filteredRecords = await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, records, {
|
|
217
219
|
query,
|
|
218
220
|
collection: this.collection,
|
|
219
221
|
}, {
|
|
@@ -221,12 +223,12 @@ class ItemsService {
|
|
|
221
223
|
schema: this.schema,
|
|
222
224
|
accountability: this.accountability,
|
|
223
225
|
});
|
|
224
|
-
emitter_1.default.emitAction(`${this.eventScope}.read`, {
|
|
226
|
+
emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.read', `${this.collection}.items.read`] : `${this.eventScope}.read`, {
|
|
225
227
|
payload: filteredRecords,
|
|
226
228
|
query,
|
|
227
229
|
collection: this.collection,
|
|
228
230
|
}, {
|
|
229
|
-
database: (0, database_1.default)(),
|
|
231
|
+
database: this.knex || (0, database_1.default)(),
|
|
230
232
|
schema: this.schema,
|
|
231
233
|
accountability: this.accountability,
|
|
232
234
|
});
|
|
@@ -288,7 +290,9 @@ class ItemsService {
|
|
|
288
290
|
// Run all hooks that are attached to this event so the end user has the chance to augment the
|
|
289
291
|
// item that is about to be saved
|
|
290
292
|
const payloadAfterHooks = (opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false
|
|
291
|
-
? await emitter_1.default.emitFilter(
|
|
293
|
+
? await emitter_1.default.emitFilter(this.eventScope === 'items'
|
|
294
|
+
? ['items.update', `${this.collection}.items.update`]
|
|
295
|
+
: `${this.eventScope}.update`, payload, {
|
|
292
296
|
keys,
|
|
293
297
|
collection: this.collection,
|
|
294
298
|
}, {
|
|
@@ -379,14 +383,14 @@ class ItemsService {
|
|
|
379
383
|
await this.cache.clear();
|
|
380
384
|
}
|
|
381
385
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
382
|
-
emitter_1.default.emitAction(`${this.eventScope}.update`, {
|
|
386
|
+
emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.update', `${this.collection}.items.update`] : `${this.eventScope}.update`, {
|
|
383
387
|
payload,
|
|
384
388
|
keys,
|
|
385
389
|
collection: this.collection,
|
|
386
390
|
}, {
|
|
387
391
|
// This hook is called async. If we would pass the transaction here, the hook can be
|
|
388
392
|
// called after the transaction is done #5460
|
|
389
|
-
database: (0, database_1.default)(),
|
|
393
|
+
database: this.knex || (0, database_1.default)(),
|
|
390
394
|
schema: this.schema,
|
|
391
395
|
accountability: this.accountability,
|
|
392
396
|
});
|
|
@@ -461,7 +465,7 @@ class ItemsService {
|
|
|
461
465
|
await authorizationService.checkAccess('delete', this.collection, keys);
|
|
462
466
|
}
|
|
463
467
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
464
|
-
await emitter_1.default.emitFilter(`${this.eventScope}.delete`, keys, {
|
|
468
|
+
await emitter_1.default.emitFilter(this.eventScope === 'items' ? ['items.delete', `${this.collection}.items.delete`] : `${this.eventScope}.delete`, keys, {
|
|
465
469
|
collection: this.collection,
|
|
466
470
|
}, {
|
|
467
471
|
database: this.knex,
|
|
@@ -490,13 +494,13 @@ class ItemsService {
|
|
|
490
494
|
await this.cache.clear();
|
|
491
495
|
}
|
|
492
496
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
493
|
-
emitter_1.default.emitAction(`${this.eventScope}.delete`, {
|
|
497
|
+
emitter_1.default.emitAction(this.eventScope === 'items' ? ['items.delete', `${this.collection}.items.delete`] : `${this.eventScope}.delete`, {
|
|
494
498
|
payload: keys,
|
|
495
499
|
collection: this.collection,
|
|
496
500
|
}, {
|
|
497
501
|
// This hook is called async. If we would pass the transaction here, the hook can be
|
|
498
502
|
// called after the transaction is done #5460
|
|
499
|
-
database: (0, database_1.default)(),
|
|
503
|
+
database: this.knex || (0, database_1.default)(),
|
|
500
504
|
schema: this.schema,
|
|
501
505
|
accountability: this.accountability,
|
|
502
506
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions } from '../../types';
|
|
3
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
import { Transporter, SendMailOptions } from 'nodemailer';
|
|
5
5
|
export declare type EmailOptions = SendMailOptions & {
|
|
6
6
|
template?: {
|
package/dist/services/meta.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions
|
|
3
|
-
import { Accountability, Query } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions } from '../types';
|
|
3
|
+
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
export declare class MetaService {
|
|
5
5
|
knex: Knex;
|
|
6
6
|
accountability: Accountability | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions, Item, PrimaryKey
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions, Item, PrimaryKey } from '../types';
|
|
3
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
import { Helpers } from '../database/helpers';
|
|
5
5
|
declare type Action = 'create' | 'read' | 'update';
|
|
6
6
|
declare type Transformers = {
|
package/dist/services/payload.js
CHANGED
|
@@ -100,12 +100,16 @@ class PayloadService {
|
|
|
100
100
|
return value;
|
|
101
101
|
},
|
|
102
102
|
async csv({ action, value }) {
|
|
103
|
-
if (
|
|
103
|
+
if (Array.isArray(value) === false && typeof value !== 'string')
|
|
104
104
|
return;
|
|
105
|
-
if (action === 'read' && Array.isArray(value) === false)
|
|
105
|
+
if (action === 'read' && Array.isArray(value) === false) {
|
|
106
|
+
if (value === '')
|
|
107
|
+
return [];
|
|
106
108
|
return value.split(',');
|
|
107
|
-
|
|
109
|
+
}
|
|
110
|
+
if (Array.isArray(value)) {
|
|
108
111
|
return value.join(',');
|
|
112
|
+
}
|
|
109
113
|
return value;
|
|
110
114
|
},
|
|
111
115
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import {
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { SchemaOverview, Relation, RelationMeta, Accountability } from '@directus/shared/types';
|
|
4
3
|
import { ItemsService, QueryOptions } from './items';
|
|
5
4
|
import { PermissionsService } from './permissions';
|
|
6
5
|
import SchemaInspector from '@directus/schema';
|
|
7
6
|
import Keyv from 'keyv';
|
|
7
|
+
import { AbstractServiceOptions } from '../types';
|
|
8
8
|
export declare class RelationsService {
|
|
9
9
|
knex: Knex;
|
|
10
10
|
permissionsService: PermissionsService;
|
|
@@ -135,6 +135,10 @@ class RelationsService {
|
|
|
135
135
|
if (relation.field in this.schema.collections[relation.collection].fields === false) {
|
|
136
136
|
throw new exceptions_1.InvalidPayloadException(`Field "${relation.field}" doesn't exist in collection "${relation.collection}"`);
|
|
137
137
|
}
|
|
138
|
+
// A primary key should not be a foreign key
|
|
139
|
+
if (this.schema.collections[relation.collection].primary === relation.field) {
|
|
140
|
+
throw new exceptions_1.InvalidPayloadException(`Field "${relation.field}" in collection "${relation.collection}" is a primary key`);
|
|
141
|
+
}
|
|
138
142
|
if (relation.related_collection && relation.related_collection in this.schema.collections === false) {
|
|
139
143
|
throw new exceptions_1.InvalidPayloadException(`Collection "${relation.related_collection}" doesn't exist`);
|
|
140
144
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions } from '../types';
|
|
3
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
import { SettingsService } from './settings';
|
|
5
5
|
export declare class ServerService {
|
|
6
6
|
knex: Knex;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { OpenAPIObject } from 'openapi3-ts';
|
|
3
|
-
import { AbstractServiceOptions
|
|
4
|
-
import { Accountability } from '@directus/shared/types';
|
|
3
|
+
import { AbstractServiceOptions } from '../types';
|
|
4
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
5
|
import { CollectionsService } from './collections';
|
|
6
6
|
import { FieldsService } from './fields';
|
|
7
7
|
import { GraphQLService } from './graphql';
|
package/dist/services/users.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions, Item, PrimaryKey,
|
|
3
|
-
import { Query } from '@directus/shared/types';
|
|
4
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions, Item, PrimaryKey, MutationOptions } from '../types';
|
|
3
|
+
import { Query, SchemaOverview, Accountability } from '@directus/shared/types';
|
|
5
4
|
import { ItemsService } from './items';
|
|
6
5
|
export declare class UsersService extends ItemsService {
|
|
7
6
|
knex: Knex;
|
package/dist/services/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { AbstractServiceOptions, PrimaryKey
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions, PrimaryKey } from '../types';
|
|
3
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
export declare class UtilsService {
|
|
5
5
|
knex: Knex;
|
|
6
6
|
accountability: Accountability | null;
|
package/dist/types/ast.d.ts
CHANGED
package/dist/types/auth.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
1
2
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from './schema';
|
|
3
3
|
export interface AuthDriverOptions {
|
|
4
4
|
knex: Knex;
|
|
5
5
|
schema: SchemaOverview;
|
|
@@ -22,10 +22,8 @@ export declare type AuthData = Record<string, any> | null;
|
|
|
22
22
|
export interface Session {
|
|
23
23
|
token: string;
|
|
24
24
|
expires: Date;
|
|
25
|
-
data: string | Record<string, unknown> | null;
|
|
26
25
|
share: string;
|
|
27
26
|
}
|
|
28
|
-
export declare type SessionData = Record<string, any> | null;
|
|
29
27
|
export declare type DirectusTokenPayload = {
|
|
30
28
|
id?: string;
|
|
31
29
|
role: string | null;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,15 +3,12 @@ export * from './assets';
|
|
|
3
3
|
export * from './ast';
|
|
4
4
|
export * from './auth';
|
|
5
5
|
export * from './collection';
|
|
6
|
-
export * from './extensions';
|
|
7
6
|
export * from './files';
|
|
8
7
|
export * from './graphql';
|
|
9
8
|
export * from './items';
|
|
10
9
|
export * from './meta';
|
|
11
10
|
export * from './migration';
|
|
12
|
-
export * from './relation';
|
|
13
11
|
export * from './revision';
|
|
14
|
-
export * from './schema';
|
|
15
12
|
export * from './services';
|
|
16
13
|
export * from './snapshot';
|
|
17
14
|
export * from './webhooks';
|
package/dist/types/index.js
CHANGED
|
@@ -15,15 +15,12 @@ __exportStar(require("./assets"), exports);
|
|
|
15
15
|
__exportStar(require("./ast"), exports);
|
|
16
16
|
__exportStar(require("./auth"), exports);
|
|
17
17
|
__exportStar(require("./collection"), exports);
|
|
18
|
-
__exportStar(require("./extensions"), exports);
|
|
19
18
|
__exportStar(require("./files"), exports);
|
|
20
19
|
__exportStar(require("./graphql"), exports);
|
|
21
20
|
__exportStar(require("./items"), exports);
|
|
22
21
|
__exportStar(require("./meta"), exports);
|
|
23
22
|
__exportStar(require("./migration"), exports);
|
|
24
|
-
__exportStar(require("./relation"), exports);
|
|
25
23
|
__exportStar(require("./revision"), exports);
|
|
26
|
-
__exportStar(require("./schema"), exports);
|
|
27
24
|
__exportStar(require("./services"), exports);
|
|
28
25
|
__exportStar(require("./snapshot"), exports);
|
|
29
26
|
__exportStar(require("./webhooks"), exports);
|
package/dist/types/services.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
import { Item, PrimaryKey } from './items';
|
|
5
|
-
import { Query } from '@directus/shared/types';
|
|
6
4
|
export declare type AbstractServiceOptions = {
|
|
7
5
|
knex?: Knex;
|
|
8
6
|
accountability?: Accountability | null;
|
package/dist/types/snapshot.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Collection } from './collection';
|
|
2
|
-
import { Relation, RelationMeta } from '
|
|
3
|
-
import { Field, FieldMeta } from '@directus/shared/types';
|
|
2
|
+
import { Relation, RelationMeta, Field, FieldMeta } from '@directus/shared/types';
|
|
4
3
|
import { Diff } from 'deep-diff';
|
|
5
4
|
export declare type Snapshot = {
|
|
6
5
|
version: number;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Aggregate, Filter, Query } from '@directus/shared/types';
|
|
2
|
+
import { Aggregate, Filter, Query, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
/**
|
|
5
4
|
* Apply the Query to a given Knex query builder instance
|
|
6
5
|
*/
|
|
@@ -177,7 +177,7 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
177
177
|
if (relationType === 'o2m' && (subQuery === true || parentAlias !== undefined)) {
|
|
178
178
|
dbQuery.leftJoin({ [alias]: relation.collection }, `${parentAlias || parentCollection}.${schema.collections[relation.related_collection].primary}`, `${alias}.${relation.field}`);
|
|
179
179
|
}
|
|
180
|
-
if (relationType === 'm2o' || subQuery === true) {
|
|
180
|
+
if (relationType === 'm2o' || subQuery === true || (relationType === 'o2m' && parentAlias !== undefined)) {
|
|
181
181
|
let parent;
|
|
182
182
|
if (relationType === 'm2o') {
|
|
183
183
|
parent = relation.related_collection;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Snapshot, SnapshotDiff
|
|
1
|
+
import { Snapshot, SnapshotDiff } from '../types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
3
4
|
export declare function applySnapshot(snapshot: Snapshot, options?: {
|
|
4
5
|
database?: Knex;
|
|
5
6
|
schema?: SchemaOverview;
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Generate an AST based on a given collection and query
|
|
3
3
|
*/
|
|
4
4
|
import { Knex } from 'knex';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { Query, PermissionsAction } from '@directus/shared/types';
|
|
5
|
+
import { AST } from '../types';
|
|
6
|
+
import { Query, PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
8
7
|
declare type GetASTOptions = {
|
|
9
8
|
accountability?: Accountability | null;
|
|
10
9
|
action?: PermissionsAction;
|
|
@@ -107,7 +107,7 @@ function getLocalType(column, field) {
|
|
|
107
107
|
return 'hash';
|
|
108
108
|
if (special.includes('csv'))
|
|
109
109
|
return 'csv';
|
|
110
|
-
if (special.includes('uuid'))
|
|
110
|
+
if (special.includes('uuid') || special.includes('file'))
|
|
111
111
|
return 'uuid';
|
|
112
112
|
if (type === null || type === void 0 ? void 0 : type.startsWith('geometry')) {
|
|
113
113
|
return special[0] || 'geometry';
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { Permission, Accountability } from '@directus/shared/types';
|
|
2
|
-
import { SchemaOverview } from '../types';
|
|
1
|
+
import { Permission, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
3
2
|
export declare function getPermissions(accountability: Accountability, schema: SchemaOverview): Promise<Permission[]>;
|
|
@@ -145,7 +145,7 @@ function processPermissions(accountability, permissions, filterContext) {
|
|
|
145
145
|
return permissions.map((permission) => {
|
|
146
146
|
permission.permissions = (0, utils_1.parseFilter)(permission.permissions, accountability, filterContext);
|
|
147
147
|
permission.validation = (0, utils_1.parseFilter)(permission.validation, accountability, filterContext);
|
|
148
|
-
permission.presets = (0, utils_1.
|
|
148
|
+
permission.presets = (0, utils_1.parsePreset)(permission.presets, accountability, filterContext);
|
|
149
149
|
return permission;
|
|
150
150
|
});
|
|
151
151
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import { SchemaOverview } from '
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
2
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
3
|
export declare function getSchema(options?: {
|
|
5
4
|
accountability?: Accountability;
|
|
6
5
|
database?: Knex;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Snapshot } from '../types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
3
4
|
export declare function getSnapshot(options?: {
|
|
4
5
|
database?: Knex;
|
|
5
6
|
schema?: SchemaOverview;
|