directus 9.4.3 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/auth/auth.d.ts +2 -1
- package/dist/auth/drivers/oauth2.js +10 -20
- package/dist/auth/drivers/openid.js +12 -2
- package/dist/cli/commands/init/questions.d.ts +3 -0
- package/dist/cli/commands/init/questions.js +2 -0
- 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/files.js +1 -1
- 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 +33 -16
- 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/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/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +3 -4
- package/dist/emitter.js +2 -8
- 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 +6 -5
- package/dist/extensions.js +56 -42
- package/dist/logger.js +22 -1
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +3 -1
- package/dist/services/authorization.d.ts +2 -3
- package/dist/services/collections.d.ts +2 -2
- package/dist/services/collections.js +10 -6
- package/dist/services/fields.d.ts +2 -3
- package/dist/services/fields.js +8 -4
- package/dist/services/graphql.d.ts +2 -1
- 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/relations.d.ts +2 -2
- 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-permissions.d.ts +1 -2
- 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/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 +15 -14
- 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
package/dist/extensions.js
CHANGED
|
@@ -56,22 +56,27 @@ function getExtensionManager() {
|
|
|
56
56
|
return extensionManager;
|
|
57
57
|
}
|
|
58
58
|
exports.getExtensionManager = getExtensionManager;
|
|
59
|
+
const defaultOptions = {
|
|
60
|
+
schedule: true,
|
|
61
|
+
watch: env_1.default.EXTENSIONS_AUTO_RELOAD && env_1.default.NODE_ENV !== 'development',
|
|
62
|
+
};
|
|
59
63
|
class ExtensionManager {
|
|
60
64
|
constructor() {
|
|
61
65
|
this.isLoaded = false;
|
|
62
|
-
this.isScheduleHookEnabled = true;
|
|
63
66
|
this.extensions = [];
|
|
64
67
|
this.appExtensions = {};
|
|
65
68
|
this.apiExtensions = { hooks: [], endpoints: [] };
|
|
66
69
|
this.watcher = null;
|
|
70
|
+
this.options = defaultOptions;
|
|
67
71
|
this.apiEmitter = new emitter_1.Emitter();
|
|
68
72
|
this.endpointRouter = (0, express_1.Router)();
|
|
69
73
|
}
|
|
70
|
-
async initialize(
|
|
71
|
-
this.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
74
|
+
async initialize(options = {}) {
|
|
75
|
+
this.options = {
|
|
76
|
+
...defaultOptions,
|
|
77
|
+
...options,
|
|
78
|
+
};
|
|
79
|
+
this.initializeWatcher();
|
|
75
80
|
if (!this.isLoaded) {
|
|
76
81
|
await this.load();
|
|
77
82
|
this.updateWatchedExtensions(this.extensions);
|
|
@@ -143,9 +148,9 @@ class ExtensionManager {
|
|
|
143
148
|
this.isLoaded = false;
|
|
144
149
|
}
|
|
145
150
|
initializeWatcher() {
|
|
146
|
-
if (
|
|
151
|
+
if (this.options.watch && !this.watcher) {
|
|
147
152
|
logger_1.default.info('Watching extensions for changes...');
|
|
148
|
-
const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.
|
|
153
|
+
const localExtensionPaths = (env_1.default.SERVE_APP ? constants_1.EXTENSION_TYPES : constants_1.API_EXTENSION_TYPES).map((type) => path_1.default.posix.join(path_1.default.relative('.', env_1.default.EXTENSIONS_PATH).split(path_1.default.sep).join(path_1.default.posix.sep), (0, utils_1.pluralize)(type), '*', 'index.js'));
|
|
149
154
|
this.watcher = chokidar_1.default.watch([path_1.default.resolve('.', 'package.json'), ...localExtensionPaths], {
|
|
150
155
|
ignoreInitial: true,
|
|
151
156
|
});
|
|
@@ -182,15 +187,21 @@ class ExtensionManager {
|
|
|
182
187
|
const bundles = {};
|
|
183
188
|
for (const extensionType of constants_1.APP_EXTENSION_TYPES) {
|
|
184
189
|
const entry = (0, node_1.generateExtensionsEntry)(extensionType, this.extensions);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
190
|
+
try {
|
|
191
|
+
const bundle = await (0, rollup_1.rollup)({
|
|
192
|
+
input: 'entry',
|
|
193
|
+
external: Object.values(sharedDepsMapping),
|
|
194
|
+
makeAbsoluteExternalsRelative: false,
|
|
195
|
+
plugins: [(0, plugin_virtual_1.default)({ entry }), (0, plugin_alias_1.default)({ entries: internalImports })],
|
|
196
|
+
});
|
|
197
|
+
const { output } = await bundle.generate({ format: 'es', compact: true });
|
|
198
|
+
bundles[extensionType] = output[0].code;
|
|
199
|
+
await bundle.close();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
logger_1.default.warn(`Couldn't bundle App extensions`);
|
|
203
|
+
logger_1.default.warn(error);
|
|
204
|
+
}
|
|
194
205
|
}
|
|
195
206
|
return bundles;
|
|
196
207
|
}
|
|
@@ -238,38 +249,39 @@ class ExtensionManager {
|
|
|
238
249
|
const hookPath = path_1.default.resolve(hook.path, hook.entrypoint || '');
|
|
239
250
|
const hookInstance = require(hookPath);
|
|
240
251
|
const register = (0, get_module_default_1.default)(hookInstance);
|
|
252
|
+
const hookHandler = {
|
|
253
|
+
path: hookPath,
|
|
254
|
+
events: [],
|
|
255
|
+
};
|
|
241
256
|
const registerFunctions = {
|
|
242
257
|
filter: (event, handler) => {
|
|
243
258
|
emitter_1.default.onFilter(event, handler);
|
|
244
|
-
|
|
259
|
+
hookHandler.events.push({
|
|
245
260
|
type: 'filter',
|
|
246
|
-
|
|
247
|
-
event,
|
|
261
|
+
name: event,
|
|
248
262
|
handler,
|
|
249
263
|
});
|
|
250
264
|
},
|
|
251
265
|
action: (event, handler) => {
|
|
252
266
|
emitter_1.default.onAction(event, handler);
|
|
253
|
-
|
|
267
|
+
hookHandler.events.push({
|
|
254
268
|
type: 'action',
|
|
255
|
-
|
|
256
|
-
event,
|
|
269
|
+
name: event,
|
|
257
270
|
handler,
|
|
258
271
|
});
|
|
259
272
|
},
|
|
260
273
|
init: (event, handler) => {
|
|
261
274
|
emitter_1.default.onInit(event, handler);
|
|
262
|
-
|
|
275
|
+
hookHandler.events.push({
|
|
263
276
|
type: 'init',
|
|
264
|
-
|
|
265
|
-
event,
|
|
277
|
+
name: event,
|
|
266
278
|
handler,
|
|
267
279
|
});
|
|
268
280
|
},
|
|
269
281
|
schedule: (cron, handler) => {
|
|
270
282
|
if ((0, node_cron_1.validate)(cron)) {
|
|
271
283
|
const task = (0, node_cron_1.schedule)(cron, async () => {
|
|
272
|
-
if (this.
|
|
284
|
+
if (this.options.schedule) {
|
|
273
285
|
try {
|
|
274
286
|
await handler();
|
|
275
287
|
}
|
|
@@ -278,9 +290,8 @@ class ExtensionManager {
|
|
|
278
290
|
}
|
|
279
291
|
}
|
|
280
292
|
});
|
|
281
|
-
|
|
293
|
+
hookHandler.events.push({
|
|
282
294
|
type: 'schedule',
|
|
283
|
-
path: hookPath,
|
|
284
295
|
task,
|
|
285
296
|
});
|
|
286
297
|
}
|
|
@@ -298,6 +309,7 @@ class ExtensionManager {
|
|
|
298
309
|
logger: logger_1.default,
|
|
299
310
|
getSchema: get_schema_1.getSchema,
|
|
300
311
|
});
|
|
312
|
+
this.apiExtensions.hooks.push(hookHandler);
|
|
301
313
|
}
|
|
302
314
|
registerEndpoint(endpoint, router) {
|
|
303
315
|
const endpointPath = path_1.default.resolve(endpoint.path, endpoint.entrypoint || '');
|
|
@@ -322,19 +334,21 @@ class ExtensionManager {
|
|
|
322
334
|
}
|
|
323
335
|
unregisterHooks() {
|
|
324
336
|
for (const hook of this.apiExtensions.hooks) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
337
|
+
for (const event of hook.events) {
|
|
338
|
+
switch (event.type) {
|
|
339
|
+
case 'filter':
|
|
340
|
+
emitter_1.default.offFilter(event.name, event.handler);
|
|
341
|
+
break;
|
|
342
|
+
case 'action':
|
|
343
|
+
emitter_1.default.offAction(event.name, event.handler);
|
|
344
|
+
break;
|
|
345
|
+
case 'init':
|
|
346
|
+
emitter_1.default.offInit(event.name, event.handler);
|
|
347
|
+
break;
|
|
348
|
+
case 'schedule':
|
|
349
|
+
event.task.stop();
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
338
352
|
}
|
|
339
353
|
delete require.cache[require.resolve(hook.path)];
|
|
340
354
|
}
|
package/dist/logger.js
CHANGED
|
@@ -25,6 +25,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.expressLogger = void 0;
|
|
26
26
|
const pino_1 = __importDefault(require("pino"));
|
|
27
27
|
const pino_http_1 = __importStar(require("pino-http"));
|
|
28
|
+
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
28
29
|
const url_1 = require("url");
|
|
29
30
|
const env_1 = __importDefault(require("./env"));
|
|
30
31
|
const pinoOptions = {
|
|
@@ -38,9 +39,29 @@ if (env_1.default.LOG_STYLE !== 'raw') {
|
|
|
38
39
|
pinoOptions.prettyPrint = true;
|
|
39
40
|
pinoOptions.prettifier = require('pino-colada');
|
|
40
41
|
}
|
|
41
|
-
const
|
|
42
|
+
const loggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_', 'LOGGER_HTTP');
|
|
43
|
+
// Expose custom log levels into formatter function
|
|
44
|
+
if (loggerEnvConfig.levels) {
|
|
45
|
+
const customLogLevels = {};
|
|
46
|
+
for (const el of loggerEnvConfig.levels.split(',')) {
|
|
47
|
+
const key_val = el.split(':');
|
|
48
|
+
customLogLevels[key_val[0].trim()] = key_val[1].trim();
|
|
49
|
+
}
|
|
50
|
+
pinoOptions.formatters = {
|
|
51
|
+
level(label, number) {
|
|
52
|
+
return {
|
|
53
|
+
severity: customLogLevels[label] || 'info',
|
|
54
|
+
level: number,
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
delete loggerEnvConfig.levels;
|
|
59
|
+
}
|
|
60
|
+
const logger = (0, pino_1.default)(Object.assign(pinoOptions, loggerEnvConfig));
|
|
61
|
+
const httpLoggerEnvConfig = (0, get_config_from_env_1.getConfigFromEnv)('LOGGER_HTTP', ['LOGGER_HTTP_LOGGER']);
|
|
42
62
|
exports.expressLogger = (0, pino_http_1.default)({
|
|
43
63
|
logger,
|
|
64
|
+
...httpLoggerEnvConfig,
|
|
44
65
|
}, {
|
|
45
66
|
serializers: {
|
|
46
67
|
req(request) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { ActivityService } from './activity';
|
|
3
|
-
import { AbstractServiceOptions,
|
|
4
|
-
import { Accountability } from '@directus/shared/types';
|
|
3
|
+
import { AbstractServiceOptions, LoginResult } from '../types';
|
|
4
|
+
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
5
|
export declare class AuthenticationService {
|
|
6
6
|
knex: Knex;
|
|
7
7
|
accountability: Accountability | null;
|
|
@@ -204,7 +204,9 @@ class AuthenticationService {
|
|
|
204
204
|
.from('directus_sessions AS s')
|
|
205
205
|
.leftJoin('directus_users AS u', 's.user', 'u.id')
|
|
206
206
|
.leftJoin('directus_shares AS d', 's.share', 'd.id')
|
|
207
|
-
.
|
|
207
|
+
.leftJoin('directus_roles AS r', (join) => {
|
|
208
|
+
join.onIn('r.id', [this.knex.ref('u.role'), this.knex.ref('d.role')]);
|
|
209
|
+
})
|
|
208
210
|
.where('s.token', refreshToken)
|
|
209
211
|
.andWhere('s.expires', '>=', new Date())
|
|
210
212
|
.andWhere((subQuery) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { PermissionsAction } from '@directus/shared/types';
|
|
2
|
+
import { AbstractServiceOptions, AST, Item, PrimaryKey } from '../types';
|
|
3
|
+
import { PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types';
|
|
5
4
|
import { PayloadService } from './payload';
|
|
6
5
|
export declare class AuthorizationService {
|
|
7
6
|
knex: Knex;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import SchemaInspector from '@directus/schema';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
3
|
import Keyv from 'keyv';
|
|
4
|
-
import { AbstractServiceOptions, Collection, CollectionMeta,
|
|
5
|
-
import { Accountability, RawField } from '@directus/shared/types';
|
|
4
|
+
import { AbstractServiceOptions, Collection, CollectionMeta, MutationOptions } from '../types';
|
|
5
|
+
import { Accountability, RawField, SchemaOverview } from '@directus/shared/types';
|
|
6
6
|
import { Table } from 'knex-schema-inspector/dist/types/table';
|
|
7
7
|
export declare type RawCollection = {
|
|
8
8
|
collection: string;
|
|
@@ -114,12 +114,14 @@ class CollectionsService {
|
|
|
114
114
|
}
|
|
115
115
|
return field;
|
|
116
116
|
});
|
|
117
|
-
await trx.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
await trx.transaction(async (schemaTrx) => {
|
|
118
|
+
await schemaTrx.schema.createTable(payload.collection, (table) => {
|
|
119
|
+
for (const field of payload.fields) {
|
|
120
|
+
if (field.type && constants_1.ALIAS_TYPES.includes(field.type) === false) {
|
|
121
|
+
fieldsService.addColumnToTable(table, field);
|
|
122
|
+
}
|
|
121
123
|
}
|
|
122
|
-
}
|
|
124
|
+
});
|
|
123
125
|
});
|
|
124
126
|
const fieldPayloads = payload.fields.filter((field) => field.meta).map((field) => field.meta);
|
|
125
127
|
await fieldItemsService.createMany(fieldPayloads);
|
|
@@ -371,7 +373,9 @@ class CollectionsService {
|
|
|
371
373
|
.update({ one_allowed_collections: newAllowedCollections })
|
|
372
374
|
.where({ id: relation.meta.id });
|
|
373
375
|
}
|
|
374
|
-
await trx.
|
|
376
|
+
await trx.transaction(async (schemaTrx) => {
|
|
377
|
+
await schemaTrx.schema.dropTable(collectionKey);
|
|
378
|
+
});
|
|
375
379
|
}
|
|
376
380
|
});
|
|
377
381
|
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
|
@@ -224,8 +224,10 @@ class FieldsService {
|
|
|
224
224
|
this.addColumnToTable(table, hookAdjustedField);
|
|
225
225
|
}
|
|
226
226
|
else {
|
|
227
|
-
await trx.
|
|
228
|
-
|
|
227
|
+
await trx.transaction(async (schemaTrx) => {
|
|
228
|
+
await schemaTrx.schema.alterTable(collection, (table) => {
|
|
229
|
+
this.addColumnToTable(table, hookAdjustedField);
|
|
230
|
+
});
|
|
229
231
|
});
|
|
230
232
|
}
|
|
231
233
|
}
|
|
@@ -387,8 +389,10 @@ class FieldsService {
|
|
|
387
389
|
if (this.schema.collections[collection] &&
|
|
388
390
|
field in this.schema.collections[collection].fields &&
|
|
389
391
|
this.schema.collections[collection].fields[field].alias === false) {
|
|
390
|
-
await trx.
|
|
391
|
-
table
|
|
392
|
+
await trx.transaction(async (schemaTrx) => {
|
|
393
|
+
await schemaTrx.schema.table(collection, (table) => {
|
|
394
|
+
table.dropColumn(field);
|
|
395
|
+
});
|
|
392
396
|
});
|
|
393
397
|
}
|
|
394
398
|
});
|
|
@@ -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;
|
|
@@ -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 = {
|
|
@@ -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;
|
|
@@ -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;
|