directus 9.21.0 → 9.21.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/auth/drivers/openid.js +3 -1
- package/dist/cli/commands/schema/apply.js +0 -2
- package/dist/cli/commands/schema/snapshot.js +0 -2
- package/dist/database/helpers/fn/dialects/mysql.js +1 -1
- package/dist/middleware/schema.js +1 -1
- package/dist/services/collections.js +7 -7
- package/dist/services/fields.d.ts +3 -2
- package/dist/services/fields.js +40 -20
- package/dist/services/relations.d.ts +2 -2
- package/dist/services/relations.js +24 -16
- package/dist/services/users.js +10 -4
- package/dist/utils/apply-snapshot.js +32 -13
- package/dist/utils/get-schema.d.ts +6 -2
- package/dist/utils/get-schema.js +1 -1
- package/dist/utils/get-snapshot.js +1 -1
- package/package.json +11 -21
|
@@ -99,6 +99,7 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
99
99
|
code_challenge_method: 'S256',
|
|
100
100
|
// Some providers require state even with PKCE
|
|
101
101
|
state: codeChallenge,
|
|
102
|
+
nonce: codeChallenge,
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
105
|
catch (e) {
|
|
@@ -122,7 +123,8 @@ class OpenIDAuthDriver extends local_1.LocalAuthDriver {
|
|
|
122
123
|
let userInfo;
|
|
123
124
|
try {
|
|
124
125
|
const client = await this.client;
|
|
125
|
-
|
|
126
|
+
const codeChallenge = openid_client_1.generators.codeChallenge(payload.codeVerifier);
|
|
127
|
+
tokenSet = await client.callback(this.redirectUrl, { code: payload.code, state: payload.state }, { code_verifier: payload.codeVerifier, state: codeChallenge, nonce: codeChallenge });
|
|
126
128
|
userInfo = tokenSet.claims();
|
|
127
129
|
if (client.issuer.metadata.userinfo_endpoint) {
|
|
128
130
|
userInfo = {
|
|
@@ -33,7 +33,6 @@ const fs_1 = require("fs");
|
|
|
33
33
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
34
34
|
const js_yaml_1 = require("js-yaml");
|
|
35
35
|
const path_1 = __importDefault(require("path"));
|
|
36
|
-
const cache_1 = require("../../../cache");
|
|
37
36
|
const database_1 = __importStar(require("../../../database"));
|
|
38
37
|
const logger_1 = __importDefault(require("../../../logger"));
|
|
39
38
|
const apply_snapshot_1 = require("../../../utils/apply-snapshot");
|
|
@@ -44,7 +43,6 @@ async function apply(snapshotPath, options) {
|
|
|
44
43
|
const filename = path_1.default.resolve(process.cwd(), snapshotPath);
|
|
45
44
|
const database = (0, database_1.default)();
|
|
46
45
|
await (0, database_1.validateDatabaseConnection)(database);
|
|
47
|
-
await (0, cache_1.flushCaches)();
|
|
48
46
|
if ((await (0, database_1.isInstalled)()) === false) {
|
|
49
47
|
logger_1.default.error(`Directus isn't installed on this database. Please run "directus bootstrap" first.`);
|
|
50
48
|
database.destroy();
|
|
@@ -11,9 +11,7 @@ const fs_1 = require("fs");
|
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
13
13
|
const js_yaml_1 = require("js-yaml");
|
|
14
|
-
const cache_1 = require("../../../cache");
|
|
15
14
|
async function snapshot(snapshotPath, options) {
|
|
16
|
-
await (0, cache_1.flushCaches)();
|
|
17
15
|
const database = (0, database_1.default)();
|
|
18
16
|
try {
|
|
19
17
|
const snapshot = await (0, get_snapshot_1.getSnapshot)({ database });
|
|
@@ -4,7 +4,7 @@ exports.FnHelperMySQL = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const parseLocaltime = (columnType) => {
|
|
6
6
|
if (columnType === 'timestamp') {
|
|
7
|
-
return `CONVERT_TZ(??.??, @@GLOBAL.time_zone, '
|
|
7
|
+
return `CONVERT_TZ(??.??, @@GLOBAL.time_zone, '+00:00')`;
|
|
8
8
|
}
|
|
9
9
|
return '??.??';
|
|
10
10
|
};
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
7
7
|
const get_schema_1 = require("../utils/get-schema");
|
|
8
8
|
const schema = (0, async_handler_1.default)(async (req, res, next) => {
|
|
9
|
-
req.schema = await (0, get_schema_1.getSchema)(
|
|
9
|
+
req.schema = await (0, get_schema_1.getSchema)();
|
|
10
10
|
return next();
|
|
11
11
|
});
|
|
12
12
|
exports.default = schema;
|
|
@@ -157,7 +157,7 @@ class CollectionsService {
|
|
|
157
157
|
await (0, cache_1.clearSystemCache)();
|
|
158
158
|
}
|
|
159
159
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
160
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
160
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
161
161
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
162
162
|
nestedActionEvent.context.schema = updatedSchema;
|
|
163
163
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -198,7 +198,7 @@ class CollectionsService {
|
|
|
198
198
|
await (0, cache_1.clearSystemCache)();
|
|
199
199
|
}
|
|
200
200
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
201
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
201
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
202
202
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
203
203
|
nestedActionEvent.context.schema = updatedSchema;
|
|
204
204
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -343,7 +343,7 @@ class CollectionsService {
|
|
|
343
343
|
await (0, cache_1.clearSystemCache)();
|
|
344
344
|
}
|
|
345
345
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
346
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
346
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
347
347
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
348
348
|
nestedActionEvent.context.schema = updatedSchema;
|
|
349
349
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -391,7 +391,7 @@ class CollectionsService {
|
|
|
391
391
|
await (0, cache_1.clearSystemCache)();
|
|
392
392
|
}
|
|
393
393
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
394
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
394
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
395
395
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
396
396
|
nestedActionEvent.context.schema = updatedSchema;
|
|
397
397
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -433,7 +433,7 @@ class CollectionsService {
|
|
|
433
433
|
await (0, cache_1.clearSystemCache)();
|
|
434
434
|
}
|
|
435
435
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
436
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
436
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
437
437
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
438
438
|
nestedActionEvent.context.schema = updatedSchema;
|
|
439
439
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -538,7 +538,7 @@ class CollectionsService {
|
|
|
538
538
|
await (0, cache_1.clearSystemCache)();
|
|
539
539
|
}
|
|
540
540
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
541
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
541
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
542
542
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
543
543
|
nestedActionEvent.context.schema = updatedSchema;
|
|
544
544
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -579,7 +579,7 @@ class CollectionsService {
|
|
|
579
579
|
await (0, cache_1.clearSystemCache)();
|
|
580
580
|
}
|
|
581
581
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
582
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
582
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
583
583
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
584
584
|
nestedActionEvent.context.schema = updatedSchema;
|
|
585
585
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -24,8 +24,9 @@ export declare class FieldsService {
|
|
|
24
24
|
createField(collection: string, field: Partial<Field> & {
|
|
25
25
|
field: string;
|
|
26
26
|
type: Type | null;
|
|
27
|
-
}, table?: Knex.CreateTableBuilder
|
|
28
|
-
|
|
27
|
+
}, table?: Knex.CreateTableBuilder, // allows collection creation to
|
|
28
|
+
opts?: MutationOptions): Promise<void>;
|
|
29
|
+
updateField(collection: string, field: RawField, opts?: MutationOptions): Promise<string>;
|
|
29
30
|
deleteField(collection: string, field: string, opts?: MutationOptions): Promise<void>;
|
|
30
31
|
addColumnToTable(table: Knex.CreateTableBuilder, field: RawField | Field, alter?: Column | null): void;
|
|
31
32
|
}
|
package/dist/services/fields.js
CHANGED
|
@@ -218,8 +218,8 @@ class FieldsService {
|
|
|
218
218
|
};
|
|
219
219
|
return data;
|
|
220
220
|
}
|
|
221
|
-
async createField(collection, field, table // allows collection creation to
|
|
222
|
-
) {
|
|
221
|
+
async createField(collection, field, table, // allows collection creation to
|
|
222
|
+
opts) {
|
|
223
223
|
if (this.accountability && this.accountability.admin !== true) {
|
|
224
224
|
throw new exceptions_1.ForbiddenException();
|
|
225
225
|
}
|
|
@@ -267,7 +267,7 @@ class FieldsService {
|
|
|
267
267
|
field: hookAdjustedField.field,
|
|
268
268
|
}, { emitEvents: false });
|
|
269
269
|
}
|
|
270
|
-
|
|
270
|
+
const actionEvent = {
|
|
271
271
|
event: 'fields.create',
|
|
272
272
|
meta: {
|
|
273
273
|
payload: hookAdjustedField,
|
|
@@ -279,25 +279,35 @@ class FieldsService {
|
|
|
279
279
|
schema: this.schema,
|
|
280
280
|
accountability: this.accountability,
|
|
281
281
|
},
|
|
282
|
-
}
|
|
282
|
+
};
|
|
283
|
+
if (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) {
|
|
284
|
+
opts.bypassEmitAction(actionEvent);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
nestedActionEvents.push(actionEvent);
|
|
288
|
+
}
|
|
283
289
|
});
|
|
284
290
|
}
|
|
285
291
|
finally {
|
|
286
292
|
if (runPostColumnChange) {
|
|
287
293
|
await this.helpers.schema.postColumnChange();
|
|
288
294
|
}
|
|
289
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
|
|
295
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
290
296
|
await this.cache.clear();
|
|
291
297
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
298
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
299
|
+
await (0, cache_1.clearSystemCache)();
|
|
300
|
+
}
|
|
301
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
302
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
303
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
304
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
305
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
306
|
+
}
|
|
297
307
|
}
|
|
298
308
|
}
|
|
299
309
|
}
|
|
300
|
-
async updateField(collection, field) {
|
|
310
|
+
async updateField(collection, field, opts) {
|
|
301
311
|
var _a, _b, _c;
|
|
302
312
|
if (this.accountability && this.accountability.admin !== true) {
|
|
303
313
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -353,7 +363,7 @@ class FieldsService {
|
|
|
353
363
|
}, { emitEvents: false });
|
|
354
364
|
}
|
|
355
365
|
}
|
|
356
|
-
|
|
366
|
+
const actionEvent = {
|
|
357
367
|
event: 'fields.update',
|
|
358
368
|
meta: {
|
|
359
369
|
payload: hookAdjustedField,
|
|
@@ -365,21 +375,31 @@ class FieldsService {
|
|
|
365
375
|
schema: this.schema,
|
|
366
376
|
accountability: this.accountability,
|
|
367
377
|
},
|
|
368
|
-
}
|
|
378
|
+
};
|
|
379
|
+
if (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) {
|
|
380
|
+
opts.bypassEmitAction(actionEvent);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
nestedActionEvents.push(actionEvent);
|
|
384
|
+
}
|
|
369
385
|
return field.field;
|
|
370
386
|
}
|
|
371
387
|
finally {
|
|
372
388
|
if (runPostColumnChange) {
|
|
373
389
|
await this.helpers.schema.postColumnChange();
|
|
374
390
|
}
|
|
375
|
-
if (this.cache && env_1.default.CACHE_AUTO_PURGE) {
|
|
391
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
376
392
|
await this.cache.clear();
|
|
377
393
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
394
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
395
|
+
await (0, cache_1.clearSystemCache)();
|
|
396
|
+
}
|
|
397
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
398
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
399
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
400
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
401
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
402
|
+
}
|
|
383
403
|
}
|
|
384
404
|
}
|
|
385
405
|
}
|
|
@@ -507,7 +527,7 @@ class FieldsService {
|
|
|
507
527
|
await (0, cache_1.clearSystemCache)();
|
|
508
528
|
}
|
|
509
529
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
510
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
530
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
511
531
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
512
532
|
nestedActionEvent.context.schema = updatedSchema;
|
|
513
533
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
@@ -21,13 +21,13 @@ export declare class RelationsService {
|
|
|
21
21
|
/**
|
|
22
22
|
* Create a new relationship / foreign key constraint
|
|
23
23
|
*/
|
|
24
|
-
createOne(relation: Partial<Relation
|
|
24
|
+
createOne(relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Update an existing foreign key constraint
|
|
27
27
|
*
|
|
28
28
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
29
29
|
*/
|
|
30
|
-
updateOne(collection: string, field: string, relation: Partial<Relation
|
|
30
|
+
updateOne(collection: string, field: string, relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Delete an existing relationship
|
|
33
33
|
*/
|
|
@@ -127,7 +127,7 @@ class RelationsService {
|
|
|
127
127
|
/**
|
|
128
128
|
* Create a new relationship / foreign key constraint
|
|
129
129
|
*/
|
|
130
|
-
async createOne(relation) {
|
|
130
|
+
async createOne(relation, opts) {
|
|
131
131
|
if (this.accountability && this.accountability.admin !== true) {
|
|
132
132
|
throw new exceptions_1.ForbiddenException();
|
|
133
133
|
}
|
|
@@ -185,7 +185,7 @@ class RelationsService {
|
|
|
185
185
|
// happens in `filterForbidden` down below
|
|
186
186
|
});
|
|
187
187
|
await relationsItemService.createOne(metaRow, {
|
|
188
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
188
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
189
189
|
});
|
|
190
190
|
});
|
|
191
191
|
}
|
|
@@ -193,11 +193,15 @@ class RelationsService {
|
|
|
193
193
|
if (runPostColumnChange) {
|
|
194
194
|
await this.helpers.schema.postColumnChange();
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
196
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
197
|
+
await (0, cache_1.clearSystemCache)();
|
|
198
|
+
}
|
|
199
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
200
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
201
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
202
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
203
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
204
|
+
}
|
|
201
205
|
}
|
|
202
206
|
}
|
|
203
207
|
}
|
|
@@ -206,7 +210,7 @@ class RelationsService {
|
|
|
206
210
|
*
|
|
207
211
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
208
212
|
*/
|
|
209
|
-
async updateOne(collection, field, relation) {
|
|
213
|
+
async updateOne(collection, field, relation, opts) {
|
|
210
214
|
if (this.accountability && this.accountability.admin !== true) {
|
|
211
215
|
throw new exceptions_1.ForbiddenException();
|
|
212
216
|
}
|
|
@@ -254,7 +258,7 @@ class RelationsService {
|
|
|
254
258
|
if (relation.meta) {
|
|
255
259
|
if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.meta) {
|
|
256
260
|
await relationsItemService.updateOne(existingRelation.meta.id, relation.meta, {
|
|
257
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
261
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
258
262
|
});
|
|
259
263
|
}
|
|
260
264
|
else {
|
|
@@ -264,7 +268,7 @@ class RelationsService {
|
|
|
264
268
|
many_field: relation.field,
|
|
265
269
|
one_collection: existingRelation.related_collection || null,
|
|
266
270
|
}, {
|
|
267
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
271
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
268
272
|
});
|
|
269
273
|
}
|
|
270
274
|
}
|
|
@@ -274,11 +278,15 @@ class RelationsService {
|
|
|
274
278
|
if (runPostColumnChange) {
|
|
275
279
|
await this.helpers.schema.postColumnChange();
|
|
276
280
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
281
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
282
|
+
await (0, cache_1.clearSystemCache)();
|
|
283
|
+
}
|
|
284
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
285
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
286
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
287
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
288
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
289
|
+
}
|
|
282
290
|
}
|
|
283
291
|
}
|
|
284
292
|
}
|
|
@@ -343,7 +351,7 @@ class RelationsService {
|
|
|
343
351
|
await (0, cache_1.clearSystemCache)();
|
|
344
352
|
}
|
|
345
353
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
346
|
-
const updatedSchema = await (0, get_schema_1.getSchema)(
|
|
354
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
347
355
|
for (const nestedActionEvent of nestedActionEvents) {
|
|
348
356
|
nestedActionEvent.context.schema = updatedSchema;
|
|
349
357
|
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
package/dist/services/users.js
CHANGED
|
@@ -202,11 +202,17 @@ class UsersService extends items_1.ItemsService {
|
|
|
202
202
|
if (data.tfa_secret !== undefined) {
|
|
203
203
|
throw new exceptions_2.InvalidPayloadException(`You can't change the "tfa_secret" value manually.`);
|
|
204
204
|
}
|
|
205
|
-
if (data.provider !== undefined
|
|
206
|
-
|
|
205
|
+
if (data.provider !== undefined) {
|
|
206
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
207
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "provider" value manually.`);
|
|
208
|
+
}
|
|
209
|
+
data.auth_data = null;
|
|
207
210
|
}
|
|
208
|
-
if (data.external_identifier !== undefined
|
|
209
|
-
|
|
211
|
+
if (data.external_identifier !== undefined) {
|
|
212
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
213
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "external_identifier" value manually.`);
|
|
214
|
+
}
|
|
215
|
+
data.auth_data = null;
|
|
210
216
|
}
|
|
211
217
|
return await super.updateMany(keys, data, opts);
|
|
212
218
|
}
|
|
@@ -12,13 +12,19 @@ const get_schema_1 = require("./get-schema");
|
|
|
12
12
|
const get_snapshot_1 = require("./get-snapshot");
|
|
13
13
|
const get_snapshot_diff_1 = require("./get-snapshot-diff");
|
|
14
14
|
const cache_1 = require("../cache");
|
|
15
|
+
const emitter_1 = __importDefault(require("../emitter"));
|
|
15
16
|
async function applySnapshot(snapshot, options) {
|
|
16
17
|
var _a, _b, _c, _d;
|
|
17
18
|
const database = (_a = options === null || options === void 0 ? void 0 : options.database) !== null && _a !== void 0 ? _a : (0, database_1.default)();
|
|
18
|
-
const schema = (_b = options === null || options === void 0 ? void 0 : options.schema) !== null && _b !== void 0 ? _b : (await (0, get_schema_1.getSchema)({ database }));
|
|
19
|
+
const schema = (_b = options === null || options === void 0 ? void 0 : options.schema) !== null && _b !== void 0 ? _b : (await (0, get_schema_1.getSchema)({ database, bypassCache: true }));
|
|
19
20
|
const { systemCache } = (0, cache_1.getCache)();
|
|
20
21
|
const current = (_c = options === null || options === void 0 ? void 0 : options.current) !== null && _c !== void 0 ? _c : (await (0, get_snapshot_1.getSnapshot)({ database, schema }));
|
|
21
22
|
const snapshotDiff = (_d = options === null || options === void 0 ? void 0 : options.diff) !== null && _d !== void 0 ? _d : (0, get_snapshot_diff_1.getSnapshotDiff)(current, snapshot);
|
|
23
|
+
const nestedActionEvents = [];
|
|
24
|
+
const mutationOptions = {
|
|
25
|
+
autoPurgeSystemCache: false,
|
|
26
|
+
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
27
|
+
};
|
|
22
28
|
await database.transaction(async (trx) => {
|
|
23
29
|
const collectionsService = new services_1.CollectionsService({ knex: trx, schema });
|
|
24
30
|
const getNestedCollectionsToCreate = (currentLevelCollection) => snapshotDiff.collections.filter(({ diff }) => { var _a, _b; return ((_b = (_a = diff[0].rhs) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.group) === currentLevelCollection; });
|
|
@@ -49,7 +55,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
49
55
|
await collectionsService.createOne({
|
|
50
56
|
...diff[0].rhs,
|
|
51
57
|
fields,
|
|
52
|
-
});
|
|
58
|
+
}, mutationOptions);
|
|
53
59
|
}
|
|
54
60
|
catch (err) {
|
|
55
61
|
logger_1.default.error(`Failed to create collection "${collection}"`);
|
|
@@ -69,7 +75,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
69
75
|
const relationsService = new services_1.RelationsService({ knex: trx, schema });
|
|
70
76
|
for (const relation of relations) {
|
|
71
77
|
try {
|
|
72
|
-
await relationsService.deleteOne(relation.collection, relation.field);
|
|
78
|
+
await relationsService.deleteOne(relation.collection, relation.field, mutationOptions);
|
|
73
79
|
}
|
|
74
80
|
catch (err) {
|
|
75
81
|
logger_1.default.error(`Failed to delete collection "${collection}" due to relation "${relation.collection}.${relation.field}"`);
|
|
@@ -81,7 +87,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
81
87
|
}
|
|
82
88
|
await deleteCollections(getNestedCollectionsToDelete(collection));
|
|
83
89
|
try {
|
|
84
|
-
await collectionsService.deleteOne(collection);
|
|
90
|
+
await collectionsService.deleteOne(collection, mutationOptions);
|
|
85
91
|
}
|
|
86
92
|
catch (err) {
|
|
87
93
|
logger_1.default.error(`Failed to delete collection "${collection}"`);
|
|
@@ -130,7 +136,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
130
136
|
});
|
|
131
137
|
if (newValues) {
|
|
132
138
|
try {
|
|
133
|
-
await collectionsService.updateOne(collection, newValues);
|
|
139
|
+
await collectionsService.updateOne(collection, newValues, mutationOptions);
|
|
134
140
|
}
|
|
135
141
|
catch (err) {
|
|
136
142
|
logger_1.default.error(`Failed to update collection "${collection}"`);
|
|
@@ -139,11 +145,14 @@ async function applySnapshot(snapshot, options) {
|
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
|
-
const fieldsService = new services_1.FieldsService({
|
|
148
|
+
const fieldsService = new services_1.FieldsService({
|
|
149
|
+
knex: trx,
|
|
150
|
+
schema: await (0, get_schema_1.getSchema)({ database: trx, bypassCache: true }),
|
|
151
|
+
});
|
|
143
152
|
for (const { collection, field, diff } of snapshotDiff.fields) {
|
|
144
153
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N' && !isNestedMetaUpdate(diff === null || diff === void 0 ? void 0 : diff[0])) {
|
|
145
154
|
try {
|
|
146
|
-
await fieldsService.createField(collection, diff[0].rhs);
|
|
155
|
+
await fieldsService.createField(collection, diff[0].rhs, undefined, mutationOptions);
|
|
147
156
|
}
|
|
148
157
|
catch (err) {
|
|
149
158
|
logger_1.default.error(`Failed to create field "${collection}.${field}"`);
|
|
@@ -158,7 +167,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
158
167
|
try {
|
|
159
168
|
await fieldsService.updateField(collection, {
|
|
160
169
|
...newValues,
|
|
161
|
-
});
|
|
170
|
+
}, mutationOptions);
|
|
162
171
|
}
|
|
163
172
|
catch (err) {
|
|
164
173
|
logger_1.default.error(`Failed to update field "${collection}.${field}"`);
|
|
@@ -168,7 +177,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
168
177
|
}
|
|
169
178
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D' && !isNestedMetaUpdate(diff === null || diff === void 0 ? void 0 : diff[0])) {
|
|
170
179
|
try {
|
|
171
|
-
await fieldsService.deleteField(collection, field);
|
|
180
|
+
await fieldsService.deleteField(collection, field, mutationOptions);
|
|
172
181
|
}
|
|
173
182
|
catch (err) {
|
|
174
183
|
logger_1.default.error(`Failed to delete field "${collection}.${field}"`);
|
|
@@ -179,7 +188,10 @@ async function applySnapshot(snapshot, options) {
|
|
|
179
188
|
snapshotDiff.relations = snapshotDiff.relations.filter((relation) => (relation.collection === collection && relation.field === field) === false);
|
|
180
189
|
}
|
|
181
190
|
}
|
|
182
|
-
const relationsService = new services_1.RelationsService({
|
|
191
|
+
const relationsService = new services_1.RelationsService({
|
|
192
|
+
knex: trx,
|
|
193
|
+
schema: await (0, get_schema_1.getSchema)({ database: trx, bypassCache: true }),
|
|
194
|
+
});
|
|
183
195
|
for (const { collection, field, diff } of snapshotDiff.relations) {
|
|
184
196
|
const structure = {};
|
|
185
197
|
for (const diffEdit of diff) {
|
|
@@ -187,7 +199,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
187
199
|
}
|
|
188
200
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
189
201
|
try {
|
|
190
|
-
await relationsService.createOne(diff[0].rhs);
|
|
202
|
+
await relationsService.createOne(diff[0].rhs, mutationOptions);
|
|
191
203
|
}
|
|
192
204
|
catch (err) {
|
|
193
205
|
logger_1.default.error(`Failed to create relation "${collection}.${field}"`);
|
|
@@ -200,7 +212,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
200
212
|
});
|
|
201
213
|
if (newValues) {
|
|
202
214
|
try {
|
|
203
|
-
await relationsService.updateOne(collection, field, newValues);
|
|
215
|
+
await relationsService.updateOne(collection, field, newValues, mutationOptions);
|
|
204
216
|
}
|
|
205
217
|
catch (err) {
|
|
206
218
|
logger_1.default.error(`Failed to update relation "${collection}.${field}"`);
|
|
@@ -210,7 +222,7 @@ async function applySnapshot(snapshot, options) {
|
|
|
210
222
|
}
|
|
211
223
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
212
224
|
try {
|
|
213
|
-
await relationsService.deleteOne(collection, field);
|
|
225
|
+
await relationsService.deleteOne(collection, field, mutationOptions);
|
|
214
226
|
}
|
|
215
227
|
catch (err) {
|
|
216
228
|
logger_1.default.error(`Failed to delete relation "${collection}.${field}"`);
|
|
@@ -220,6 +232,13 @@ async function applySnapshot(snapshot, options) {
|
|
|
220
232
|
}
|
|
221
233
|
});
|
|
222
234
|
await (systemCache === null || systemCache === void 0 ? void 0 : systemCache.clear());
|
|
235
|
+
if (nestedActionEvents.length > 0) {
|
|
236
|
+
const updatedSchema = await (0, get_schema_1.getSchema)({ database, bypassCache: true });
|
|
237
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
238
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
239
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
223
242
|
}
|
|
224
243
|
exports.applySnapshot = applySnapshot;
|
|
225
244
|
function isNestedMetaUpdate(diff) {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SchemaOverview } from '@directus/shared/types';
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
3
|
export declare function getSchema(options?: {
|
|
4
|
-
accountability?: Accountability;
|
|
5
4
|
database?: Knex;
|
|
5
|
+
/**
|
|
6
|
+
* To bypass any cached schema if bypassCache is enabled.
|
|
7
|
+
* Used to ensure schema snapshot/apply is not using outdated schema
|
|
8
|
+
*/
|
|
9
|
+
bypassCache?: boolean;
|
|
6
10
|
}): Promise<SchemaOverview>;
|
package/dist/utils/get-schema.js
CHANGED
|
@@ -21,7 +21,7 @@ async function getSchema(options) {
|
|
|
21
21
|
const database = (options === null || options === void 0 ? void 0 : options.database) || (0, database_1.default)();
|
|
22
22
|
const schemaInspector = (0, schema_1.default)(database);
|
|
23
23
|
let result;
|
|
24
|
-
if (env_1.default.CACHE_SCHEMA !== false) {
|
|
24
|
+
if (!(options === null || options === void 0 ? void 0 : options.bypassCache) && env_1.default.CACHE_SCHEMA !== false) {
|
|
25
25
|
let cachedSchema;
|
|
26
26
|
try {
|
|
27
27
|
cachedSchema = (await (0, cache_1.getSystemCache)('schema'));
|
|
@@ -12,7 +12,7 @@ const lodash_1 = require("lodash");
|
|
|
12
12
|
async function getSnapshot(options) {
|
|
13
13
|
var _a, _b;
|
|
14
14
|
const database = (_a = options === null || options === void 0 ? void 0 : options.database) !== null && _a !== void 0 ? _a : (0, database_1.default)();
|
|
15
|
-
const schema = (_b = options === null || options === void 0 ? void 0 : options.schema) !== null && _b !== void 0 ? _b : (await (0, get_schema_1.getSchema)({ database }));
|
|
15
|
+
const schema = (_b = options === null || options === void 0 ? void 0 : options.schema) !== null && _b !== void 0 ? _b : (await (0, get_schema_1.getSchema)({ database, bypassCache: true }));
|
|
16
16
|
const collectionsService = new services_1.CollectionsService({ knex: database, schema });
|
|
17
17
|
const fieldsService = new services_1.FieldsService({ knex: database, schema });
|
|
18
18
|
const relationsService = new services_1.RelationsService({ knex: database, schema });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.21.
|
|
3
|
+
"version": "9.21.2",
|
|
4
4
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"directus",
|
|
@@ -66,16 +66,7 @@
|
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@authenio/samlify-node-xmllint": "2.0.0",
|
|
68
68
|
"@aws-sdk/client-ses": "3.211.0",
|
|
69
|
-
"@directus/app": "9.21.0",
|
|
70
|
-
"@directus/drive": "9.21.0",
|
|
71
|
-
"@directus/drive-azure": "9.21.0",
|
|
72
|
-
"@directus/drive-gcs": "9.21.0",
|
|
73
|
-
"@directus/drive-s3": "9.21.0",
|
|
74
|
-
"@directus/extensions-sdk": "9.21.0",
|
|
75
69
|
"@directus/format-title": "9.15.0",
|
|
76
|
-
"@directus/schema": "9.21.0",
|
|
77
|
-
"@directus/shared": "9.21.0",
|
|
78
|
-
"@directus/specs": "9.21.0",
|
|
79
70
|
"@godaddy/terminus": "4.11.2",
|
|
80
71
|
"@rollup/plugin-alias": "4.0.2",
|
|
81
72
|
"@rollup/plugin-virtual": "3.0.1",
|
|
@@ -94,7 +85,6 @@
|
|
|
94
85
|
"csv-parser": "3.0.0",
|
|
95
86
|
"date-fns": "2.29.3",
|
|
96
87
|
"deep-diff": "1.0.2",
|
|
97
|
-
"deep-map": "2.0.0",
|
|
98
88
|
"destroy": "1.2.0",
|
|
99
89
|
"dotenv": "16.0.3",
|
|
100
90
|
"encodeurl": "1.0.2",
|
|
@@ -140,7 +130,6 @@
|
|
|
140
130
|
"pino-http-print": "3.1.0",
|
|
141
131
|
"qs": "6.11.0",
|
|
142
132
|
"rate-limiter-flexible": "2.4.1",
|
|
143
|
-
"resolve-cwd": "3.0.0",
|
|
144
133
|
"rollup": "3.3.0",
|
|
145
134
|
"samlify": "2.8.7",
|
|
146
135
|
"sanitize-html": "2.7.3",
|
|
@@ -153,10 +142,18 @@
|
|
|
153
142
|
"uuid": "9.0.0",
|
|
154
143
|
"uuid-validate": "0.0.3",
|
|
155
144
|
"vm2": "3.9.11",
|
|
156
|
-
"wellknown": "0.5.0"
|
|
145
|
+
"wellknown": "0.5.0",
|
|
146
|
+
"@directus/app": "9.21.2",
|
|
147
|
+
"@directus/drive": "9.21.2",
|
|
148
|
+
"@directus/drive-azure": "9.21.2",
|
|
149
|
+
"@directus/drive-gcs": "9.21.2",
|
|
150
|
+
"@directus/drive-s3": "9.21.2",
|
|
151
|
+
"@directus/extensions-sdk": "9.21.2",
|
|
152
|
+
"@directus/schema": "9.21.2",
|
|
153
|
+
"@directus/shared": "9.21.2",
|
|
154
|
+
"@directus/specs": "9.21.2"
|
|
157
155
|
},
|
|
158
156
|
"devDependencies": {
|
|
159
|
-
"@otplib/preset-default": "12.0.1",
|
|
160
157
|
"@types/async": "3.2.15",
|
|
161
158
|
"@types/busboy": "1.5.0",
|
|
162
159
|
"@types/bytes": "3.1.1",
|
|
@@ -166,9 +163,7 @@
|
|
|
166
163
|
"@types/destroy": "1.0.0",
|
|
167
164
|
"@types/encodeurl": "1.0.0",
|
|
168
165
|
"@types/express": "4.17.14",
|
|
169
|
-
"@types/express-pino-logger": "4.0.3",
|
|
170
166
|
"@types/express-serve-static-core": "4.17.31",
|
|
171
|
-
"@types/express-session": "1.17.5",
|
|
172
167
|
"@types/fast-redact": "3.0.2",
|
|
173
168
|
"@types/flat": "5.0.2",
|
|
174
169
|
"@types/fs-extra": "9.0.13",
|
|
@@ -192,7 +187,6 @@
|
|
|
192
187
|
"@types/sanitize-html": "2.6.2",
|
|
193
188
|
"@types/sharp": "0.31.0",
|
|
194
189
|
"@types/stream-json": "1.7.2",
|
|
195
|
-
"@types/supertest": "2.0.12",
|
|
196
190
|
"@types/uuid": "8.3.4",
|
|
197
191
|
"@types/uuid-validate": "0.0.1",
|
|
198
192
|
"@types/wellknown": "0.5.4",
|
|
@@ -200,8 +194,6 @@
|
|
|
200
194
|
"copyfiles": "2.4.1",
|
|
201
195
|
"form-data": "4.0.0",
|
|
202
196
|
"knex-mock-client": "1.8.4",
|
|
203
|
-
"rimraf": "3.0.2",
|
|
204
|
-
"supertest": "6.3.1",
|
|
205
197
|
"ts-node": "10.9.1",
|
|
206
198
|
"ts-node-dev": "2.0.0",
|
|
207
199
|
"typescript": "4.9.3",
|
|
@@ -222,9 +214,7 @@
|
|
|
222
214
|
"node": ">=12.20.0"
|
|
223
215
|
},
|
|
224
216
|
"scripts": {
|
|
225
|
-
"prebuild": "pnpm cleanup",
|
|
226
217
|
"build": "tsc --build && copyfiles \"src/**/*.{yaml,liquid}\" -u 1 dist",
|
|
227
|
-
"cleanup": "rimraf dist",
|
|
228
218
|
"cli": "NODE_ENV=development SERVE_APP=false ts-node --script-mode --transpile-only src/cli/run.ts",
|
|
229
219
|
"dev": "NODE_ENV=development SERVE_APP=false ts-node-dev --files --transpile-only --respawn --watch \".env\" --inspect=0 --exit-child -- src/start.ts",
|
|
230
220
|
"start": "npx directus start",
|