directus 9.12.2 → 9.14.1
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/app.js +14 -5
- package/dist/auth/drivers/index.js +5 -1
- package/dist/auth/drivers/ldap.js +5 -1
- package/dist/auth/drivers/oauth2.js +15 -23
- package/dist/auth/drivers/openid.js +20 -25
- package/dist/cli/commands/bootstrap/index.js +5 -1
- package/dist/cli/commands/schema/apply.js +7 -3
- package/dist/cli/commands/schema/snapshot.d.ts +1 -1
- package/dist/cli/commands/schema/snapshot.js +33 -25
- package/dist/cli/index.js +1 -1
- package/dist/cli/utils/create-env/env-stub.liquid +11 -11
- package/dist/controllers/assets.js +5 -5
- package/dist/controllers/dashboards.js +4 -1
- package/dist/controllers/files.js +8 -5
- package/dist/controllers/flows.js +4 -1
- package/dist/controllers/folders.js +4 -1
- package/dist/controllers/items.js +4 -1
- package/dist/controllers/notifications.js +4 -1
- package/dist/controllers/operations.js +4 -1
- package/dist/controllers/panels.js +4 -1
- package/dist/controllers/permissions.js +4 -1
- package/dist/controllers/presets.js +4 -1
- package/dist/controllers/roles.js +4 -1
- package/dist/controllers/shares.js +4 -1
- package/dist/controllers/users.js +75 -3
- package/dist/controllers/utils.js +3 -3
- package/dist/database/helpers/date/dialects/sqlite.js +3 -0
- package/dist/database/helpers/index.js +5 -1
- package/dist/database/index.js +2 -0
- package/dist/database/migrations/20210225A-add-relations-sort-field.js +2 -2
- package/dist/database/migrations/20210506A-rename-interfaces.js +2 -2
- package/dist/database/migrations/20210802A-replace-groups.js +2 -2
- package/dist/database/migrations/20210805A-update-groups.js +2 -2
- package/dist/database/migrations/20210805B-change-image-metadata-structure.js +3 -3
- package/dist/database/migrations/20211007A-update-presets.js +5 -5
- package/dist/database/migrations/20220429A-add-flows.js +1 -2
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +3 -0
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.js +11 -0
- package/dist/database/system-data/fields/dashboards.yaml +1 -0
- package/dist/emitter.js +12 -7
- package/dist/env.d.ts +1 -1
- package/dist/env.js +8 -3
- package/dist/exceptions/database/translate.js +5 -1
- package/dist/exceptions/index.js +5 -1
- package/dist/extensions.js +5 -1
- package/dist/flows.js +15 -11
- package/dist/index.js +5 -1
- package/dist/logger.js +5 -1
- package/dist/messenger.js +2 -2
- package/dist/middleware/graphql.js +2 -2
- package/dist/middleware/respond.js +10 -1
- package/dist/middleware/validate-batch.js +3 -1
- package/dist/operations/item-create/index.js +1 -2
- package/dist/operations/item-delete/index.d.ts +1 -0
- package/dist/operations/item-delete/index.js +8 -7
- package/dist/operations/item-read/index.d.ts +1 -0
- package/dist/operations/item-read/index.js +8 -7
- package/dist/operations/item-update/index.d.ts +1 -0
- package/dist/operations/item-update/index.js +9 -8
- package/dist/operations/log/index.js +1 -2
- package/dist/operations/notification/index.js +1 -2
- package/dist/operations/transform/index.js +1 -2
- package/dist/operations/trigger/index.js +1 -2
- package/dist/server.js +5 -1
- package/dist/services/assets.js +5 -1
- package/dist/services/collections.js +5 -1
- package/dist/services/fields.d.ts +3 -3
- package/dist/services/fields.js +25 -17
- package/dist/services/files.js +5 -1
- package/dist/services/flows.d.ts +1 -0
- package/dist/services/flows.js +6 -0
- package/dist/services/{graphql.d.ts → graphql/index.d.ts} +3 -5
- package/dist/services/{graphql.js → graphql/index.js} +109 -101
- package/dist/services/graphql/types/date.d.ts +2 -0
- package/dist/services/graphql/types/date.js +9 -0
- package/dist/services/graphql/types/geojson.d.ts +2 -0
- package/dist/services/graphql/types/geojson.js +10 -0
- package/dist/services/graphql/types/string-or-float.d.ts +5 -0
- package/dist/services/graphql/types/string-or-float.js +34 -0
- package/dist/services/graphql/types/void.d.ts +2 -0
- package/dist/services/graphql/types/void.js +17 -0
- package/dist/services/graphql/utils/add-path-to-validation-error.d.ts +2 -0
- package/dist/services/graphql/utils/add-path-to-validation-error.js +20 -0
- package/dist/services/import-export.js +12 -8
- package/dist/services/index.js +5 -1
- package/dist/services/items.d.ts +6 -1
- package/dist/services/items.js +43 -19
- package/dist/services/mail/index.js +8 -6
- package/dist/services/notifications.js +22 -11
- package/dist/services/operations.d.ts +1 -0
- package/dist/services/operations.js +6 -0
- package/dist/services/payload.js +13 -11
- package/dist/services/permissions.d.ts +1 -0
- package/dist/services/permissions.js +5 -0
- package/dist/services/relations.js +5 -1
- package/dist/services/roles.d.ts +1 -0
- package/dist/services/roles.js +9 -0
- package/dist/services/server.js +5 -1
- package/dist/services/users.d.ts +1 -0
- package/dist/services/users.js +17 -0
- package/dist/types/index.js +5 -1
- package/dist/utils/apply-query.js +24 -15
- package/dist/utils/calculate-field-depth.d.ts +33 -0
- package/dist/utils/calculate-field-depth.js +75 -0
- package/dist/utils/get-default-value.js +3 -13
- package/dist/utils/get-graphql-type.js +4 -3
- package/dist/utils/get-local-type.d.ts +6 -3
- package/dist/utils/get-permissions.js +3 -4
- package/dist/utils/get-schema.js +1 -2
- package/dist/utils/get-string-byte-size.d.ts +4 -0
- package/dist/utils/get-string-byte-size.js +10 -0
- package/dist/utils/jwt.js +5 -1
- package/dist/utils/sanitize-query.js +4 -5
- package/dist/utils/validate-query.js +50 -0
- package/dist/webhooks.js +5 -1
- package/package.json +74 -73
- package/dist/utils/operation-options.d.ts +0 -3
- package/dist/utils/operation-options.js +0 -45
- package/dist/utils/parse-json.d.ts +0 -5
- package/dist/utils/parse-json.js +0 -19
package/dist/services/files.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
package/dist/services/flows.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare class FlowsService extends ItemsService<FlowRaw> {
|
|
|
6
6
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
7
7
|
createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
8
8
|
updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
9
|
+
updateBatch(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
9
10
|
updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
10
11
|
deleteOne(key: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
11
12
|
deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
package/dist/services/flows.js
CHANGED
|
@@ -25,6 +25,12 @@ class FlowsService extends items_1.ItemsService {
|
|
|
25
25
|
await flowManager.reload();
|
|
26
26
|
return result;
|
|
27
27
|
}
|
|
28
|
+
async updateBatch(data, opts) {
|
|
29
|
+
const flowManager = (0, flows_1.getFlowManager)();
|
|
30
|
+
const result = await super.updateBatch(data, opts);
|
|
31
|
+
await flowManager.reload();
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
28
34
|
async updateMany(keys, data, opts) {
|
|
29
35
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
30
36
|
const result = await super.updateMany(keys, data, opts);
|
|
@@ -1,12 +1,10 @@
|
|
|
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,
|
|
3
|
+
import { ArgumentNode, FormattedExecutionResult, FragmentDefinitionNode, GraphQLError, GraphQLResolveInfo, GraphQLSchema, ObjectFieldNode, SelectionNode } from 'graphql';
|
|
4
4
|
import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
|
|
5
5
|
import { Knex } from 'knex';
|
|
6
|
-
import { AbstractServiceOptions, GraphQLParams, Item } from '
|
|
7
|
-
import { ItemsService } from '
|
|
8
|
-
export declare const GraphQLGeoJSON: GraphQLScalarType;
|
|
9
|
-
export declare const GraphQLDate: GraphQLScalarType;
|
|
6
|
+
import { AbstractServiceOptions, GraphQLParams, Item } from '../../types';
|
|
7
|
+
import { ItemsService } from '../items';
|
|
10
8
|
export declare class GraphQLService {
|
|
11
9
|
accountability: Accountability | null;
|
|
12
10
|
knex: Knex;
|
|
@@ -3,70 +3,56 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.GraphQLService =
|
|
6
|
+
exports.GraphQLService = void 0;
|
|
7
7
|
const types_1 = require("@directus/shared/types");
|
|
8
8
|
const argon2_1 = __importDefault(require("argon2"));
|
|
9
9
|
const graphql_1 = require("graphql");
|
|
10
10
|
const graphql_compose_1 = require("graphql-compose");
|
|
11
11
|
const lodash_1 = require("lodash");
|
|
12
12
|
const ms_1 = __importDefault(require("ms"));
|
|
13
|
-
const cache_1 = require("
|
|
14
|
-
const constants_1 = require("
|
|
15
|
-
const database_1 = __importDefault(require("
|
|
16
|
-
const env_1 = __importDefault(require("
|
|
17
|
-
const exceptions_1 = require("
|
|
18
|
-
const extensions_1 = require("
|
|
19
|
-
const generate_hash_1 = require("
|
|
20
|
-
const get_graphql_type_1 = require("
|
|
21
|
-
const reduce_schema_1 = require("
|
|
22
|
-
const sanitize_query_1 = require("
|
|
23
|
-
const validate_query_1 = require("
|
|
24
|
-
const activity_1 = require("
|
|
25
|
-
const authentication_1 = require("
|
|
26
|
-
const collections_1 = require("
|
|
27
|
-
const fields_1 = require("
|
|
28
|
-
const files_1 = require("
|
|
29
|
-
const flows_1 = require("
|
|
30
|
-
const folders_1 = require("
|
|
31
|
-
const items_1 = require("
|
|
32
|
-
const notifications_1 = require("
|
|
33
|
-
const operations_1 = require("
|
|
34
|
-
const permissions_1 = require("
|
|
35
|
-
const presets_1 = require("
|
|
36
|
-
const relations_1 = require("
|
|
37
|
-
const revisions_1 = require("
|
|
38
|
-
const roles_1 = require("
|
|
39
|
-
const server_1 = require("
|
|
40
|
-
const settings_1 = require("
|
|
41
|
-
const shares_1 = require("
|
|
42
|
-
const specifications_1 = require("
|
|
43
|
-
const tfa_1 = require("
|
|
44
|
-
const users_1 = require("
|
|
45
|
-
const utils_1 = require("
|
|
46
|
-
const webhooks_1 = require("
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
parseLiteral() {
|
|
57
|
-
return null;
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
exports.GraphQLGeoJSON = new graphql_1.GraphQLScalarType({
|
|
61
|
-
...graphql_compose_1.GraphQLJSON,
|
|
62
|
-
name: 'GraphQLGeoJSON',
|
|
63
|
-
description: 'GeoJSON value',
|
|
64
|
-
});
|
|
65
|
-
exports.GraphQLDate = new graphql_1.GraphQLScalarType({
|
|
66
|
-
...graphql_1.GraphQLString,
|
|
67
|
-
name: 'Date',
|
|
68
|
-
description: 'ISO8601 Date values',
|
|
69
|
-
});
|
|
13
|
+
const cache_1 = require("../../cache");
|
|
14
|
+
const constants_1 = require("../../constants");
|
|
15
|
+
const database_1 = __importDefault(require("../../database"));
|
|
16
|
+
const env_1 = __importDefault(require("../../env"));
|
|
17
|
+
const exceptions_1 = require("../../exceptions");
|
|
18
|
+
const extensions_1 = require("../../extensions");
|
|
19
|
+
const generate_hash_1 = require("../../utils/generate-hash");
|
|
20
|
+
const get_graphql_type_1 = require("../../utils/get-graphql-type");
|
|
21
|
+
const reduce_schema_1 = require("../../utils/reduce-schema");
|
|
22
|
+
const sanitize_query_1 = require("../../utils/sanitize-query");
|
|
23
|
+
const validate_query_1 = require("../../utils/validate-query");
|
|
24
|
+
const activity_1 = require("../activity");
|
|
25
|
+
const authentication_1 = require("../authentication");
|
|
26
|
+
const collections_1 = require("../collections");
|
|
27
|
+
const fields_1 = require("../fields");
|
|
28
|
+
const files_1 = require("../files");
|
|
29
|
+
const flows_1 = require("../flows");
|
|
30
|
+
const folders_1 = require("../folders");
|
|
31
|
+
const items_1 = require("../items");
|
|
32
|
+
const notifications_1 = require("../notifications");
|
|
33
|
+
const operations_1 = require("../operations");
|
|
34
|
+
const permissions_1 = require("../permissions");
|
|
35
|
+
const presets_1 = require("../presets");
|
|
36
|
+
const relations_1 = require("../relations");
|
|
37
|
+
const revisions_1 = require("../revisions");
|
|
38
|
+
const roles_1 = require("../roles");
|
|
39
|
+
const server_1 = require("../server");
|
|
40
|
+
const settings_1 = require("../settings");
|
|
41
|
+
const shares_1 = require("../shares");
|
|
42
|
+
const specifications_1 = require("../specifications");
|
|
43
|
+
const tfa_1 = require("../tfa");
|
|
44
|
+
const users_1 = require("../users");
|
|
45
|
+
const utils_1 = require("../utils");
|
|
46
|
+
const webhooks_1 = require("../webhooks");
|
|
47
|
+
const date_1 = require("./types/date");
|
|
48
|
+
const geojson_1 = require("./types/geojson");
|
|
49
|
+
const string_or_float_1 = require("./types/string-or-float");
|
|
50
|
+
const void_1 = require("./types/void");
|
|
51
|
+
const add_path_to_validation_error_1 = require("./utils/add-path-to-validation-error");
|
|
52
|
+
const validationRules = Array.from(graphql_1.specifiedRules);
|
|
53
|
+
if (env_1.default.GRAPHQL_INTROSPECTION === false) {
|
|
54
|
+
validationRules.push(graphql_1.NoSchemaIntrospectionCustomRule);
|
|
55
|
+
}
|
|
70
56
|
/**
|
|
71
57
|
* These should be ignored in the context of GraphQL, and/or are replaced by a custom resolver (for non-standard structures)
|
|
72
58
|
*/
|
|
@@ -91,16 +77,7 @@ class GraphQLService {
|
|
|
91
77
|
async execute({ document, variables, operationName, contextValue, }) {
|
|
92
78
|
var _a;
|
|
93
79
|
const schema = this.getSchema();
|
|
94
|
-
const validationErrors = (0, graphql_1.validate)(schema, document,
|
|
95
|
-
...graphql_1.specifiedRules,
|
|
96
|
-
(context) => ({
|
|
97
|
-
Field(node) {
|
|
98
|
-
if (env_1.default.GRAPHQL_INTROSPECTION === false && (node.name.value === '__schema' || node.name.value === '__type')) {
|
|
99
|
-
context.reportError(new graphql_1.GraphQLError('GraphQL introspection is not allowed. The query contained __schema or __type.', [node]));
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
}),
|
|
103
|
-
]);
|
|
80
|
+
const validationErrors = (0, graphql_1.validate)(schema, document, validationRules).map((validationError) => (0, add_path_to_validation_error_1.addPathToValidationError)(validationError));
|
|
104
81
|
if (validationErrors.length > 0) {
|
|
105
82
|
throw new exceptions_1.GraphQLValidationException({ graphqlErrors: validationErrors });
|
|
106
83
|
}
|
|
@@ -180,7 +157,7 @@ class GraphQLService {
|
|
|
180
157
|
else {
|
|
181
158
|
schemaComposer.Query.addFields({
|
|
182
159
|
_empty: {
|
|
183
|
-
type: GraphQLVoid,
|
|
160
|
+
type: void_1.GraphQLVoid,
|
|
184
161
|
description: "There's no data to query.",
|
|
185
162
|
},
|
|
186
163
|
});
|
|
@@ -209,6 +186,7 @@ class GraphQLService {
|
|
|
209
186
|
}
|
|
210
187
|
else {
|
|
211
188
|
acc[`update_${collectionName}_items`] = UpdateCollectionTypes[collection.collection].getResolver(`update_${collection.collection}_items`);
|
|
189
|
+
acc[`update_${collectionName}_batch`] = UpdateCollectionTypes[collection.collection].getResolver(`update_${collection.collection}_batch`);
|
|
212
190
|
acc[`update_${collectionName}_item`] = UpdateCollectionTypes[collection.collection].getResolver(`update_${collection.collection}_item`);
|
|
213
191
|
}
|
|
214
192
|
return acc;
|
|
@@ -512,32 +490,33 @@ class GraphQLService {
|
|
|
512
490
|
},
|
|
513
491
|
},
|
|
514
492
|
});
|
|
493
|
+
// Uses StringOrFloat rather than Float to support api dynamic variables (like `$NOW`)
|
|
515
494
|
const NumberFilterOperators = schemaComposer.createInputTC({
|
|
516
495
|
name: 'number_filter_operators',
|
|
517
496
|
fields: {
|
|
518
497
|
_eq: {
|
|
519
|
-
type:
|
|
498
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
520
499
|
},
|
|
521
500
|
_neq: {
|
|
522
|
-
type:
|
|
501
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
523
502
|
},
|
|
524
503
|
_in: {
|
|
525
|
-
type: new graphql_1.GraphQLList(
|
|
504
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
526
505
|
},
|
|
527
506
|
_nin: {
|
|
528
|
-
type: new graphql_1.GraphQLList(
|
|
507
|
+
type: new graphql_1.GraphQLList(string_or_float_1.GraphQLStringOrFloat),
|
|
529
508
|
},
|
|
530
509
|
_gt: {
|
|
531
|
-
type:
|
|
510
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
532
511
|
},
|
|
533
512
|
_gte: {
|
|
534
|
-
type:
|
|
513
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
535
514
|
},
|
|
536
515
|
_lt: {
|
|
537
|
-
type:
|
|
516
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
538
517
|
},
|
|
539
518
|
_lte: {
|
|
540
|
-
type:
|
|
519
|
+
type: string_or_float_1.GraphQLStringOrFloat,
|
|
541
520
|
},
|
|
542
521
|
_null: {
|
|
543
522
|
type: graphql_1.GraphQLBoolean,
|
|
@@ -551,22 +530,22 @@ class GraphQLService {
|
|
|
551
530
|
name: 'geometry_filter_operators',
|
|
552
531
|
fields: {
|
|
553
532
|
_eq: {
|
|
554
|
-
type:
|
|
533
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
555
534
|
},
|
|
556
535
|
_neq: {
|
|
557
|
-
type:
|
|
536
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
558
537
|
},
|
|
559
538
|
_intersects: {
|
|
560
|
-
type:
|
|
539
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
561
540
|
},
|
|
562
541
|
_nintersects: {
|
|
563
|
-
type:
|
|
542
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
564
543
|
},
|
|
565
544
|
_intersects_bbox: {
|
|
566
|
-
type:
|
|
545
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
567
546
|
},
|
|
568
547
|
_nintersects_bbox: {
|
|
569
|
-
type:
|
|
548
|
+
type: geojson_1.GraphQLGeoJSON,
|
|
570
549
|
},
|
|
571
550
|
},
|
|
572
551
|
});
|
|
@@ -637,10 +616,10 @@ class GraphQLService {
|
|
|
637
616
|
case graphql_1.GraphQLFloat:
|
|
638
617
|
filterOperatorType = NumberFilterOperators;
|
|
639
618
|
break;
|
|
640
|
-
case
|
|
619
|
+
case date_1.GraphQLDate:
|
|
641
620
|
filterOperatorType = DateFilterOperators;
|
|
642
621
|
break;
|
|
643
|
-
case
|
|
622
|
+
case geojson_1.GraphQLGeoJSON:
|
|
644
623
|
filterOperatorType = GeometryFilterOperators;
|
|
645
624
|
break;
|
|
646
625
|
default:
|
|
@@ -782,7 +761,7 @@ class GraphQLService {
|
|
|
782
761
|
},
|
|
783
762
|
type: collection.singleton
|
|
784
763
|
? ReadCollectionTypes[collection.collection]
|
|
785
|
-
:
|
|
764
|
+
: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(ReadCollectionTypes[collection.collection].getType()))),
|
|
786
765
|
resolve: async ({ info, context }) => {
|
|
787
766
|
const result = await self.resolveQuery(info);
|
|
788
767
|
context.data = result;
|
|
@@ -791,7 +770,7 @@ class GraphQLService {
|
|
|
791
770
|
});
|
|
792
771
|
ReadCollectionTypes[collection.collection].addResolver({
|
|
793
772
|
name: `${collection.collection}_aggregated`,
|
|
794
|
-
type:
|
|
773
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(AggregatedFunctions[collection.collection].getType()))),
|
|
795
774
|
args: {
|
|
796
775
|
groupBy: new graphql_1.GraphQLList(graphql_1.GraphQLString),
|
|
797
776
|
filter: ReadableCollectionFilterTypes[collection.collection],
|
|
@@ -901,7 +880,9 @@ class GraphQLService {
|
|
|
901
880
|
if (Object.keys(creatableFields).length > 0) {
|
|
902
881
|
CreateCollectionTypes[collection.collection].addResolver({
|
|
903
882
|
name: `create_${collection.collection}_items`,
|
|
904
|
-
type: collectionIsReadable
|
|
883
|
+
type: collectionIsReadable
|
|
884
|
+
? new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(ReadCollectionTypes[collection.collection].getType())))
|
|
885
|
+
: graphql_1.GraphQLBoolean,
|
|
905
886
|
args: collectionIsReadable
|
|
906
887
|
? ReadCollectionTypes[collection.collection].getResolver(collection.collection).getArgs()
|
|
907
888
|
: undefined,
|
|
@@ -949,9 +930,26 @@ class GraphQLService {
|
|
|
949
930
|
});
|
|
950
931
|
}
|
|
951
932
|
else {
|
|
933
|
+
UpdateCollectionTypes[collection.collection].addResolver({
|
|
934
|
+
name: `update_${collection.collection}_batch`,
|
|
935
|
+
type: collectionIsReadable
|
|
936
|
+
? new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(ReadCollectionTypes[collection.collection].getType())))
|
|
937
|
+
: graphql_1.GraphQLBoolean,
|
|
938
|
+
args: {
|
|
939
|
+
...(collectionIsReadable
|
|
940
|
+
? ReadCollectionTypes[collection.collection].getResolver(collection.collection).getArgs()
|
|
941
|
+
: {}),
|
|
942
|
+
data: [
|
|
943
|
+
(0, graphql_compose_1.toInputObjectType)(UpdateCollectionTypes[collection.collection]).setTypeName(`update_${collection.collection}_input`).NonNull,
|
|
944
|
+
],
|
|
945
|
+
},
|
|
946
|
+
resolve: async ({ args, info }) => await self.resolveMutation(args, info),
|
|
947
|
+
});
|
|
952
948
|
UpdateCollectionTypes[collection.collection].addResolver({
|
|
953
949
|
name: `update_${collection.collection}_items`,
|
|
954
|
-
type: collectionIsReadable
|
|
950
|
+
type: collectionIsReadable
|
|
951
|
+
? new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(ReadCollectionTypes[collection.collection].getType())))
|
|
952
|
+
: graphql_1.GraphQLBoolean,
|
|
955
953
|
args: {
|
|
956
954
|
...(collectionIsReadable
|
|
957
955
|
? ReadCollectionTypes[collection.collection].getResolver(collection.collection).getArgs()
|
|
@@ -1065,10 +1063,14 @@ class GraphQLService {
|
|
|
1065
1063
|
collection = `directus_${collection}`;
|
|
1066
1064
|
const selections = this.replaceFragmentsInSelections((_b = (_a = info.fieldNodes[0]) === null || _a === void 0 ? void 0 : _a.selectionSet) === null || _b === void 0 ? void 0 : _b.selections, info.fragments);
|
|
1067
1065
|
const query = this.getQuery(args, selections || [], info.variableValues);
|
|
1068
|
-
const singleton = collection.endsWith('
|
|
1066
|
+
const singleton = collection.endsWith('_batch') === false &&
|
|
1067
|
+
collection.endsWith('_items') === false &&
|
|
1069
1068
|
collection.endsWith('_item') === false &&
|
|
1070
1069
|
collection in this.schema.collections;
|
|
1071
|
-
const single = collection.endsWith('_items') === false;
|
|
1070
|
+
const single = collection.endsWith('_items') === false && collection.endsWith('_batch') === false;
|
|
1071
|
+
const batchUpdate = action === 'update' && collection.endsWith('_batch');
|
|
1072
|
+
if (collection.endsWith('_batch'))
|
|
1073
|
+
collection = collection.slice(0, -6);
|
|
1072
1074
|
if (collection.endsWith('_items'))
|
|
1073
1075
|
collection = collection.slice(0, -6);
|
|
1074
1076
|
if (collection.endsWith('_item'))
|
|
@@ -1099,7 +1101,13 @@ class GraphQLService {
|
|
|
1099
1101
|
return hasQuery ? await service.readMany(keys, query) : true;
|
|
1100
1102
|
}
|
|
1101
1103
|
if (action === 'update') {
|
|
1102
|
-
const keys =
|
|
1104
|
+
const keys = [];
|
|
1105
|
+
if (batchUpdate) {
|
|
1106
|
+
keys.push(...(await service.updateBatch(args.data)));
|
|
1107
|
+
}
|
|
1108
|
+
else {
|
|
1109
|
+
keys.push(...(await service.updateMany(args.ids, args.data)));
|
|
1110
|
+
}
|
|
1103
1111
|
return hasQuery ? await service.readMany(keys, query) : true;
|
|
1104
1112
|
}
|
|
1105
1113
|
if (action === 'delete') {
|
|
@@ -1232,7 +1240,7 @@ class GraphQLService {
|
|
|
1232
1240
|
if (selection.selectionSet) {
|
|
1233
1241
|
if (!query.deep)
|
|
1234
1242
|
query.deep = {};
|
|
1235
|
-
(0, lodash_1.set)(query.deep, parent, (0, lodash_1.merge)((0, lodash_1.get)(query.deep, parent), { _alias: { [selection.alias.value]: selection.name.value } }));
|
|
1243
|
+
(0, lodash_1.set)(query.deep, parent, (0, lodash_1.merge)({}, (0, lodash_1.get)(query.deep, parent), { _alias: { [selection.alias.value]: selection.name.value } }));
|
|
1236
1244
|
}
|
|
1237
1245
|
}
|
|
1238
1246
|
}
|
|
@@ -1261,7 +1269,7 @@ class GraphQLService {
|
|
|
1261
1269
|
if (!query.deep)
|
|
1262
1270
|
query.deep = {};
|
|
1263
1271
|
const args = this.parseArgs(selection.arguments, variableValues);
|
|
1264
|
-
(0, lodash_1.set)(query.deep, currentAlias !== null && currentAlias !== void 0 ? currentAlias : current, (0, lodash_1.merge)((0, lodash_1.get)(query.deep, currentAlias !== null && currentAlias !== void 0 ? currentAlias : current), (0, lodash_1.mapKeys)((0, sanitize_query_1.sanitizeQuery)(args, this.accountability), (value, key) => `_${key}`)));
|
|
1272
|
+
(0, lodash_1.set)(query.deep, currentAlias !== null && currentAlias !== void 0 ? currentAlias : current, (0, lodash_1.merge)({}, (0, lodash_1.get)(query.deep, currentAlias !== null && currentAlias !== void 0 ? currentAlias : current), (0, lodash_1.mapKeys)((0, sanitize_query_1.sanitizeQuery)(args, this.accountability), (value, key) => `_${key}`)));
|
|
1265
1273
|
}
|
|
1266
1274
|
}
|
|
1267
1275
|
}
|
|
@@ -1307,7 +1315,7 @@ class GraphQLService {
|
|
|
1307
1315
|
continue;
|
|
1308
1316
|
const aggregateProperty = aggregationGroup.name.value;
|
|
1309
1317
|
query.aggregate[aggregateProperty] =
|
|
1310
|
-
(_b = (_a = aggregationGroup.selectionSet) === null || _a === void 0 ? void 0 : _a.selections.filter((selectionNode) =>
|
|
1318
|
+
(_b = (_a = aggregationGroup.selectionSet) === null || _a === void 0 ? void 0 : _a.selections.filter((selectionNode) => !(selectionNode === null || selectionNode === void 0 ? void 0 : selectionNode.name.value.startsWith('__'))).map((selectionNode) => {
|
|
1311
1319
|
selectionNode = selectionNode;
|
|
1312
1320
|
return selectionNode.name.value;
|
|
1313
1321
|
})) !== null && _b !== void 0 ? _b : [];
|
|
@@ -1808,7 +1816,7 @@ class GraphQLService {
|
|
|
1808
1816
|
},
|
|
1809
1817
|
},
|
|
1810
1818
|
utils_cache_clear: {
|
|
1811
|
-
type: GraphQLVoid,
|
|
1819
|
+
type: void_1.GraphQLVoid,
|
|
1812
1820
|
resolve: async () => {
|
|
1813
1821
|
var _a;
|
|
1814
1822
|
if (((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true) {
|
|
@@ -1859,7 +1867,7 @@ class GraphQLService {
|
|
|
1859
1867
|
});
|
|
1860
1868
|
schemaComposer.Query.addFields({
|
|
1861
1869
|
collections: {
|
|
1862
|
-
type:
|
|
1870
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(Collection.getType()))),
|
|
1863
1871
|
resolve: async () => {
|
|
1864
1872
|
const collectionsService = new collections_1.CollectionsService({
|
|
1865
1873
|
accountability: this.accountability,
|
|
@@ -1920,7 +1928,7 @@ class GraphQLService {
|
|
|
1920
1928
|
});
|
|
1921
1929
|
schemaComposer.Query.addFields({
|
|
1922
1930
|
fields: {
|
|
1923
|
-
type:
|
|
1931
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(Field.getType()))),
|
|
1924
1932
|
resolve: async () => {
|
|
1925
1933
|
const service = new fields_1.FieldsService({
|
|
1926
1934
|
accountability: this.accountability,
|
|
@@ -1930,7 +1938,7 @@ class GraphQLService {
|
|
|
1930
1938
|
},
|
|
1931
1939
|
},
|
|
1932
1940
|
fields_in_collection: {
|
|
1933
|
-
type:
|
|
1941
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(Field.getType()))),
|
|
1934
1942
|
args: {
|
|
1935
1943
|
collection: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
|
|
1936
1944
|
},
|
|
@@ -1988,7 +1996,7 @@ class GraphQLService {
|
|
|
1988
1996
|
});
|
|
1989
1997
|
schemaComposer.Query.addFields({
|
|
1990
1998
|
relations: {
|
|
1991
|
-
type:
|
|
1999
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(Relation.getType()))),
|
|
1992
2000
|
resolve: async () => {
|
|
1993
2001
|
const service = new relations_1.RelationsService({
|
|
1994
2002
|
accountability: this.accountability,
|
|
@@ -1998,7 +2006,7 @@ class GraphQLService {
|
|
|
1998
2006
|
},
|
|
1999
2007
|
},
|
|
2000
2008
|
relations_in_collection: {
|
|
2001
|
-
type:
|
|
2009
|
+
type: new graphql_1.GraphQLNonNull(new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(Relation.getType()))),
|
|
2002
2010
|
args: {
|
|
2003
2011
|
collection: (0, graphql_1.GraphQLNonNull)(graphql_1.GraphQLString),
|
|
2004
2012
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLDate = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
exports.GraphQLDate = new graphql_1.GraphQLScalarType({
|
|
6
|
+
...graphql_1.GraphQLString,
|
|
7
|
+
name: 'Date',
|
|
8
|
+
description: 'ISO8601 Date values',
|
|
9
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLGeoJSON = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const graphql_compose_1 = require("graphql-compose");
|
|
6
|
+
exports.GraphQLGeoJSON = new graphql_1.GraphQLScalarType({
|
|
7
|
+
...graphql_compose_1.GraphQLJSON,
|
|
8
|
+
name: 'GraphQLGeoJSON',
|
|
9
|
+
description: 'GeoJSON value',
|
|
10
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLStringOrFloat = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
/**
|
|
6
|
+
* Adopted from https://kamranicus.com/handling-multiple-scalar-types-in-graphql/
|
|
7
|
+
*/
|
|
8
|
+
exports.GraphQLStringOrFloat = new graphql_1.GraphQLScalarType({
|
|
9
|
+
name: 'GraphQLStringOrFloat',
|
|
10
|
+
description: 'A Float or a String',
|
|
11
|
+
serialize(value) {
|
|
12
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
13
|
+
throw new Error('Value must be either a String or a Float');
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
},
|
|
17
|
+
parseValue(value) {
|
|
18
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
19
|
+
throw new Error('Value must be either a String or a Float');
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
},
|
|
23
|
+
parseLiteral(ast) {
|
|
24
|
+
switch (ast.kind) {
|
|
25
|
+
case graphql_1.Kind.INT:
|
|
26
|
+
case graphql_1.Kind.FLOAT:
|
|
27
|
+
return Number(ast.value);
|
|
28
|
+
case graphql_1.Kind.STRING:
|
|
29
|
+
return ast.value;
|
|
30
|
+
default:
|
|
31
|
+
throw new Error('Value must be either a String or a Float');
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLVoid = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
exports.GraphQLVoid = new graphql_1.GraphQLScalarType({
|
|
6
|
+
name: 'Void',
|
|
7
|
+
description: 'Represents NULL values',
|
|
8
|
+
serialize() {
|
|
9
|
+
return null;
|
|
10
|
+
},
|
|
11
|
+
parseValue() {
|
|
12
|
+
return null;
|
|
13
|
+
},
|
|
14
|
+
parseLiteral() {
|
|
15
|
+
return null;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addPathToValidationError = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function addPathToValidationError(validationError) {
|
|
6
|
+
var _a, _b, _c;
|
|
7
|
+
const token = (_c = (_b = (_a = validationError.nodes) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.loc) === null || _c === void 0 ? void 0 : _c.startToken;
|
|
8
|
+
if (!token)
|
|
9
|
+
return validationError;
|
|
10
|
+
let prev = token;
|
|
11
|
+
const queryRegex = /query_[A-Za-z0-9]{8}/;
|
|
12
|
+
while (prev) {
|
|
13
|
+
if (prev.kind === 'Name' && prev.value && queryRegex.test(prev.value)) {
|
|
14
|
+
return (0, graphql_1.locatedError)(validationError, validationError.nodes, [prev.value]);
|
|
15
|
+
}
|
|
16
|
+
prev = prev.prev;
|
|
17
|
+
}
|
|
18
|
+
return (0, graphql_1.locatedError)(validationError, validationError.nodes);
|
|
19
|
+
}
|
|
20
|
+
exports.addPathToValidationError = addPathToValidationError;
|
|
@@ -20,7 +20,6 @@ const env_1 = __importDefault(require("../env"));
|
|
|
20
20
|
const exceptions_1 = require("../exceptions");
|
|
21
21
|
const logger_1 = __importDefault(require("../logger"));
|
|
22
22
|
const get_date_formatted_1 = require("../utils/get-date-formatted");
|
|
23
|
-
const parse_json_1 = require("../utils/parse-json");
|
|
24
23
|
const files_1 = require("./files");
|
|
25
24
|
const items_1 = require("./items");
|
|
26
25
|
const notifications_1 = require("./notifications");
|
|
@@ -31,12 +30,12 @@ class ImportService {
|
|
|
31
30
|
this.schema = options.schema;
|
|
32
31
|
}
|
|
33
32
|
async import(collection, mimetype, stream) {
|
|
34
|
-
var _a, _b, _c, _d, _e;
|
|
35
|
-
if (collection.startsWith('directus_'))
|
|
33
|
+
var _a, _b, _c, _d, _e, _f;
|
|
34
|
+
if (((_a = this.accountability) === null || _a === void 0 ? void 0 : _a.admin) !== true && collection.startsWith('directus_'))
|
|
36
35
|
throw new exceptions_1.ForbiddenException();
|
|
37
|
-
const createPermissions = (
|
|
38
|
-
const updatePermissions = (
|
|
39
|
-
if (((
|
|
36
|
+
const createPermissions = (_c = (_b = this.accountability) === null || _b === void 0 ? void 0 : _b.permissions) === null || _c === void 0 ? void 0 : _c.find((permission) => permission.collection === collection && permission.action === 'create');
|
|
37
|
+
const updatePermissions = (_e = (_d = this.accountability) === null || _d === void 0 ? void 0 : _d.permissions) === null || _e === void 0 ? void 0 : _e.find((permission) => permission.collection === collection && permission.action === 'update');
|
|
38
|
+
if (((_f = this.accountability) === null || _f === void 0 ? void 0 : _f.admin) !== true && (!createPermissions || !updatePermissions)) {
|
|
40
39
|
throw new exceptions_1.ForbiddenException();
|
|
41
40
|
}
|
|
42
41
|
switch (mimetype) {
|
|
@@ -102,8 +101,13 @@ class ImportService {
|
|
|
102
101
|
}
|
|
103
102
|
else {
|
|
104
103
|
try {
|
|
105
|
-
const parsedJson = (0,
|
|
106
|
-
|
|
104
|
+
const parsedJson = (0, utils_1.parseJSON)(value);
|
|
105
|
+
if (typeof parsedJson === 'number') {
|
|
106
|
+
(0, lodash_1.set)(result, key, value);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
(0, lodash_1.set)(result, key, parsedJson);
|
|
110
|
+
}
|
|
107
111
|
}
|
|
108
112
|
catch {
|
|
109
113
|
(0, lodash_1.set)(result, key, value);
|
package/dist/services/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|