directus 9.1.2 → 9.2.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/dist/auth.js +5 -3
- package/dist/cli/commands/database/install.js +2 -4
- package/dist/cli/commands/schema/apply.js +26 -10
- package/dist/controllers/assets.js +0 -27
- package/dist/controllers/auth.js +7 -2
- package/dist/controllers/extensions.js +1 -1
- package/dist/database/{functions/types.d.ts → helpers/date/dialects/mssql.d.ts} +2 -1
- package/dist/database/{functions → helpers/date}/dialects/mssql.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/mysql.d.ts +2 -4
- package/dist/database/{functions → helpers/date}/dialects/mysql.js +4 -6
- package/dist/database/{functions/dialects/mssql.d.ts → helpers/date/dialects/oracle.d.ts} +2 -4
- package/dist/database/{functions → helpers/date}/dialects/oracle.js +4 -6
- package/dist/database/helpers/date/dialects/postgres.d.ts +12 -0
- package/dist/database/{functions → helpers/date}/dialects/postgres.js +4 -6
- package/dist/database/{functions → helpers/date}/dialects/sqlite.d.ts +3 -4
- package/dist/database/helpers/date/dialects/sqlite.js +35 -0
- package/dist/database/helpers/date/index.d.ts +6 -0
- package/dist/database/helpers/date/index.js +15 -0
- package/dist/database/helpers/date/types.d.ts +13 -0
- package/dist/database/helpers/date/types.js +10 -0
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +14 -0
- package/dist/database/helpers/geometry/dialects/mssql.js +36 -0
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/mysql.js +16 -0
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +15 -0
- package/dist/database/helpers/geometry/dialects/oracle.js +39 -0
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +10 -0
- package/dist/database/helpers/geometry/dialects/postgres.js +23 -0
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +7 -0
- package/dist/database/helpers/geometry/dialects/redshift.js +16 -0
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +6 -0
- package/dist/database/helpers/geometry/dialects/sqlite.js +14 -0
- package/dist/database/helpers/geometry/index.d.ts +6 -0
- package/dist/database/helpers/geometry/index.js +15 -0
- package/dist/database/helpers/{geometry.d.ts → geometry/types.d.ts} +3 -7
- package/dist/database/helpers/geometry/types.js +54 -0
- package/dist/database/helpers/index.d.ts +8 -0
- package/dist/database/helpers/index.js +33 -0
- package/dist/database/helpers/types.d.ts +5 -0
- package/dist/database/helpers/types.js +9 -0
- package/dist/database/index.js +6 -6
- package/dist/database/run-ast.js +5 -5
- package/dist/database/seeds/run.js +3 -3
- package/dist/database/system-data/fields/notifications.yaml +1 -0
- package/dist/env.js +1 -0
- package/dist/extensions.js +17 -2
- package/dist/middleware/sanitize-query.js +1 -1
- package/dist/services/activity.js +7 -2
- package/dist/services/assets.js +14 -0
- package/dist/services/fields.d.ts +2 -0
- package/dist/services/fields.js +57 -26
- package/dist/services/files.d.ts +1 -1
- package/dist/services/files.js +13 -11
- package/dist/services/graphql.js +3 -0
- package/dist/services/items.js +18 -29
- package/dist/services/payload.d.ts +2 -0
- package/dist/services/payload.js +3 -3
- package/dist/utils/apply-query.js +9 -11
- package/dist/utils/apply-snapshot.js +27 -28
- package/dist/utils/get-column.js +2 -2
- package/dist/utils/get-default-index-name.js +2 -2
- package/dist/utils/get-local-type.js +1 -12
- package/dist/utils/merge-permissions.js +2 -2
- package/dist/utils/sanitize-query.js +1 -12
- package/dist/utils/validate-query.js +1 -1
- package/dist/webhooks.js +16 -24
- package/package.json +13 -13
- package/dist/database/functions/dialects/oracle.d.ts +0 -14
- package/dist/database/functions/dialects/postgres.d.ts +0 -14
- package/dist/database/functions/dialects/sqlite.js +0 -33
- package/dist/database/functions/index.d.ts +0 -3
- package/dist/database/functions/index.js +0 -26
- package/dist/database/functions/types.js +0 -2
- package/dist/database/helpers/date.d.ts +0 -8
- package/dist/database/helpers/date.js +0 -44
- package/dist/database/helpers/geometry.js +0 -189
- package/dist/utils/get-simple-hash.d.ts +0 -5
- package/dist/utils/get-simple-hash.js +0 -15
package/dist/services/items.js
CHANGED
|
@@ -213,8 +213,16 @@ class ItemsService {
|
|
|
213
213
|
if (records === null) {
|
|
214
214
|
throw new exceptions_1.ForbiddenException();
|
|
215
215
|
}
|
|
216
|
+
const filteredRecords = await emitter_1.default.emitFilter(`${this.eventScope}.read`, records, {
|
|
217
|
+
query,
|
|
218
|
+
collection: this.collection,
|
|
219
|
+
}, {
|
|
220
|
+
database: this.knex,
|
|
221
|
+
schema: this.schema,
|
|
222
|
+
accountability: this.accountability,
|
|
223
|
+
});
|
|
216
224
|
emitter_1.default.emitAction(`${this.eventScope}.read`, {
|
|
217
|
-
payload:
|
|
225
|
+
payload: filteredRecords,
|
|
218
226
|
query,
|
|
219
227
|
collection: this.collection,
|
|
220
228
|
}, {
|
|
@@ -222,23 +230,15 @@ class ItemsService {
|
|
|
222
230
|
schema: this.schema,
|
|
223
231
|
accountability: this.accountability,
|
|
224
232
|
});
|
|
225
|
-
return
|
|
233
|
+
return filteredRecords;
|
|
226
234
|
}
|
|
227
235
|
/**
|
|
228
236
|
* Get single item by primary key
|
|
229
237
|
*/
|
|
230
|
-
async readOne(key, query, opts) {
|
|
231
|
-
query = query !== null && query !== void 0 ? query : {};
|
|
238
|
+
async readOne(key, query = {}, opts) {
|
|
232
239
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
filter: {
|
|
236
|
-
...(query.filter || {}),
|
|
237
|
-
[primaryKeyField]: {
|
|
238
|
-
_eq: key,
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
};
|
|
240
|
+
const filterWithKey = (0, lodash_1.assign)({}, query.filter, { [primaryKeyField]: { _eq: key } });
|
|
241
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
242
242
|
const results = await this.readByQuery(queryWithKey, opts);
|
|
243
243
|
if (results.length === 0) {
|
|
244
244
|
throw new exceptions_1.ForbiddenException();
|
|
@@ -248,23 +248,12 @@ class ItemsService {
|
|
|
248
248
|
/**
|
|
249
249
|
* Get multiple items by primary keys
|
|
250
250
|
*/
|
|
251
|
-
async readMany(keys, query, opts) {
|
|
252
|
-
|
|
251
|
+
async readMany(keys, query = {}, opts) {
|
|
252
|
+
var _a;
|
|
253
253
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
_and: [
|
|
258
|
-
query.filter || {},
|
|
259
|
-
{
|
|
260
|
-
[primaryKeyField]: {
|
|
261
|
-
_in: keys,
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
],
|
|
265
|
-
},
|
|
266
|
-
};
|
|
267
|
-
const results = await this.readByQuery(queryWithKeys, opts);
|
|
254
|
+
const filterWithKey = { _and: [{ [primaryKeyField]: { _in: keys } }, (_a = query.filter) !== null && _a !== void 0 ? _a : {}] };
|
|
255
|
+
const queryWithKey = (0, lodash_1.assign)({}, query, { filter: filterWithKey });
|
|
256
|
+
const results = await this.readByQuery(queryWithKey, opts);
|
|
268
257
|
return results;
|
|
269
258
|
}
|
|
270
259
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Knex } from 'knex';
|
|
2
2
|
import { AbstractServiceOptions, Item, PrimaryKey, SchemaOverview } from '../types';
|
|
3
3
|
import { Accountability } from '@directus/shared/types';
|
|
4
|
+
import { Helpers } from '../database/helpers';
|
|
4
5
|
declare type Action = 'create' | 'read' | 'update';
|
|
5
6
|
declare type Transformers = {
|
|
6
7
|
[type: string]: (context: {
|
|
@@ -18,6 +19,7 @@ declare type Transformers = {
|
|
|
18
19
|
export declare class PayloadService {
|
|
19
20
|
accountability: Accountability | null;
|
|
20
21
|
knex: Knex;
|
|
22
|
+
helpers: Helpers;
|
|
21
23
|
collection: string;
|
|
22
24
|
schema: SchemaOverview;
|
|
23
25
|
constructor(collection: string, options: AbstractServiceOptions);
|
package/dist/services/payload.js
CHANGED
|
@@ -13,7 +13,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
13
13
|
const utils_1 = require("@directus/shared/utils");
|
|
14
14
|
const items_1 = require("./items");
|
|
15
15
|
const flat_1 = require("flat");
|
|
16
|
-
const
|
|
16
|
+
const helpers_1 = require("../database/helpers");
|
|
17
17
|
const wellknown_1 = require("wellknown");
|
|
18
18
|
const generate_hash_1 = require("../utils/generate-hash");
|
|
19
19
|
/**
|
|
@@ -111,6 +111,7 @@ class PayloadService {
|
|
|
111
111
|
};
|
|
112
112
|
this.accountability = options.accountability || null;
|
|
113
113
|
this.knex = options.knex || (0, database_1.default)();
|
|
114
|
+
this.helpers = (0, helpers_1.getHelpers)(this.knex);
|
|
114
115
|
this.collection = collection;
|
|
115
116
|
this.schema = options.schema;
|
|
116
117
|
return this;
|
|
@@ -188,10 +189,9 @@ class PayloadService {
|
|
|
188
189
|
* to check if the value is a raw instance before stringifying it in the next step.
|
|
189
190
|
*/
|
|
190
191
|
processGeometries(payloads, action) {
|
|
191
|
-
const helper = (0, geometry_1.getGeometryHelper)();
|
|
192
192
|
const process = action == 'read'
|
|
193
193
|
? (value) => (typeof value === 'string' ? (0, wellknown_1.parse)(value) : value)
|
|
194
|
-
: (value) =>
|
|
194
|
+
: (value) => this.helpers.st.fromGeoJSON(typeof value == 'string' ? JSON.parse(value) : value);
|
|
195
195
|
const fieldsInCollection = Object.entries(this.schema.collections[this.collection].fields);
|
|
196
196
|
const geometryColumns = fieldsInCollection.filter(([_, field]) => field.type.startsWith('geometry'));
|
|
197
197
|
for (const [name] of geometryColumns) {
|
|
@@ -11,8 +11,7 @@ const exceptions_1 = require("../exceptions");
|
|
|
11
11
|
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
12
12
|
const get_column_1 = require("./get-column");
|
|
13
13
|
const get_relation_type_1 = require("./get-relation-type");
|
|
14
|
-
const
|
|
15
|
-
const date_1 = require("../database/helpers/date");
|
|
14
|
+
const helpers_1 = require("../database/helpers");
|
|
16
15
|
const generateAlias = (0, nanoid_1.customAlphabet)('abcdefghijklmnopqrstuvwxyz', 5);
|
|
17
16
|
/**
|
|
18
17
|
* Apply the Query to a given Knex query builder instance
|
|
@@ -45,7 +44,7 @@ function applyQuery(knex, collection, dbQuery, query, schema, subQuery = false)
|
|
|
45
44
|
applySearch(schema, dbQuery, query.search, collection);
|
|
46
45
|
}
|
|
47
46
|
if (query.group) {
|
|
48
|
-
dbQuery.groupBy(query.group.map(apply_function_to_column_name_1.applyFunctionToColumnName));
|
|
47
|
+
dbQuery.groupBy(`${collection}.${query.group.map(apply_function_to_column_name_1.applyFunctionToColumnName)}`);
|
|
49
48
|
}
|
|
50
49
|
if (query.aggregate) {
|
|
51
50
|
applyAggregate(dbQuery, query.aggregate, collection);
|
|
@@ -117,6 +116,7 @@ exports.default = applyQuery;
|
|
|
117
116
|
* ```
|
|
118
117
|
*/
|
|
119
118
|
function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery = false) {
|
|
119
|
+
const helpers = (0, helpers_1.getHelpers)(knex);
|
|
120
120
|
const relations = schema.relations;
|
|
121
121
|
const aliasMap = {};
|
|
122
122
|
addJoins(rootQuery, rootFilter, collection);
|
|
@@ -273,16 +273,15 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
273
273
|
query.where(key, '!=', '');
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
|
-
const dateHelper = (0, date_1.getDateHelper)();
|
|
277
276
|
const [collection, field] = key.split('.');
|
|
278
277
|
if (collection in schema.collections && field in schema.collections[collection].fields) {
|
|
279
278
|
const type = schema.collections[collection].fields[field].type;
|
|
280
279
|
if (['date', 'dateTime', 'time', 'timestamp'].includes(type)) {
|
|
281
280
|
if (Array.isArray(compareValue)) {
|
|
282
|
-
compareValue = compareValue.map((val) =>
|
|
281
|
+
compareValue = compareValue.map((val) => helpers.date.parse(val));
|
|
283
282
|
}
|
|
284
283
|
else {
|
|
285
|
-
compareValue =
|
|
284
|
+
compareValue = helpers.date.parse(compareValue);
|
|
286
285
|
}
|
|
287
286
|
}
|
|
288
287
|
}
|
|
@@ -361,18 +360,17 @@ function applyFilter(knex, schema, rootQuery, rootFilter, collection, subQuery =
|
|
|
361
360
|
value = value.split(',');
|
|
362
361
|
dbQuery[logical].whereNotBetween(selectionRaw, value);
|
|
363
362
|
}
|
|
364
|
-
const geometryHelper = (0, geometry_1.getGeometryHelper)();
|
|
365
363
|
if (operator == '_intersects') {
|
|
366
|
-
dbQuery[logical].whereRaw(
|
|
364
|
+
dbQuery[logical].whereRaw(helpers.st.intersects(key, compareValue));
|
|
367
365
|
}
|
|
368
366
|
if (operator == '_nintersects') {
|
|
369
|
-
dbQuery[logical].whereRaw(
|
|
367
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects(key, compareValue));
|
|
370
368
|
}
|
|
371
369
|
if (operator == '_intersects_bbox') {
|
|
372
|
-
dbQuery[logical].whereRaw(
|
|
370
|
+
dbQuery[logical].whereRaw(helpers.st.intersects_bbox(key, compareValue));
|
|
373
371
|
}
|
|
374
372
|
if (operator == '_nintersects_bbox') {
|
|
375
|
-
dbQuery[logical].whereRaw(
|
|
373
|
+
dbQuery[logical].whereRaw(helpers.st.nintersects_bbox(key, compareValue));
|
|
376
374
|
}
|
|
377
375
|
}
|
|
378
376
|
function getWhereColumn(path, collection) {
|
|
@@ -36,14 +36,13 @@ async function applySnapshot(snapshot, options) {
|
|
|
36
36
|
// edits
|
|
37
37
|
snapshotDiff.fields = snapshotDiff.fields.filter((fieldDiff) => fieldDiff.collection !== collection);
|
|
38
38
|
}
|
|
39
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
await collectionsService.updateOne(collection, updates);
|
|
39
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
40
|
+
const newValues = snapshot.collections.find((field) => {
|
|
41
|
+
return field.collection === collection;
|
|
42
|
+
});
|
|
43
|
+
if (newValues) {
|
|
44
|
+
await collectionsService.updateOne(collection, newValues);
|
|
45
|
+
}
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
const fieldsService = new services_1.FieldsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
@@ -51,18 +50,15 @@ async function applySnapshot(snapshot, options) {
|
|
|
51
50
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
52
51
|
await fieldsService.createField(collection, diff[0].rhs);
|
|
53
52
|
}
|
|
54
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
return acc;
|
|
58
|
-
(0, lodash_1.set)(acc, edit.path, edit.rhs);
|
|
59
|
-
return acc;
|
|
60
|
-
}, {});
|
|
61
|
-
await fieldsService.updateField(collection, {
|
|
62
|
-
field,
|
|
63
|
-
type: 'unknown',
|
|
64
|
-
...updates,
|
|
53
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
54
|
+
const newValues = snapshot.fields.find((snapshotField) => {
|
|
55
|
+
return snapshotField.collection === collection && snapshotField.field === field;
|
|
65
56
|
});
|
|
57
|
+
if (newValues) {
|
|
58
|
+
await fieldsService.updateField(collection, {
|
|
59
|
+
...newValues,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
66
62
|
}
|
|
67
63
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
68
64
|
await fieldsService.deleteField(collection, field);
|
|
@@ -72,18 +68,21 @@ async function applySnapshot(snapshot, options) {
|
|
|
72
68
|
}
|
|
73
69
|
}
|
|
74
70
|
const relationsService = new services_1.RelationsService({ knex: trx, schema: await (0, get_schema_1.getSchema)({ database: trx }) });
|
|
75
|
-
for (const { collection, field, diff
|
|
71
|
+
for (const { collection, field, diff } of snapshotDiff.relations) {
|
|
72
|
+
const structure = {};
|
|
73
|
+
for (const diffEdit of diff) {
|
|
74
|
+
(0, lodash_1.set)(structure, diffEdit.path, undefined);
|
|
75
|
+
}
|
|
76
76
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'N') {
|
|
77
77
|
await relationsService.createOne(diff[0].rhs);
|
|
78
78
|
}
|
|
79
|
-
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E') {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
await relationsService.updateOne(collection, field, updates);
|
|
79
|
+
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'E' || (diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'A') {
|
|
80
|
+
const newValues = snapshot.relations.find((relation) => {
|
|
81
|
+
return relation.collection === collection && relation.field === field;
|
|
82
|
+
});
|
|
83
|
+
if (newValues) {
|
|
84
|
+
await relationsService.updateOne(collection, field, newValues);
|
|
85
|
+
}
|
|
87
86
|
}
|
|
88
87
|
if ((diff === null || diff === void 0 ? void 0 : diff[0].kind) === 'D') {
|
|
89
88
|
await relationsService.deleteOne(collection, field);
|
package/dist/utils/get-column.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getColumn = void 0;
|
|
4
|
-
const
|
|
4
|
+
const helpers_1 = require("../database/helpers");
|
|
5
5
|
const constants_1 = require("@directus/shared/constants");
|
|
6
6
|
const apply_function_to_column_name_1 = require("./apply-function-to-column-name");
|
|
7
7
|
/**
|
|
@@ -15,7 +15,7 @@ const apply_function_to_column_name_1 = require("./apply-function-to-column-name
|
|
|
15
15
|
* @returns Knex raw instance
|
|
16
16
|
*/
|
|
17
17
|
function getColumn(knex, table, column, alias = (0, apply_function_to_column_name_1.applyFunctionToColumnName)(column)) {
|
|
18
|
-
const fn = (0,
|
|
18
|
+
const { date: fn } = (0, helpers_1.getHelpers)(knex);
|
|
19
19
|
if (column.includes('(') && column.includes(')')) {
|
|
20
20
|
const functionName = column.split('(')[0];
|
|
21
21
|
const columnName = column.match(constants_1.REGEX_BETWEEN_PARENS)[1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getDefaultIndexName = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_1 = require("@directus/shared/utils");
|
|
5
5
|
/**
|
|
6
6
|
* Generate an index name for a given collection + fields combination.
|
|
7
7
|
*
|
|
@@ -18,7 +18,7 @@ function getDefaultIndexName(type, collection, fields) {
|
|
|
18
18
|
const indexName = (table + '_' + fields.join('_') + '_' + type).toLowerCase();
|
|
19
19
|
if (indexName.length <= 60)
|
|
20
20
|
return indexName;
|
|
21
|
-
const suffix = `__${(0,
|
|
21
|
+
const suffix = `__${(0, utils_1.getSimpleHash)(indexName)}_${type}`;
|
|
22
22
|
const prefix = indexName.substring(0, 60 - suffix.length);
|
|
23
23
|
return `${prefix}${suffix}`;
|
|
24
24
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const database_1 = require("../database");
|
|
7
|
-
const database_2 = __importDefault(require("../database"));
|
|
8
3
|
const localTypeMap = {
|
|
9
4
|
// Shared
|
|
10
5
|
boolean: 'boolean',
|
|
@@ -100,8 +95,6 @@ const localTypeMap = {
|
|
|
100
95
|
integerfirst: 'integer',
|
|
101
96
|
};
|
|
102
97
|
function getLocalType(column, field) {
|
|
103
|
-
const database = (0, database_2.default)();
|
|
104
|
-
const databaseClient = (0, database_1.getDatabaseClient)(database);
|
|
105
98
|
if (!column)
|
|
106
99
|
return 'alias';
|
|
107
100
|
const dataType = column.data_type.toLowerCase();
|
|
@@ -125,13 +118,9 @@ function getLocalType(column, field) {
|
|
|
125
118
|
return 'decimal';
|
|
126
119
|
}
|
|
127
120
|
/** Handle MS SQL varchar(MAX) (eg TEXT) types */
|
|
128
|
-
if (
|
|
121
|
+
if (column.data_type === 'nvarchar' && column.max_length === -1) {
|
|
129
122
|
return 'text';
|
|
130
123
|
}
|
|
131
|
-
/** Handle Boolean as TINYINT and edgecase MySQL where it still is just tinyint */
|
|
132
|
-
if (databaseClient === 'mysql' && dataType === 'tinyint(1)') {
|
|
133
|
-
return 'boolean';
|
|
134
|
-
}
|
|
135
124
|
return type !== null && type !== void 0 ? type : 'unknown';
|
|
136
125
|
}
|
|
137
126
|
exports.default = getLocalType;
|
|
@@ -23,13 +23,13 @@ function mergePerm(currentPerm, newPerm) {
|
|
|
23
23
|
let validation = currentPerm.validation;
|
|
24
24
|
let fields = currentPerm.fields;
|
|
25
25
|
let presets = currentPerm.presets;
|
|
26
|
-
if (newPerm.permissions) {
|
|
26
|
+
if (newPerm.permissions && !(0, lodash_1.isEmpty)(newPerm.permissions)) {
|
|
27
27
|
if (currentPerm.permissions && Object.keys(currentPerm.permissions)[0] === '_or') {
|
|
28
28
|
permissions = {
|
|
29
29
|
_or: [...currentPerm.permissions._or, newPerm.permissions],
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
else if (currentPerm.permissions) {
|
|
32
|
+
else if (currentPerm.permissions && !(0, lodash_1.isEmpty)(currentPerm.permissions)) {
|
|
33
33
|
permissions = {
|
|
34
34
|
_or: [currentPerm.permissions, newPerm.permissions],
|
|
35
35
|
};
|
|
@@ -106,17 +106,6 @@ function sanitizeFilter(rawFilter, accountability) {
|
|
|
106
106
|
logger_1.default.warn('Invalid value passed for filter query parameter.');
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
filters = (0, utils_1.deepMap)(filters, (val) => {
|
|
110
|
-
try {
|
|
111
|
-
const parsed = JSON.parse(val);
|
|
112
|
-
if (typeof parsed == 'number' && !Number.isSafeInteger(parsed))
|
|
113
|
-
return val;
|
|
114
|
-
return parsed;
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return val;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
109
|
return (0, utils_1.parseFilter)(filters, accountability);
|
|
121
110
|
}
|
|
122
111
|
function sanitizeLimit(rawLimit) {
|
|
@@ -167,7 +156,7 @@ function sanitizeDeep(deep, accountability) {
|
|
|
167
156
|
const [parsedKey, parsedValue] = Object.entries(parsedSubQuery)[0];
|
|
168
157
|
parsedLevel[`_${parsedKey}`] = parsedValue;
|
|
169
158
|
}
|
|
170
|
-
else {
|
|
159
|
+
else if ((0, lodash_1.isPlainObject)(value)) {
|
|
171
160
|
parse(value, [...path, key]);
|
|
172
161
|
}
|
|
173
162
|
}
|
|
@@ -100,7 +100,7 @@ function validateFilterPrimitive(value, key) {
|
|
|
100
100
|
false) {
|
|
101
101
|
throw new exceptions_1.InvalidQueryException(`The filter value for "${key}" has to be a string, number, or boolean`);
|
|
102
102
|
}
|
|
103
|
-
if (typeof value === 'number' && Number.isNaN(value)) {
|
|
103
|
+
if (typeof value === 'number' && (Number.isNaN(value) || !Number.isSafeInteger(value))) {
|
|
104
104
|
throw new exceptions_1.InvalidQueryException(`The filter value for "${key}" is not a valid number`);
|
|
105
105
|
}
|
|
106
106
|
if (typeof value === 'string' && value.length === 0) {
|
package/dist/webhooks.js
CHANGED
|
@@ -8,7 +8,6 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
8
8
|
const database_1 = __importDefault(require("./database"));
|
|
9
9
|
const emitter_1 = __importDefault(require("./emitter"));
|
|
10
10
|
const logger_1 = __importDefault(require("./logger"));
|
|
11
|
-
const lodash_1 = require("lodash");
|
|
12
11
|
const services_1 = require("./services");
|
|
13
12
|
const get_schema_1 = require("./utils/get-schema");
|
|
14
13
|
let registered = [];
|
|
@@ -17,20 +16,12 @@ async function register() {
|
|
|
17
16
|
const webhookService = new services_1.WebhooksService({ knex: (0, database_1.default)(), schema: await (0, get_schema_1.getSchema)() });
|
|
18
17
|
const webhooks = await webhookService.readByQuery({ filter: { status: { _eq: 'active' } } });
|
|
19
18
|
for (const webhook of webhooks) {
|
|
20
|
-
|
|
21
|
-
const event =
|
|
22
|
-
const handler = createHandler(webhook);
|
|
19
|
+
for (const action of webhook.actions) {
|
|
20
|
+
const event = `items.${action}`;
|
|
21
|
+
const handler = createHandler(webhook, event);
|
|
23
22
|
emitter_1.default.onAction(event, handler);
|
|
24
23
|
registered.push({ event, handler });
|
|
25
24
|
}
|
|
26
|
-
else {
|
|
27
|
-
for (const action of webhook.actions) {
|
|
28
|
-
const event = `items.${action}`;
|
|
29
|
-
const handler = createHandler(webhook);
|
|
30
|
-
emitter_1.default.onAction(event, handler);
|
|
31
|
-
registered.push({ event, handler });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
25
|
}
|
|
35
26
|
}
|
|
36
27
|
exports.register = register;
|
|
@@ -41,19 +32,20 @@ function unregister() {
|
|
|
41
32
|
registered = [];
|
|
42
33
|
}
|
|
43
34
|
exports.unregister = unregister;
|
|
44
|
-
function createHandler(webhook) {
|
|
45
|
-
return async (
|
|
46
|
-
if (webhook.collections.includes(
|
|
35
|
+
function createHandler(webhook, event) {
|
|
36
|
+
return async (meta, context) => {
|
|
37
|
+
if (webhook.collections.includes(meta.collection) === false)
|
|
47
38
|
return;
|
|
48
|
-
const webhookPayload =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
const webhookPayload = {
|
|
40
|
+
event,
|
|
41
|
+
accountability: context.accountability
|
|
42
|
+
? {
|
|
43
|
+
user: context.accountability.user,
|
|
44
|
+
role: context.accountability.role,
|
|
45
|
+
}
|
|
46
|
+
: null,
|
|
47
|
+
...meta,
|
|
48
|
+
};
|
|
57
49
|
try {
|
|
58
50
|
await (0, axios_1.default)({
|
|
59
51
|
url: webhook.url,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"license": "GPL-3.0-only",
|
|
5
5
|
"homepage": "https://github.com/directus/directus#readme",
|
|
6
6
|
"description": "Directus is a real-time API and App dashboard for managing SQL database content.",
|
|
@@ -76,16 +76,16 @@
|
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"@aws-sdk/client-ses": "^3.40.0",
|
|
79
|
-
"@directus/app": "9.
|
|
80
|
-
"@directus/drive": "9.
|
|
81
|
-
"@directus/drive-azure": "9.
|
|
82
|
-
"@directus/drive-gcs": "9.
|
|
83
|
-
"@directus/drive-s3": "9.
|
|
84
|
-
"@directus/extensions-sdk": "9.
|
|
85
|
-
"@directus/format-title": "9.
|
|
86
|
-
"@directus/schema": "9.
|
|
87
|
-
"@directus/shared": "9.
|
|
88
|
-
"@directus/specs": "9.
|
|
79
|
+
"@directus/app": "9.2.0",
|
|
80
|
+
"@directus/drive": "9.2.0",
|
|
81
|
+
"@directus/drive-azure": "9.2.0",
|
|
82
|
+
"@directus/drive-gcs": "9.2.0",
|
|
83
|
+
"@directus/drive-s3": "9.2.0",
|
|
84
|
+
"@directus/extensions-sdk": "9.2.0",
|
|
85
|
+
"@directus/format-title": "9.2.0",
|
|
86
|
+
"@directus/schema": "9.2.0",
|
|
87
|
+
"@directus/shared": "9.2.0",
|
|
88
|
+
"@directus/specs": "9.2.0",
|
|
89
89
|
"@godaddy/terminus": "^4.9.0",
|
|
90
90
|
"@rollup/plugin-alias": "^3.1.2",
|
|
91
91
|
"@rollup/plugin-virtual": "^2.0.3",
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"jsonwebtoken": "^8.5.1",
|
|
123
123
|
"keyv": "^4.0.3",
|
|
124
124
|
"knex": "^0.95.11",
|
|
125
|
-
"knex-schema-inspector": "1.6.
|
|
125
|
+
"knex-schema-inspector": "1.6.6",
|
|
126
126
|
"ldapjs": "^2.3.1",
|
|
127
127
|
"liquidjs": "^9.25.0",
|
|
128
128
|
"lodash": "^4.17.21",
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
"sqlite3": "^5.0.2",
|
|
170
170
|
"tedious": "^13.0.0"
|
|
171
171
|
},
|
|
172
|
-
"gitHead": "
|
|
172
|
+
"gitHead": "776c105aacfda559a1ebf49cb2220599652f6c48",
|
|
173
173
|
"devDependencies": {
|
|
174
174
|
"@types/async": "3.2.10",
|
|
175
175
|
"@types/atob": "2.1.2",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Knex } from 'knex';
|
|
2
|
-
import { HelperFn } from '../types';
|
|
3
|
-
export declare class HelperOracle implements HelperFn {
|
|
4
|
-
private knex;
|
|
5
|
-
constructor(knex: Knex);
|
|
6
|
-
year(table: string, column: string): Knex.Raw;
|
|
7
|
-
month(table: string, column: string): Knex.Raw;
|
|
8
|
-
week(table: string, column: string): Knex.Raw;
|
|
9
|
-
day(table: string, column: string): Knex.Raw;
|
|
10
|
-
weekday(table: string, column: string): Knex.Raw;
|
|
11
|
-
hour(table: string, column: string): Knex.Raw;
|
|
12
|
-
minute(table: string, column: string): Knex.Raw;
|
|
13
|
-
second(table: string, column: string): Knex.Raw;
|
|
14
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Knex } from 'knex';
|
|
2
|
-
import { HelperFn } from '../types';
|
|
3
|
-
export declare class HelperPostgres implements HelperFn {
|
|
4
|
-
private knex;
|
|
5
|
-
constructor(knex: Knex);
|
|
6
|
-
year(table: string, column: string): Knex.Raw;
|
|
7
|
-
month(table: string, column: string): Knex.Raw;
|
|
8
|
-
week(table: string, column: string): Knex.Raw;
|
|
9
|
-
day(table: string, column: string): Knex.Raw;
|
|
10
|
-
weekday(table: string, column: string): Knex.Raw;
|
|
11
|
-
hour(table: string, column: string): Knex.Raw;
|
|
12
|
-
minute(table: string, column: string): Knex.Raw;
|
|
13
|
-
second(table: string, column: string): Knex.Raw;
|
|
14
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HelperSQLite = void 0;
|
|
4
|
-
class HelperSQLite {
|
|
5
|
-
constructor(knex) {
|
|
6
|
-
this.knex = knex;
|
|
7
|
-
}
|
|
8
|
-
year(table, column) {
|
|
9
|
-
return this.knex.raw("strftime('%Y', ??.??)", [table, column]);
|
|
10
|
-
}
|
|
11
|
-
month(table, column) {
|
|
12
|
-
return this.knex.raw("strftime('%m', ??.??)", [table, column]);
|
|
13
|
-
}
|
|
14
|
-
week(table, column) {
|
|
15
|
-
return this.knex.raw("strftime('%W', ??.??)", [table, column]);
|
|
16
|
-
}
|
|
17
|
-
day(table, column) {
|
|
18
|
-
return this.knex.raw("strftime('%d', ??.??)", [table, column]);
|
|
19
|
-
}
|
|
20
|
-
weekday(table, column) {
|
|
21
|
-
return this.knex.raw("strftime('%w', ??.??)", [table, column]);
|
|
22
|
-
}
|
|
23
|
-
hour(table, column) {
|
|
24
|
-
return this.knex.raw("strftime('%H', ??.??)", [table, column]);
|
|
25
|
-
}
|
|
26
|
-
minute(table, column) {
|
|
27
|
-
return this.knex.raw("strftime('%M', ??.??)", [table, column]);
|
|
28
|
-
}
|
|
29
|
-
second(table, column) {
|
|
30
|
-
return this.knex.raw("strftime('%S', ??.??)", [table, column]);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.HelperSQLite = HelperSQLite;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FunctionsHelper = void 0;
|
|
4
|
-
const postgres_1 = require("./dialects/postgres");
|
|
5
|
-
const mysql_1 = require("./dialects/mysql");
|
|
6
|
-
const mssql_1 = require("./dialects/mssql");
|
|
7
|
-
const sqlite_1 = require("./dialects/sqlite");
|
|
8
|
-
const oracle_1 = require("./dialects/oracle");
|
|
9
|
-
function FunctionsHelper(knex) {
|
|
10
|
-
switch (knex.client.constructor.name) {
|
|
11
|
-
case 'Client_MySQL':
|
|
12
|
-
return new mysql_1.HelperMySQL(knex);
|
|
13
|
-
case 'Client_PG':
|
|
14
|
-
return new postgres_1.HelperPostgres(knex);
|
|
15
|
-
case 'Client_SQLite3':
|
|
16
|
-
return new sqlite_1.HelperSQLite(knex);
|
|
17
|
-
case 'Client_Oracledb':
|
|
18
|
-
case 'Client_Oracle':
|
|
19
|
-
return new oracle_1.HelperOracle(knex);
|
|
20
|
-
case 'Client_MSSQL':
|
|
21
|
-
return new mssql_1.HelperMSSQL(knex);
|
|
22
|
-
default:
|
|
23
|
-
throw Error('Unsupported driver used: ' + knex.client.constructor.name);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
exports.FunctionsHelper = FunctionsHelper;
|