directus 9.14.5 → 9.16.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/__utils__/items-utils.d.ts +2 -0
- package/dist/__utils__/items-utils.js +36 -0
- package/dist/__utils__/schemas.d.ts +13 -0
- package/dist/__utils__/schemas.js +304 -0
- package/dist/__utils__/snapshots.d.ts +5 -0
- package/dist/__utils__/snapshots.js +897 -0
- package/dist/app.js +2 -1
- package/dist/auth/drivers/ldap.js +18 -8
- package/dist/auth/drivers/oauth2.js +19 -9
- package/dist/auth/drivers/openid.js +19 -9
- package/dist/cache.d.ts +3 -0
- package/dist/cache.js +21 -2
- package/dist/cli/index.test.d.ts +1 -0
- package/dist/cli/index.test.js +58 -0
- package/dist/cli/utils/create-env/env-stub.liquid +2 -2
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -1
- package/dist/controllers/assets.js +27 -1
- package/dist/controllers/extensions.js +3 -2
- package/dist/controllers/files.test.d.ts +1 -0
- package/dist/controllers/files.test.js +49 -0
- package/dist/controllers/server.js +0 -1
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +3 -14
- package/dist/database/helpers/schema/dialects/cockroachdb.js +2 -8
- package/dist/database/helpers/schema/dialects/oracle.d.ts +3 -10
- package/dist/database/helpers/schema/dialects/oracle.js +2 -5
- package/dist/database/helpers/schema/types.d.ts +8 -18
- package/dist/database/helpers/schema/types.js +7 -36
- package/dist/database/migrations/20201105B-change-webhook-url-type.js +3 -2
- package/dist/database/migrations/20210312A-webhooks-collections-text.js +3 -2
- package/dist/database/migrations/20210415A-make-filesize-nullable.js +2 -2
- package/dist/database/migrations/20210510A-restructure-relations.js +3 -3
- package/dist/database/migrations/20210903A-add-auth-provider.js +2 -2
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.js +4 -2
- package/dist/database/migrations/20210920A-webhooks-url-not-null.js +2 -2
- package/dist/database/migrations/20220303A-remove-default-project-color.js +2 -2
- package/dist/database/migrations/20220325B-add-default-language.js +2 -2
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.js +2 -2
- package/dist/database/migrations/20220801A-update-notifications-timestamp-column.d.ts +3 -0
- package/dist/database/migrations/20220801A-update-notifications-timestamp-column.js +19 -0
- package/dist/database/migrations/20220802A-add-custom-aspect-ratios.d.ts +3 -0
- package/dist/database/migrations/20220802A-add-custom-aspect-ratios.js +15 -0
- package/dist/database/migrations/run.test.d.ts +1 -0
- package/dist/database/migrations/run.test.js +92 -0
- package/dist/database/system-data/fields/settings.yaml +33 -0
- package/dist/env.js +8 -0
- package/dist/env.test.d.ts +8 -0
- package/dist/env.test.js +39 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +10 -9
- package/dist/flows.js +2 -1
- package/dist/logger.js +0 -1
- package/dist/middleware/authenticate.test.d.ts +1 -0
- package/dist/middleware/authenticate.test.js +174 -0
- package/dist/middleware/cache.js +3 -3
- package/dist/middleware/extract-token.test.d.ts +1 -0
- package/dist/middleware/extract-token.test.js +60 -0
- package/dist/middleware/respond.js +2 -2
- package/dist/operations/exec/index.d.ts +5 -0
- package/dist/operations/exec/index.js +26 -0
- package/dist/operations/exec/index.test.d.ts +1 -0
- package/dist/operations/exec/index.test.js +95 -0
- package/dist/operations/item-create/index.js +1 -1
- package/dist/operations/item-delete/index.js +2 -2
- package/dist/operations/item-read/index.js +2 -2
- package/dist/operations/item-update/index.js +3 -3
- package/dist/operations/notification/index.js +9 -6
- package/dist/operations/request/index.js +22 -3
- package/dist/services/assets.d.ts +1 -1
- package/dist/services/assets.js +7 -2
- package/dist/services/authorization.js +2 -1
- package/dist/services/files.js +3 -2
- package/dist/services/files.test.d.ts +1 -0
- package/dist/services/files.test.js +53 -0
- package/dist/services/flows.js +4 -0
- package/dist/services/graphql/index.d.ts +2 -2
- package/dist/services/graphql/index.js +59 -40
- package/dist/services/graphql/types/hash.d.ts +2 -0
- package/dist/services/graphql/types/hash.js +9 -0
- package/dist/services/items.js +83 -39
- package/dist/services/items.test.d.ts +1 -0
- package/dist/services/items.test.js +765 -0
- package/dist/services/payload.d.ts +7 -4
- package/dist/services/payload.js +35 -8
- package/dist/services/payload.test.d.ts +1 -0
- package/dist/services/payload.test.js +94 -0
- package/dist/services/server.js +5 -3
- package/dist/services/specifications.js +1 -6
- package/dist/services/specifications.test.d.ts +1 -0
- package/dist/services/specifications.test.js +96 -0
- package/dist/types/items.d.ts +11 -0
- package/dist/utils/apply-query.js +15 -0
- package/dist/utils/apply-snapshot.js +15 -0
- package/dist/utils/apply-snapshot.test.d.ts +1 -0
- package/dist/utils/apply-snapshot.test.js +305 -0
- package/dist/utils/calculate-field-depth.test.d.ts +1 -0
- package/dist/utils/calculate-field-depth.test.js +76 -0
- package/dist/utils/compress.d.ts +3 -0
- package/dist/utils/compress.js +17 -0
- package/dist/utils/filter-items.test.d.ts +1 -0
- package/dist/utils/filter-items.test.js +60 -0
- package/dist/utils/get-ast-from-query.js +1 -1
- package/dist/utils/get-cache-key.test.d.ts +1 -0
- package/dist/utils/get-cache-key.test.js +53 -0
- package/dist/utils/get-column-path.test.d.ts +1 -0
- package/dist/utils/get-column-path.test.js +136 -0
- package/dist/utils/get-config-from-env.test.d.ts +1 -0
- package/dist/utils/get-config-from-env.test.js +19 -0
- package/dist/utils/get-graphql-type.d.ts +1 -1
- package/dist/utils/get-graphql-type.js +7 -1
- package/dist/utils/get-os-info.d.ts +9 -0
- package/dist/utils/get-os-info.js +47 -0
- package/dist/utils/get-permissions.js +2 -2
- package/dist/utils/get-relation-info.test.d.ts +1 -0
- package/dist/utils/get-relation-info.test.js +88 -0
- package/dist/utils/get-relation-type.test.d.ts +1 -0
- package/dist/utils/get-relation-type.test.js +69 -0
- package/dist/utils/get-schema.js +1 -2
- package/dist/utils/get-string-byte-size.test.d.ts +1 -0
- package/dist/utils/get-string-byte-size.test.js +8 -0
- package/dist/utils/is-directus-jwt.test.d.ts +1 -0
- package/dist/utils/is-directus-jwt.test.js +26 -0
- package/dist/utils/jwt.test.d.ts +1 -0
- package/dist/utils/jwt.test.js +36 -0
- package/dist/utils/merge-permissions.test.d.ts +1 -0
- package/dist/utils/merge-permissions.test.js +80 -0
- package/dist/utils/validate-keys.test.d.ts +1 -0
- package/dist/utils/validate-keys.test.js +97 -0
- package/package.json +12 -11
package/dist/services/flows.js
CHANGED
|
@@ -39,12 +39,16 @@ class FlowsService extends items_1.ItemsService {
|
|
|
39
39
|
}
|
|
40
40
|
async deleteOne(key, opts) {
|
|
41
41
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
42
|
+
// this is to prevent foreign key constraint error on directus_operations resolve/reject during cascade deletion
|
|
43
|
+
await this.knex('directus_operations').update({ resolve: null, reject: null }).where('flow', key);
|
|
42
44
|
const result = await super.deleteOne(key, opts);
|
|
43
45
|
await flowManager.reload();
|
|
44
46
|
return result;
|
|
45
47
|
}
|
|
46
48
|
async deleteMany(keys, opts) {
|
|
47
49
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
50
|
+
// this is to prevent foreign key constraint error on directus_operations resolve/reject during cascade deletion
|
|
51
|
+
await this.knex('directus_operations').update({ resolve: null, reject: null }).whereIn('flow', keys);
|
|
48
52
|
const result = await super.deleteMany(keys, opts);
|
|
49
53
|
await flowManager.reload();
|
|
50
54
|
return result;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseException } from '@directus/shared/exceptions';
|
|
2
2
|
import { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
3
|
-
import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLSchema,
|
|
3
|
+
import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLSchema, SelectionNode } from 'graphql';
|
|
4
4
|
import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
|
|
5
5
|
import { Knex } from 'knex';
|
|
6
6
|
import { AbstractServiceOptions, GraphQLParams, Item } from '../../types';
|
|
@@ -44,7 +44,7 @@ export declare class GraphQLService {
|
|
|
44
44
|
* In order to do that, we'll parse over all ArgumentNodes and ObjectFieldNodes to manually recreate an object structure
|
|
45
45
|
* of arguments
|
|
46
46
|
*/
|
|
47
|
-
parseArgs(args: readonly ArgumentNode[]
|
|
47
|
+
parseArgs(args: readonly ArgumentNode[], variableValues: GraphQLResolveInfo['variableValues']): Record<string, any>;
|
|
48
48
|
/**
|
|
49
49
|
* Get a Directus Query object from the parsed arguments (rawQuery) and GraphQL AST selectionSet. Converts SelectionSet into
|
|
50
50
|
* Directus' `fields` query for use in the resolver. Also applies variables where appropriate.
|
|
@@ -50,6 +50,7 @@ const geojson_1 = require("./types/geojson");
|
|
|
50
50
|
const string_or_float_1 = require("./types/string-or-float");
|
|
51
51
|
const void_1 = require("./types/void");
|
|
52
52
|
const add_path_to_validation_error_1 = require("./utils/add-path-to-validation-error");
|
|
53
|
+
const hash_1 = require("./types/hash");
|
|
53
54
|
const validationRules = Array.from(graphql_1.specifiedRules);
|
|
54
55
|
if (env_1.default.GRAPHQL_INTROSPECTION === false) {
|
|
55
56
|
validationRules.push(graphql_1.NoSchemaIntrospectionCustomRule);
|
|
@@ -273,11 +274,13 @@ class GraphQLService {
|
|
|
273
274
|
CollectionTypes[collection.collection] = schemaComposer.createObjectTC({
|
|
274
275
|
name: action === 'read' ? collection.collection : `${action}_${collection.collection}`,
|
|
275
276
|
fields: Object.values(collection.fields).reduce((acc, field) => {
|
|
276
|
-
let type = (0, get_graphql_type_1.getGraphQLType)(field.type);
|
|
277
|
+
let type = (0, get_graphql_type_1.getGraphQLType)(field.type, field.special);
|
|
277
278
|
// GraphQL doesn't differentiate between not-null and has-to-be-submitted. We
|
|
278
279
|
// can't non-null in update, as that would require every not-nullable field to be
|
|
279
280
|
// submitted on updates
|
|
280
|
-
if (field.nullable === false &&
|
|
281
|
+
if (field.nullable === false &&
|
|
282
|
+
!constants_1.GENERATE_SPECIAL.some((flag) => field.special.includes(flag)) &&
|
|
283
|
+
action !== 'update') {
|
|
281
284
|
type = (0, graphql_1.GraphQLNonNull)(type);
|
|
282
285
|
}
|
|
283
286
|
if (collection.primary === field.field) {
|
|
@@ -562,6 +565,23 @@ class GraphQLService {
|
|
|
562
565
|
},
|
|
563
566
|
},
|
|
564
567
|
});
|
|
568
|
+
const HashFilterOperators = schemaComposer.createInputTC({
|
|
569
|
+
name: 'hash_filter_operators',
|
|
570
|
+
fields: {
|
|
571
|
+
_null: {
|
|
572
|
+
type: graphql_1.GraphQLBoolean,
|
|
573
|
+
},
|
|
574
|
+
_nnull: {
|
|
575
|
+
type: graphql_1.GraphQLBoolean,
|
|
576
|
+
},
|
|
577
|
+
_empty: {
|
|
578
|
+
type: graphql_1.GraphQLBoolean,
|
|
579
|
+
},
|
|
580
|
+
_nempty: {
|
|
581
|
+
type: graphql_1.GraphQLBoolean,
|
|
582
|
+
},
|
|
583
|
+
},
|
|
584
|
+
});
|
|
565
585
|
const CountFunctionFilterOperators = schemaComposer.createInputTC({
|
|
566
586
|
name: 'count_function_filter_operators',
|
|
567
587
|
fields: {
|
|
@@ -619,7 +639,7 @@ class GraphQLService {
|
|
|
619
639
|
ReadableCollectionFilterTypes[collection.collection] = schemaComposer.createInputTC({
|
|
620
640
|
name: `${collection.collection}_filter`,
|
|
621
641
|
fields: Object.values(collection.fields).reduce((acc, field) => {
|
|
622
|
-
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type);
|
|
642
|
+
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type, field.special);
|
|
623
643
|
let filterOperatorType;
|
|
624
644
|
switch (graphqlType) {
|
|
625
645
|
case graphql_1.GraphQLBoolean:
|
|
@@ -635,6 +655,9 @@ class GraphQLService {
|
|
|
635
655
|
case geojson_1.GraphQLGeoJSON:
|
|
636
656
|
filterOperatorType = GeometryFilterOperators;
|
|
637
657
|
break;
|
|
658
|
+
case hash_1.GraphQLHash:
|
|
659
|
+
filterOperatorType = HashFilterOperators;
|
|
660
|
+
break;
|
|
638
661
|
default:
|
|
639
662
|
filterOperatorType = StringFilterOperators;
|
|
640
663
|
}
|
|
@@ -669,7 +692,7 @@ class GraphQLService {
|
|
|
669
692
|
AggregatedFields[collection.collection] = schemaComposer.createObjectTC({
|
|
670
693
|
name: `${collection.collection}_aggregated_fields`,
|
|
671
694
|
fields: Object.values(collection.fields).reduce((acc, field) => {
|
|
672
|
-
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type);
|
|
695
|
+
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type, field.special);
|
|
673
696
|
switch (graphqlType) {
|
|
674
697
|
case graphql_1.GraphQLInt:
|
|
675
698
|
case graphql_1.GraphQLFloat:
|
|
@@ -713,7 +736,7 @@ class GraphQLService {
|
|
|
713
736
|
},
|
|
714
737
|
};
|
|
715
738
|
const hasNumericAggregates = Object.values(collection.fields).some((field) => {
|
|
716
|
-
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type);
|
|
739
|
+
const graphqlType = (0, get_graphql_type_1.getGraphQLType)(field.type, field.special);
|
|
717
740
|
if (graphqlType === graphql_1.GraphQLInt || graphqlType === graphql_1.GraphQLFloat) {
|
|
718
741
|
return true;
|
|
719
742
|
}
|
|
@@ -1184,38 +1207,29 @@ class GraphQLService {
|
|
|
1184
1207
|
parseArgs(args, variableValues) {
|
|
1185
1208
|
if (!args || args.length === 0)
|
|
1186
1209
|
return {};
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
}
|
|
1208
|
-
else {
|
|
1209
|
-
values.push(valueNode.value);
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
argsObject[argument.name.value] = values;
|
|
1210
|
+
const parse = (node) => {
|
|
1211
|
+
switch (node.kind) {
|
|
1212
|
+
case 'Variable':
|
|
1213
|
+
return variableValues[node.name.value];
|
|
1214
|
+
case 'ListValue':
|
|
1215
|
+
return node.values.map(parse);
|
|
1216
|
+
case 'ObjectValue':
|
|
1217
|
+
return Object.fromEntries(node.fields.map((node) => [node.name.value, parse(node.value)]));
|
|
1218
|
+
case 'NullValue':
|
|
1219
|
+
return null;
|
|
1220
|
+
case 'StringValue':
|
|
1221
|
+
return String(node.value);
|
|
1222
|
+
case 'IntValue':
|
|
1223
|
+
case 'FloatValue':
|
|
1224
|
+
return Number(node.value);
|
|
1225
|
+
case 'BooleanValue':
|
|
1226
|
+
return Boolean(node.value);
|
|
1227
|
+
case 'EnumValue':
|
|
1228
|
+
default:
|
|
1229
|
+
return node.value;
|
|
1214
1230
|
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1231
|
+
};
|
|
1232
|
+
const argsObject = Object.fromEntries(args.map((arg) => [arg.name.value, parse(arg.value)]));
|
|
1219
1233
|
return argsObject;
|
|
1220
1234
|
}
|
|
1221
1235
|
/**
|
|
@@ -1315,7 +1329,8 @@ class GraphQLService {
|
|
|
1315
1329
|
result[currentKey] = Object.values(value)[0];
|
|
1316
1330
|
}
|
|
1317
1331
|
else {
|
|
1318
|
-
result[currentKey] =
|
|
1332
|
+
result[currentKey] =
|
|
1333
|
+
(value === null || value === void 0 ? void 0 : value.constructor) === Object || (value === null || value === void 0 ? void 0 : value.constructor) === Array ? replaceFuncDeep(value) : value;
|
|
1319
1334
|
}
|
|
1320
1335
|
});
|
|
1321
1336
|
}
|
|
@@ -1878,7 +1893,9 @@ class GraphQLService {
|
|
|
1878
1893
|
name: 'directus_collections_meta',
|
|
1879
1894
|
fields: Object.values(schema.read.collections['directus_collections'].fields).reduce((acc, field) => {
|
|
1880
1895
|
acc[field.field] = {
|
|
1881
|
-
type: field.nullable
|
|
1896
|
+
type: field.nullable
|
|
1897
|
+
? (0, get_graphql_type_1.getGraphQLType)(field.type, field.special)
|
|
1898
|
+
: (0, graphql_1.GraphQLNonNull)((0, get_graphql_type_1.getGraphQLType)(field.type, field.special)),
|
|
1882
1899
|
description: field.note,
|
|
1883
1900
|
};
|
|
1884
1901
|
return acc;
|
|
@@ -1927,7 +1944,9 @@ class GraphQLService {
|
|
|
1927
1944
|
name: 'directus_fields_meta',
|
|
1928
1945
|
fields: Object.values(schema.read.collections['directus_fields'].fields).reduce((acc, field) => {
|
|
1929
1946
|
acc[field.field] = {
|
|
1930
|
-
type: field.nullable
|
|
1947
|
+
type: field.nullable
|
|
1948
|
+
? (0, get_graphql_type_1.getGraphQLType)(field.type, field.special)
|
|
1949
|
+
: (0, graphql_1.GraphQLNonNull)((0, get_graphql_type_1.getGraphQLType)(field.type, field.special)),
|
|
1931
1950
|
description: field.note,
|
|
1932
1951
|
};
|
|
1933
1952
|
return acc;
|
|
@@ -2014,7 +2033,7 @@ class GraphQLService {
|
|
|
2014
2033
|
name: 'directus_relations_meta',
|
|
2015
2034
|
fields: Object.values(schema.read.collections['directus_relations'].fields).reduce((acc, field) => {
|
|
2016
2035
|
acc[field.field] = {
|
|
2017
|
-
type: (0, get_graphql_type_1.getGraphQLType)(field.type),
|
|
2036
|
+
type: (0, get_graphql_type_1.getGraphQLType)(field.type, field.special),
|
|
2018
2037
|
description: field.note,
|
|
2019
2038
|
};
|
|
2020
2039
|
return acc;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLHash = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
exports.GraphQLHash = new graphql_1.GraphQLScalarType({
|
|
6
|
+
...graphql_1.GraphQLString,
|
|
7
|
+
name: 'Hash',
|
|
8
|
+
description: 'Hashed string values',
|
|
9
|
+
});
|
package/dist/services/items.js
CHANGED
|
@@ -52,6 +52,7 @@ class ItemsService {
|
|
|
52
52
|
.filter((field) => field.alias === true)
|
|
53
53
|
.map((field) => field.field);
|
|
54
54
|
const payload = (0, lodash_1.cloneDeep)(data);
|
|
55
|
+
const nestedActionEvents = [];
|
|
55
56
|
// By wrapping the logic in a transaction, we make sure we automatically roll back all the
|
|
56
57
|
// changes in the DB if any of the parts contained within throws an error. This also means
|
|
57
58
|
// that any errors thrown in any nested relational changes will bubble up and cancel the whole
|
|
@@ -84,8 +85,8 @@ class ItemsService {
|
|
|
84
85
|
const payloadWithPresets = this.accountability
|
|
85
86
|
? await authorizationService.validatePayload('create', this.collection, payloadAfterHooks)
|
|
86
87
|
: payloadAfterHooks;
|
|
87
|
-
const { payload: payloadWithM2O, revisions: revisionsM2O } = await payloadService.processM2O(payloadWithPresets);
|
|
88
|
-
const { payload: payloadWithA2O, revisions: revisionsA2O } = await payloadService.processA2O(payloadWithM2O);
|
|
88
|
+
const { payload: payloadWithM2O, revisions: revisionsM2O, nestedActionEvents: nestedActionEventsM2O, } = await payloadService.processM2O(payloadWithPresets, opts);
|
|
89
|
+
const { payload: payloadWithA2O, revisions: revisionsA2O, nestedActionEvents: nestedActionEventsA2O, } = await payloadService.processA2O(payloadWithM2O, opts);
|
|
89
90
|
const payloadWithoutAliases = (0, lodash_1.pick)(payloadWithA2O, (0, lodash_1.without)(fields, ...aliases));
|
|
90
91
|
const payloadWithTypeCasting = await payloadService.processValues('create', payloadWithoutAliases);
|
|
91
92
|
// In case of manual string / UUID primary keys, the PK already exists in the object we're saving.
|
|
@@ -113,7 +114,10 @@ class ItemsService {
|
|
|
113
114
|
// to read from it
|
|
114
115
|
payload[primaryKeyField] = primaryKey;
|
|
115
116
|
}
|
|
116
|
-
const { revisions: revisionsO2M } = await payloadService.processO2M(payload, primaryKey);
|
|
117
|
+
const { revisions: revisionsO2M, nestedActionEvents: nestedActionEventsO2M } = await payloadService.processO2M(payload, primaryKey, opts);
|
|
118
|
+
nestedActionEvents.push(...nestedActionEventsM2O);
|
|
119
|
+
nestedActionEvents.push(...nestedActionEventsA2O);
|
|
120
|
+
nestedActionEvents.push(...nestedActionEventsO2M);
|
|
117
121
|
// If this is an authenticated action, and accountability tracking is enabled, save activity row
|
|
118
122
|
if (this.accountability && this.schema.collections[this.collection].accountability !== null) {
|
|
119
123
|
const activityService = new index_1.ActivityService({
|
|
@@ -154,17 +158,30 @@ class ItemsService {
|
|
|
154
158
|
return primaryKey;
|
|
155
159
|
});
|
|
156
160
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
const actionEvent = {
|
|
162
|
+
event: this.eventScope === 'items'
|
|
163
|
+
? ['items.create', `${this.collection}.items.create`]
|
|
164
|
+
: `${this.eventScope}.create`,
|
|
165
|
+
meta: {
|
|
166
|
+
payload,
|
|
167
|
+
key: primaryKey,
|
|
168
|
+
collection: this.collection,
|
|
169
|
+
},
|
|
170
|
+
context: {
|
|
171
|
+
database: (0, database_1.default)(),
|
|
172
|
+
schema: this.schema,
|
|
173
|
+
accountability: this.accountability,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction)) {
|
|
177
|
+
emitter_1.default.emitAction(actionEvent.event, actionEvent.meta, actionEvent.context);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
opts.bypassEmitAction(actionEvent);
|
|
181
|
+
}
|
|
182
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
183
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
184
|
+
}
|
|
168
185
|
}
|
|
169
186
|
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
170
187
|
await this.cache.clear();
|
|
@@ -323,6 +340,7 @@ class ItemsService {
|
|
|
323
340
|
.filter((field) => field.alias === true)
|
|
324
341
|
.map((field) => field.field);
|
|
325
342
|
const payload = (0, lodash_1.cloneDeep)(data);
|
|
343
|
+
const nestedActionEvents = [];
|
|
326
344
|
const authorizationService = new authorization_1.AuthorizationService({
|
|
327
345
|
accountability: this.accountability,
|
|
328
346
|
knex: this.knex,
|
|
@@ -356,8 +374,8 @@ class ItemsService {
|
|
|
356
374
|
knex: trx,
|
|
357
375
|
schema: this.schema,
|
|
358
376
|
});
|
|
359
|
-
const { payload: payloadWithM2O, revisions: revisionsM2O } = await payloadService.processM2O(payloadWithPresets);
|
|
360
|
-
const { payload: payloadWithA2O, revisions: revisionsA2O } = await payloadService.processA2O(payloadWithM2O);
|
|
377
|
+
const { payload: payloadWithM2O, revisions: revisionsM2O, nestedActionEvents: nestedActionEventsM2O, } = await payloadService.processM2O(payloadWithPresets, opts);
|
|
378
|
+
const { payload: payloadWithA2O, revisions: revisionsA2O, nestedActionEvents: nestedActionEventsA2O, } = await payloadService.processA2O(payloadWithM2O, opts);
|
|
361
379
|
const payloadWithoutAliasAndPK = (0, lodash_1.pick)(payloadWithA2O, (0, lodash_1.without)(fields, primaryKeyField, ...aliases));
|
|
362
380
|
const payloadWithTypeCasting = await payloadService.processValues('update', payloadWithoutAliasAndPK);
|
|
363
381
|
if (Object.keys(payloadWithTypeCasting).length > 0) {
|
|
@@ -369,9 +387,12 @@ class ItemsService {
|
|
|
369
387
|
}
|
|
370
388
|
}
|
|
371
389
|
const childrenRevisions = [...revisionsM2O, ...revisionsA2O];
|
|
390
|
+
nestedActionEvents.push(...nestedActionEventsM2O);
|
|
391
|
+
nestedActionEvents.push(...nestedActionEventsA2O);
|
|
372
392
|
for (const key of keys) {
|
|
373
|
-
const { revisions } = await payloadService.processO2M(payload, key);
|
|
393
|
+
const { revisions, nestedActionEvents: nestedActionEventsO2M } = await payloadService.processO2M(payload, key, opts);
|
|
374
394
|
childrenRevisions.push(...revisions);
|
|
395
|
+
nestedActionEvents.push(...nestedActionEventsO2M);
|
|
375
396
|
}
|
|
376
397
|
// If this is an authenticated action, and accountability tracking is enabled, save activity row
|
|
377
398
|
if (this.accountability && this.schema.collections[this.collection].accountability !== null) {
|
|
@@ -427,17 +448,30 @@ class ItemsService {
|
|
|
427
448
|
await this.cache.clear();
|
|
428
449
|
}
|
|
429
450
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
451
|
+
const actionEvent = {
|
|
452
|
+
event: this.eventScope === 'items'
|
|
453
|
+
? ['items.update', `${this.collection}.items.update`]
|
|
454
|
+
: `${this.eventScope}.update`,
|
|
455
|
+
meta: {
|
|
456
|
+
payload,
|
|
457
|
+
keys,
|
|
458
|
+
collection: this.collection,
|
|
459
|
+
},
|
|
460
|
+
context: {
|
|
461
|
+
database: (0, database_1.default)(),
|
|
462
|
+
schema: this.schema,
|
|
463
|
+
accountability: this.accountability,
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction)) {
|
|
467
|
+
emitter_1.default.emitAction(actionEvent.event, actionEvent.meta, actionEvent.context);
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
opts.bypassEmitAction(actionEvent);
|
|
471
|
+
}
|
|
472
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
473
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
474
|
+
}
|
|
441
475
|
}
|
|
442
476
|
return keys;
|
|
443
477
|
}
|
|
@@ -547,17 +581,27 @@ class ItemsService {
|
|
|
547
581
|
await this.cache.clear();
|
|
548
582
|
}
|
|
549
583
|
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
584
|
+
const actionEvent = {
|
|
585
|
+
event: this.eventScope === 'items'
|
|
586
|
+
? ['items.delete', `${this.collection}.items.delete`]
|
|
587
|
+
: `${this.eventScope}.delete`,
|
|
588
|
+
meta: {
|
|
589
|
+
payload: keys,
|
|
590
|
+
keys: keys,
|
|
591
|
+
collection: this.collection,
|
|
592
|
+
},
|
|
593
|
+
context: {
|
|
594
|
+
database: (0, database_1.default)(),
|
|
595
|
+
schema: this.schema,
|
|
596
|
+
accountability: this.accountability,
|
|
597
|
+
},
|
|
598
|
+
};
|
|
599
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction)) {
|
|
600
|
+
emitter_1.default.emitAction(actionEvent.event, actionEvent.meta, actionEvent.context);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
opts.bypassEmitAction(actionEvent);
|
|
604
|
+
}
|
|
561
605
|
}
|
|
562
606
|
return keys;
|
|
563
607
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|