@directus/api 19.3.1 → 20.0.0-rc.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/app.js +4 -4
- package/dist/auth/drivers/ldap.js +4 -4
- package/dist/auth/drivers/local.js +4 -4
- package/dist/auth/drivers/oauth2.js +4 -4
- package/dist/auth/drivers/openid.js +2 -4
- package/dist/cache.js +3 -0
- package/dist/cli/commands/bootstrap/index.js +8 -2
- package/dist/cli/commands/init/index.js +9 -10
- package/dist/cli/utils/defaults.d.ts +4 -11
- package/dist/cli/utils/defaults.js +7 -1
- package/dist/constants.d.ts +1 -1
- package/dist/controllers/access.d.ts +2 -0
- package/dist/controllers/access.js +148 -0
- package/dist/controllers/auth.js +5 -16
- package/dist/controllers/permissions.js +14 -2
- package/dist/controllers/policies.d.ts +2 -0
- package/dist/controllers/policies.js +169 -0
- package/dist/controllers/roles.js +22 -1
- package/dist/controllers/users.js +0 -55
- package/dist/database/errors/dialects/mysql.js +23 -23
- package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +16 -0
- package/dist/database/get-ast-from-query/get-ast-from-query.js +82 -0
- package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +13 -0
- package/dist/database/get-ast-from-query/lib/convert-wildcards.js +69 -0
- package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +15 -0
- package/dist/database/get-ast-from-query/lib/parse-fields.js +190 -0
- package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +14 -0
- package/dist/database/get-ast-from-query/utils/get-deep-query.js +17 -0
- package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +2 -0
- package/dist/database/get-ast-from-query/utils/get-related-collection.js +13 -0
- package/dist/database/get-ast-from-query/utils/get-relation.d.ts +2 -0
- package/dist/database/get-ast-from-query/utils/get-relation.js +7 -0
- package/dist/database/helpers/fn/types.d.ts +2 -1
- package/dist/database/helpers/fn/types.js +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.js +4 -2
- package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.js +5 -3
- package/dist/database/helpers/geometry/types.d.ts +1 -1
- package/dist/database/helpers/geometry/types.js +4 -2
- package/dist/database/index.js +2 -1
- package/dist/database/migrations/20240619A-permissions-policies.d.ts +3 -0
- package/dist/database/migrations/20240619A-permissions-policies.js +163 -0
- package/dist/database/run-ast/lib/get-db-query.d.ts +4 -0
- package/dist/database/run-ast/lib/get-db-query.js +194 -0
- package/dist/database/run-ast/lib/parse-current-level.d.ts +7 -0
- package/dist/database/run-ast/lib/parse-current-level.js +41 -0
- package/dist/database/run-ast/run-ast.d.ts +7 -0
- package/dist/database/run-ast/run-ast.js +107 -0
- package/dist/database/{run-ast.d.ts → run-ast/types.d.ts} +3 -9
- package/dist/database/run-ast/types.js +1 -0
- package/dist/database/run-ast/utils/apply-case-when.d.ts +16 -0
- package/dist/database/run-ast/utils/apply-case-when.js +26 -0
- package/dist/database/run-ast/utils/apply-parent-filters.d.ts +3 -0
- package/dist/database/run-ast/utils/apply-parent-filters.js +55 -0
- package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +10 -0
- package/dist/database/run-ast/utils/get-column-pre-processor.js +57 -0
- package/dist/database/run-ast/utils/get-field-alias.d.ts +2 -0
- package/dist/database/run-ast/utils/get-field-alias.js +4 -0
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +5 -0
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +23 -0
- package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +3 -0
- package/dist/database/run-ast/utils/merge-with-parent-items.js +87 -0
- package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +3 -0
- package/dist/database/run-ast/utils/remove-temporary-fields.js +73 -0
- package/dist/extensions/lib/sandbox/generate-api-extensions-sandbox-entrypoint.d.ts +1 -1
- package/dist/flows.js +3 -4
- package/dist/middleware/authenticate.js +2 -7
- package/dist/middleware/cache.js +1 -1
- package/dist/middleware/cors.js +4 -4
- package/dist/middleware/respond.js +1 -1
- package/dist/permissions/cache.d.ts +2 -0
- package/dist/permissions/cache.js +23 -0
- package/dist/permissions/lib/fetch-permissions.d.ts +10 -0
- package/dist/permissions/lib/fetch-permissions.js +55 -0
- package/dist/permissions/lib/fetch-policies.d.ts +7 -0
- package/dist/permissions/lib/fetch-policies.js +28 -0
- package/dist/permissions/lib/fetch-roles-tree.d.ts +3 -0
- package/dist/permissions/lib/fetch-roles-tree.js +28 -0
- package/dist/{services/permissions → permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
- package/dist/permissions/lib/with-app-minimal-permissions.js +10 -0
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +7 -0
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +56 -0
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +3 -0
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +16 -0
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +8 -0
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +24 -0
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +9 -0
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +31 -0
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +16 -0
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +27 -0
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +10 -0
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +23 -0
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +5 -0
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +7 -0
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +5 -0
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +10 -0
- package/dist/permissions/modules/fetch-global-access/types.d.ts +4 -0
- package/dist/permissions/modules/fetch-global-access/types.js +1 -0
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +4 -0
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +27 -0
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +12 -0
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +32 -0
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +4 -0
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +29 -0
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +4 -0
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +49 -0
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +3 -0
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +56 -0
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +4 -0
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +8 -0
- package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +9 -0
- package/dist/permissions/modules/process-ast/lib/inject-cases.js +93 -0
- package/dist/permissions/modules/process-ast/process-ast.d.ts +9 -0
- package/dist/permissions/modules/process-ast/process-ast.js +39 -0
- package/dist/permissions/modules/process-ast/types.d.ts +24 -0
- package/dist/permissions/modules/process-ast/types.js +1 -0
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +2 -0
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +7 -0
- package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +12 -0
- package/dist/permissions/modules/process-ast/utils/dedupe-access.js +30 -0
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +15 -0
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +50 -0
- package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +3 -0
- package/dist/permissions/modules/process-ast/utils/find-related-collection.js +9 -0
- package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +3 -0
- package/dist/permissions/modules/process-ast/utils/flatten-filter.js +24 -0
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +1 -0
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +3 -0
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +5 -0
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +7 -0
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +2 -0
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +3 -0
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +2 -0
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +3 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +3 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +16 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +2 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +12 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +2 -0
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +28 -0
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +5 -0
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +12 -0
- package/dist/permissions/modules/process-payload/process-payload.d.ts +13 -0
- package/dist/permissions/modules/process-payload/process-payload.js +77 -0
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +12 -0
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +11 -0
- package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +9 -0
- package/dist/permissions/modules/validate-access/lib/validate-item-access.js +33 -0
- package/dist/permissions/modules/validate-access/validate-access.d.ts +14 -0
- package/dist/permissions/modules/validate-access/validate-access.js +28 -0
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +1 -0
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +8 -0
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +5 -0
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +10 -0
- package/dist/permissions/types.d.ts +6 -0
- package/dist/permissions/types.js +1 -0
- package/dist/permissions/utils/create-default-accountability.d.ts +2 -0
- package/dist/permissions/utils/create-default-accountability.js +11 -0
- package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +8 -0
- package/dist/permissions/utils/extract-required-dynamic-variable-context.js +27 -0
- package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +9 -0
- package/dist/permissions/utils/fetch-dynamic-variable-context.js +43 -0
- package/dist/permissions/utils/filter-policies-by-ip.d.ts +2 -0
- package/dist/permissions/utils/filter-policies-by-ip.js +15 -0
- package/dist/permissions/utils/get-unaliased-field-key.d.ts +5 -0
- package/dist/permissions/utils/get-unaliased-field-key.js +17 -0
- package/dist/permissions/utils/process-permissions.d.ts +7 -0
- package/dist/permissions/utils/process-permissions.js +9 -0
- package/dist/permissions/utils/with-cache.d.ts +10 -0
- package/dist/permissions/utils/with-cache.js +25 -0
- package/dist/services/access.d.ts +10 -0
- package/dist/services/access.js +43 -0
- package/dist/services/activity.js +22 -10
- package/dist/services/assets.d.ts +2 -3
- package/dist/services/assets.js +10 -5
- package/dist/services/authentication.js +18 -18
- package/dist/services/collections.js +18 -17
- package/dist/services/fields.d.ts +0 -1
- package/dist/services/fields.js +53 -24
- package/dist/services/files.d.ts +0 -4
- package/dist/services/files.js +10 -10
- package/dist/services/flows.d.ts +0 -2
- package/dist/services/flows.js +2 -14
- package/dist/services/graphql/index.d.ts +3 -3
- package/dist/services/graphql/index.js +126 -22
- package/dist/services/graphql/subscription.js +2 -4
- package/dist/services/import-export.js +23 -9
- package/dist/services/index.d.ts +3 -2
- package/dist/services/index.js +3 -2
- package/dist/services/items.d.ts +40 -14
- package/dist/services/items.js +182 -79
- package/dist/services/meta.js +60 -23
- package/dist/services/notifications.d.ts +0 -1
- package/dist/services/notifications.js +0 -7
- package/dist/services/operations.d.ts +0 -2
- package/dist/services/operations.js +2 -14
- package/dist/services/payload.d.ts +9 -10
- package/dist/services/payload.js +35 -19
- package/dist/services/{permissions/index.d.ts → permissions.d.ts} +5 -7
- package/dist/services/{permissions/index.js → permissions.js} +30 -54
- package/dist/services/policies.d.ts +12 -0
- package/dist/services/policies.js +87 -0
- package/dist/services/relations.d.ts +0 -6
- package/dist/services/relations.js +26 -29
- package/dist/services/roles.d.ts +4 -14
- package/dist/services/roles.js +56 -430
- package/dist/services/shares.d.ts +0 -2
- package/dist/services/shares.js +12 -8
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/specifications.js +39 -27
- package/dist/services/users.d.ts +2 -20
- package/dist/services/users.js +87 -192
- package/dist/services/utils.js +11 -7
- package/dist/services/versions.d.ts +0 -2
- package/dist/services/versions.js +34 -10
- package/dist/telemetry/lib/get-report.js +6 -3
- package/dist/telemetry/types/report.d.ts +4 -0
- package/dist/telemetry/utils/check-user-limits.d.ts +5 -0
- package/dist/telemetry/utils/check-user-limits.js +19 -0
- package/dist/telemetry/utils/get-filesize-sum.d.ts +5 -0
- package/dist/telemetry/utils/get-filesize-sum.js +7 -0
- package/dist/types/ast.d.ts +43 -1
- package/dist/types/items.d.ts +11 -0
- package/dist/utils/apply-query.d.ts +4 -3
- package/dist/utils/apply-query.js +37 -8
- package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +17 -0
- package/dist/utils/fetch-user-count/fetch-access-lookup.js +22 -0
- package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +16 -0
- package/dist/utils/fetch-user-count/fetch-access-roles.js +37 -0
- package/dist/utils/fetch-user-count/fetch-active-users.d.ts +6 -0
- package/dist/utils/fetch-user-count/fetch-active-users.js +3 -0
- package/dist/utils/fetch-user-count/fetch-user-count.d.ts +12 -0
- package/dist/utils/fetch-user-count/fetch-user-count.js +57 -0
- package/dist/utils/fetch-user-count/get-user-count-query.d.ts +20 -0
- package/dist/utils/fetch-user-count/get-user-count-query.js +17 -0
- package/dist/utils/get-accountability-for-role.js +16 -25
- package/dist/utils/get-accountability-for-token.js +17 -16
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +12 -1
- package/dist/utils/get-column.d.ts +2 -1
- package/dist/utils/get-column.js +1 -0
- package/dist/utils/get-graphql-type.js +1 -0
- package/dist/utils/get-service.d.ts +1 -1
- package/dist/utils/get-service.js +14 -10
- package/dist/utils/reduce-schema.d.ts +4 -6
- package/dist/utils/reduce-schema.js +14 -34
- package/dist/utils/validate-user-count-integrity.d.ts +13 -0
- package/dist/utils/validate-user-count-integrity.js +29 -0
- package/dist/websocket/authenticate.d.ts +0 -2
- package/dist/websocket/authenticate.js +0 -12
- package/dist/websocket/controllers/graphql.js +1 -4
- package/dist/websocket/controllers/hooks.js +4 -0
- package/dist/websocket/controllers/rest.js +0 -2
- package/dist/websocket/handlers/subscribe.js +0 -2
- package/dist/websocket/utils/items.d.ts +1 -1
- package/dist/websocket/utils/items.js +4 -1
- package/package.json +31 -30
- package/dist/database/run-ast.js +0 -450
- package/dist/middleware/check-ip.d.ts +0 -2
- package/dist/middleware/check-ip.js +0 -37
- package/dist/middleware/get-permissions.d.ts +0 -3
- package/dist/middleware/get-permissions.js +0 -10
- package/dist/services/authorization.d.ts +0 -17
- package/dist/services/authorization.js +0 -456
- package/dist/services/permissions/lib/with-app-minimal-permissions.js +0 -13
- package/dist/telemetry/utils/check-increased-user-limits.d.ts +0 -7
- package/dist/telemetry/utils/check-increased-user-limits.js +0 -22
- package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +0 -6
- package/dist/telemetry/utils/get-role-counts-by-roles.js +0 -27
- package/dist/telemetry/utils/get-role-counts-by-users.d.ts +0 -11
- package/dist/telemetry/utils/get-role-counts-by-users.js +0 -34
- package/dist/telemetry/utils/get-user-count.d.ts +0 -8
- package/dist/telemetry/utils/get-user-count.js +0 -33
- package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +0 -7
- package/dist/telemetry/utils/get-user-counts-by-roles.js +0 -35
- package/dist/utils/get-ast-from-query.d.ts +0 -13
- package/dist/utils/get-ast-from-query.js +0 -297
- package/dist/utils/get-permissions.d.ts +0 -2
- package/dist/utils/get-permissions.js +0 -150
- package/dist/utils/merge-permissions-for-share.d.ts +0 -4
- package/dist/utils/merge-permissions-for-share.js +0 -109
- package/dist/utils/merge-permissions.d.ts +0 -3
- package/dist/utils/merge-permissions.js +0 -95
|
@@ -11,6 +11,9 @@ import { clearSystemCache, getCache } from '../../cache.js';
|
|
|
11
11
|
import { DEFAULT_AUTH_PROVIDER, GENERATE_SPECIAL, REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS, } from '../../constants.js';
|
|
12
12
|
import getDatabase from '../../database/index.js';
|
|
13
13
|
import { rateLimiter } from '../../middleware/rate-limiter-registration.js';
|
|
14
|
+
import { fetchAllowedFieldMap } from '../../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
|
|
15
|
+
import { fetchInconsistentFieldMap } from '../../permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js';
|
|
16
|
+
import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
|
|
14
17
|
import { generateHash } from '../../utils/generate-hash.js';
|
|
15
18
|
import { getGraphQLType } from '../../utils/get-graphql-type.js';
|
|
16
19
|
import { getIPFromReq } from '../../utils/get-ip-from-req.js';
|
|
@@ -48,6 +51,9 @@ import { GraphQLVoid } from './types/void.js';
|
|
|
48
51
|
import { addPathToValidationError } from './utils/add-path-to-validation-error.js';
|
|
49
52
|
import processError from './utils/process-error.js';
|
|
50
53
|
import { sanitizeGraphqlSchema } from './utils/sanitize-gql-schema.js';
|
|
54
|
+
import { fetchAccountabilityCollectionAccess } from '../../permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js';
|
|
55
|
+
import { fetchAccountabilityPolicyGlobals } from '../../permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js';
|
|
56
|
+
import { RolesService } from '../roles.js';
|
|
51
57
|
const env = useEnv();
|
|
52
58
|
const validationRules = Array.from(specifiedRules);
|
|
53
59
|
if (env['GRAPHQL_INTROSPECTION'] === false) {
|
|
@@ -80,7 +86,7 @@ export class GraphQLService {
|
|
|
80
86
|
* Execute a GraphQL structure
|
|
81
87
|
*/
|
|
82
88
|
async execute({ document, variables, operationName, contextValue, }) {
|
|
83
|
-
const schema = this.getSchema();
|
|
89
|
+
const schema = await this.getSchema();
|
|
84
90
|
const validationErrors = validate(schema, document, validationRules).map((validationError) => addPathToValidationError(validationError));
|
|
85
91
|
if (validationErrors.length > 0) {
|
|
86
92
|
throw new GraphQLValidationError({ errors: validationErrors });
|
|
@@ -108,7 +114,7 @@ export class GraphQLService {
|
|
|
108
114
|
formattedResult.extensions = result['extensions'];
|
|
109
115
|
return formattedResult;
|
|
110
116
|
}
|
|
111
|
-
getSchema(type = 'schema') {
|
|
117
|
+
async getSchema(type = 'schema') {
|
|
112
118
|
const key = `${this.scope}_${type}_${this.accountability?.role}_${this.accountability?.user}`;
|
|
113
119
|
const cachedSchema = cache.get(key);
|
|
114
120
|
if (cachedSchema)
|
|
@@ -116,20 +122,53 @@ export class GraphQLService {
|
|
|
116
122
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
117
123
|
const self = this;
|
|
118
124
|
const schemaComposer = new SchemaComposer();
|
|
125
|
+
let schema;
|
|
119
126
|
const sanitizedSchema = sanitizeGraphqlSchema(this.schema);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
if (!this.accountability || this.accountability.admin) {
|
|
128
|
+
schema = {
|
|
129
|
+
read: sanitizedSchema,
|
|
130
|
+
create: sanitizedSchema,
|
|
131
|
+
update: sanitizedSchema,
|
|
132
|
+
delete: sanitizedSchema,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
schema = {
|
|
137
|
+
read: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
|
|
138
|
+
accountability: this.accountability,
|
|
139
|
+
action: 'read',
|
|
140
|
+
}, { schema: this.schema, knex: this.knex })),
|
|
141
|
+
create: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
|
|
142
|
+
accountability: this.accountability,
|
|
143
|
+
action: 'create',
|
|
144
|
+
}, { schema: this.schema, knex: this.knex })),
|
|
145
|
+
update: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
|
|
146
|
+
accountability: this.accountability,
|
|
147
|
+
action: 'update',
|
|
148
|
+
}, { schema: this.schema, knex: this.knex })),
|
|
149
|
+
delete: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
|
|
150
|
+
accountability: this.accountability,
|
|
151
|
+
action: 'delete',
|
|
152
|
+
}, { schema: this.schema, knex: this.knex })),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const inconsistentFields = {
|
|
156
|
+
read: await fetchInconsistentFieldMap({
|
|
157
|
+
accountability: this.accountability,
|
|
158
|
+
action: 'read',
|
|
159
|
+
}, { schema: this.schema, knex: this.knex }),
|
|
160
|
+
create: await fetchInconsistentFieldMap({
|
|
161
|
+
accountability: this.accountability,
|
|
162
|
+
action: 'create',
|
|
163
|
+
}, { schema: this.schema, knex: this.knex }),
|
|
164
|
+
update: await fetchInconsistentFieldMap({
|
|
165
|
+
accountability: this.accountability,
|
|
166
|
+
action: 'update',
|
|
167
|
+
}, { schema: this.schema, knex: this.knex }),
|
|
168
|
+
delete: await fetchInconsistentFieldMap({
|
|
169
|
+
accountability: this.accountability,
|
|
170
|
+
action: 'delete',
|
|
171
|
+
}, { schema: this.schema, knex: this.knex }),
|
|
133
172
|
};
|
|
134
173
|
const subscriptionEventType = schemaComposer.createEnumTC({
|
|
135
174
|
name: 'EventEnum',
|
|
@@ -300,16 +339,18 @@ export class GraphQLService {
|
|
|
300
339
|
name: action === 'read' ? collection.collection : `${action}_${collection.collection}`,
|
|
301
340
|
fields: Object.values(collection.fields).reduce((acc, field) => {
|
|
302
341
|
let type = getGraphQLType(field.type, field.special);
|
|
342
|
+
const fieldIsInconsistent = inconsistentFields[action][collection.collection]?.includes(field.field);
|
|
303
343
|
// GraphQL doesn't differentiate between not-null and has-to-be-submitted. We
|
|
304
344
|
// can't non-null in update, as that would require every not-nullable field to be
|
|
305
345
|
// submitted on updates
|
|
306
346
|
if (field.nullable === false &&
|
|
307
347
|
!field.defaultValue &&
|
|
308
348
|
!GENERATE_SPECIAL.some((flag) => field.special.includes(flag)) &&
|
|
349
|
+
fieldIsInconsistent === false &&
|
|
309
350
|
action !== 'update') {
|
|
310
351
|
type = new GraphQLNonNull(type);
|
|
311
352
|
}
|
|
312
|
-
if (collection.primary === field.field) {
|
|
353
|
+
if (collection.primary === field.field && fieldIsInconsistent === false) {
|
|
313
354
|
// permissions IDs need to be nullable https://github.com/directus/directus/issues/20509
|
|
314
355
|
if (collection.collection === 'directus_permissions') {
|
|
315
356
|
type = GraphQLID;
|
|
@@ -1762,7 +1803,7 @@ export class GraphQLService {
|
|
|
1762
1803
|
accountability: this.accountability,
|
|
1763
1804
|
scope: args['scope'] ?? 'items',
|
|
1764
1805
|
});
|
|
1765
|
-
return service.getSchema('sdl');
|
|
1806
|
+
return await service.getSchema('sdl');
|
|
1766
1807
|
},
|
|
1767
1808
|
},
|
|
1768
1809
|
server_ping: {
|
|
@@ -1815,7 +1856,7 @@ export class GraphQLService {
|
|
|
1815
1856
|
otp: GraphQLString,
|
|
1816
1857
|
},
|
|
1817
1858
|
resolve: async (_, args, { req, res }) => {
|
|
1818
|
-
const accountability =
|
|
1859
|
+
const accountability = createDefaultAccountability();
|
|
1819
1860
|
if (req?.ip)
|
|
1820
1861
|
accountability.ip = req.ip;
|
|
1821
1862
|
const userAgent = req?.get('user-agent');
|
|
@@ -1855,7 +1896,7 @@ export class GraphQLService {
|
|
|
1855
1896
|
mode: AuthMode,
|
|
1856
1897
|
},
|
|
1857
1898
|
resolve: async (_, args, { req, res }) => {
|
|
1858
|
-
const accountability =
|
|
1899
|
+
const accountability = createDefaultAccountability();
|
|
1859
1900
|
if (req?.ip)
|
|
1860
1901
|
accountability.ip = req.ip;
|
|
1861
1902
|
const userAgent = req?.get('user-agent');
|
|
@@ -1913,7 +1954,7 @@ export class GraphQLService {
|
|
|
1913
1954
|
mode: AuthMode,
|
|
1914
1955
|
},
|
|
1915
1956
|
resolve: async (_, args, { req, res }) => {
|
|
1916
|
-
const accountability =
|
|
1957
|
+
const accountability = createDefaultAccountability();
|
|
1917
1958
|
if (req?.ip)
|
|
1918
1959
|
accountability.ip = req.ip;
|
|
1919
1960
|
const userAgent = req?.get('user-agent');
|
|
@@ -1963,7 +2004,7 @@ export class GraphQLService {
|
|
|
1963
2004
|
reset_url: GraphQLString,
|
|
1964
2005
|
},
|
|
1965
2006
|
resolve: async (_, args, { req }) => {
|
|
1966
|
-
const accountability =
|
|
2007
|
+
const accountability = createDefaultAccountability();
|
|
1967
2008
|
if (req?.ip)
|
|
1968
2009
|
accountability.ip = req.ip;
|
|
1969
2010
|
const userAgent = req?.get('user-agent');
|
|
@@ -1991,7 +2032,7 @@ export class GraphQLService {
|
|
|
1991
2032
|
password: new GraphQLNonNull(GraphQLString),
|
|
1992
2033
|
},
|
|
1993
2034
|
resolve: async (_, args, { req }) => {
|
|
1994
|
-
const accountability =
|
|
2035
|
+
const accountability = createDefaultAccountability();
|
|
1995
2036
|
if (req?.ip)
|
|
1996
2037
|
accountability.ip = req.ip;
|
|
1997
2038
|
const userAgent = req?.get('user-agent');
|
|
@@ -2632,6 +2673,69 @@ export class GraphQLService {
|
|
|
2632
2673
|
},
|
|
2633
2674
|
});
|
|
2634
2675
|
}
|
|
2676
|
+
if ('directus_permissions' in schema.read.collections) {
|
|
2677
|
+
schemaComposer.Query.addFields({
|
|
2678
|
+
permissions_me: {
|
|
2679
|
+
type: schemaComposer.createScalarTC({
|
|
2680
|
+
name: 'permissions_me_type',
|
|
2681
|
+
parseValue: (value) => value,
|
|
2682
|
+
serialize: (value) => value,
|
|
2683
|
+
}),
|
|
2684
|
+
resolve: async (_, _args, __, _info) => {
|
|
2685
|
+
if (!this.accountability?.user && !this.accountability?.role)
|
|
2686
|
+
return null;
|
|
2687
|
+
const result = await fetchAccountabilityCollectionAccess(this.accountability, {
|
|
2688
|
+
schema: this.schema,
|
|
2689
|
+
knex: getDatabase(),
|
|
2690
|
+
});
|
|
2691
|
+
return result;
|
|
2692
|
+
},
|
|
2693
|
+
},
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
if ('directus_roles' in schema.read.collections) {
|
|
2697
|
+
schemaComposer.Query.addFields({
|
|
2698
|
+
roles_me: {
|
|
2699
|
+
type: ReadCollectionTypes['directus_roles'].List,
|
|
2700
|
+
resolve: async (_, args, __, info) => {
|
|
2701
|
+
if (!this.accountability?.user && !this.accountability?.role)
|
|
2702
|
+
return null;
|
|
2703
|
+
const service = new RolesService({
|
|
2704
|
+
accountability: this.accountability,
|
|
2705
|
+
schema: this.schema,
|
|
2706
|
+
});
|
|
2707
|
+
const selections = this.replaceFragmentsInSelections(info.fieldNodes[0]?.selectionSet?.selections, info.fragments);
|
|
2708
|
+
const query = this.getQuery(args, selections || [], info.variableValues);
|
|
2709
|
+
query.limit = -1;
|
|
2710
|
+
const roles = await service.readMany(this.accountability.roles, query);
|
|
2711
|
+
return roles;
|
|
2712
|
+
},
|
|
2713
|
+
},
|
|
2714
|
+
});
|
|
2715
|
+
}
|
|
2716
|
+
if ('directus_policies' in schema.read.collections) {
|
|
2717
|
+
schemaComposer.Query.addFields({
|
|
2718
|
+
policies_me_globals: {
|
|
2719
|
+
type: schemaComposer.createObjectTC({
|
|
2720
|
+
name: 'policy_me_globals_type',
|
|
2721
|
+
fields: {
|
|
2722
|
+
enforce_tfa: 'Boolean',
|
|
2723
|
+
app_access: 'Boolean',
|
|
2724
|
+
admin_access: 'Boolean',
|
|
2725
|
+
},
|
|
2726
|
+
}),
|
|
2727
|
+
resolve: async (_, _args, __, _info) => {
|
|
2728
|
+
if (!this.accountability?.user && !this.accountability?.role)
|
|
2729
|
+
return null;
|
|
2730
|
+
const result = await fetchAccountabilityPolicyGlobals(this.accountability, {
|
|
2731
|
+
schema: this.schema,
|
|
2732
|
+
knex: getDatabase(),
|
|
2733
|
+
});
|
|
2734
|
+
return result;
|
|
2735
|
+
},
|
|
2736
|
+
},
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2635
2739
|
if ('directus_users' in schema.update.collections && this.accountability?.user) {
|
|
2636
2740
|
schemaComposer.Mutation.addFields({
|
|
2637
2741
|
update_users_me: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EventEmitter, on } from 'events';
|
|
2
2
|
import { useBus } from '../../bus/index.js';
|
|
3
3
|
import { getSchema } from '../../utils/get-schema.js';
|
|
4
|
-
import { refreshAccountability } from '../../websocket/authenticate.js';
|
|
5
4
|
import { getPayload } from '../../websocket/utils/items.js';
|
|
6
5
|
const messages = createPubSub(new EventEmitter());
|
|
7
6
|
export function bindPubSub() {
|
|
@@ -19,7 +18,6 @@ export function createSubscriptionGenerator(self, event) {
|
|
|
19
18
|
if ('event' in args && eventData['action'] !== args['event']) {
|
|
20
19
|
continue; // skip filtered events
|
|
21
20
|
}
|
|
22
|
-
const accountability = await refreshAccountability(self.accountability);
|
|
23
21
|
const schema = await getSchema();
|
|
24
22
|
const subscription = {
|
|
25
23
|
collection: eventData['collection'],
|
|
@@ -35,7 +33,7 @@ export function createSubscriptionGenerator(self, event) {
|
|
|
35
33
|
if (eventData['action'] === 'create') {
|
|
36
34
|
try {
|
|
37
35
|
subscription.item = eventData['key'];
|
|
38
|
-
const result = await getPayload(subscription, accountability, schema, eventData);
|
|
36
|
+
const result = await getPayload(subscription, self.accountability, schema, eventData);
|
|
39
37
|
yield {
|
|
40
38
|
[event]: {
|
|
41
39
|
key: eventData['key'],
|
|
@@ -52,7 +50,7 @@ export function createSubscriptionGenerator(self, event) {
|
|
|
52
50
|
for (const key of eventData['keys']) {
|
|
53
51
|
try {
|
|
54
52
|
subscription.item = key;
|
|
55
|
-
const result = await getPayload(subscription, accountability, schema, eventData);
|
|
53
|
+
const result = await getPayload(subscription, self.accountability, schema, eventData);
|
|
56
54
|
yield {
|
|
57
55
|
[event]: {
|
|
58
56
|
key,
|
|
@@ -15,12 +15,13 @@ import StreamArray from 'stream-json/streamers/StreamArray.js';
|
|
|
15
15
|
import getDatabase from '../database/index.js';
|
|
16
16
|
import emitter from '../emitter.js';
|
|
17
17
|
import { useLogger } from '../logger.js';
|
|
18
|
+
import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
|
|
18
19
|
import { getDateFormatted } from '../utils/get-date-formatted.js';
|
|
20
|
+
import { getService } from '../utils/get-service.js';
|
|
19
21
|
import { transaction } from '../utils/transaction.js';
|
|
20
22
|
import { Url } from '../utils/url.js';
|
|
21
23
|
import { userName } from '../utils/user-name.js';
|
|
22
24
|
import { FilesService } from './files.js';
|
|
23
|
-
import { ItemsService } from './items.js';
|
|
24
25
|
import { NotificationsService } from './notifications.js';
|
|
25
26
|
import { UsersService } from './users.js';
|
|
26
27
|
const env = useEnv();
|
|
@@ -37,10 +38,23 @@ export class ImportService {
|
|
|
37
38
|
async import(collection, mimetype, stream) {
|
|
38
39
|
if (this.accountability?.admin !== true && isSystemCollection(collection))
|
|
39
40
|
throw new ForbiddenError();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
if (this.accountability) {
|
|
42
|
+
await validateAccess({
|
|
43
|
+
accountability: this.accountability,
|
|
44
|
+
action: 'create',
|
|
45
|
+
collection,
|
|
46
|
+
}, {
|
|
47
|
+
schema: this.schema,
|
|
48
|
+
knex: this.knex,
|
|
49
|
+
});
|
|
50
|
+
await validateAccess({
|
|
51
|
+
accountability: this.accountability,
|
|
52
|
+
action: 'update',
|
|
53
|
+
collection,
|
|
54
|
+
}, {
|
|
55
|
+
schema: this.schema,
|
|
56
|
+
knex: this.knex,
|
|
57
|
+
});
|
|
44
58
|
}
|
|
45
59
|
switch (mimetype) {
|
|
46
60
|
case 'application/json':
|
|
@@ -52,11 +66,11 @@ export class ImportService {
|
|
|
52
66
|
throw new UnsupportedMediaTypeError({ mediaType: mimetype, where: 'file import' });
|
|
53
67
|
}
|
|
54
68
|
}
|
|
55
|
-
importJSON(collection, stream) {
|
|
69
|
+
async importJSON(collection, stream) {
|
|
56
70
|
const extractJSON = StreamArray.withParser();
|
|
57
71
|
const nestedActionEvents = [];
|
|
58
72
|
return transaction(this.knex, (trx) => {
|
|
59
|
-
const service =
|
|
73
|
+
const service = getService(collection, {
|
|
60
74
|
knex: trx,
|
|
61
75
|
schema: this.schema,
|
|
62
76
|
accountability: this.accountability,
|
|
@@ -94,7 +108,7 @@ export class ImportService {
|
|
|
94
108
|
throw new Error('Failed to create temporary file for import');
|
|
95
109
|
const nestedActionEvents = [];
|
|
96
110
|
return transaction(this.knex, (trx) => {
|
|
97
|
-
const service =
|
|
111
|
+
const service = getService(collection, {
|
|
98
112
|
knex: trx,
|
|
99
113
|
schema: this.schema,
|
|
100
114
|
accountability: this.accountability,
|
|
@@ -213,7 +227,7 @@ export class ExportService {
|
|
|
213
227
|
};
|
|
214
228
|
const database = getDatabase();
|
|
215
229
|
await transaction(database, async (trx) => {
|
|
216
|
-
const service =
|
|
230
|
+
const service = getService(collection, {
|
|
217
231
|
accountability: this.accountability,
|
|
218
232
|
schema: this.schema,
|
|
219
233
|
knex: trx,
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export * from './access.js';
|
|
1
2
|
export * from './activity.js';
|
|
2
3
|
export * from './assets.js';
|
|
3
4
|
export * from './authentication.js';
|
|
4
|
-
export * from './authorization.js';
|
|
5
5
|
export * from './collections.js';
|
|
6
6
|
export * from './dashboards.js';
|
|
7
7
|
export * from './extensions.js';
|
|
@@ -18,7 +18,8 @@ export * from './notifications.js';
|
|
|
18
18
|
export * from './operations.js';
|
|
19
19
|
export * from './panels.js';
|
|
20
20
|
export * from './payload.js';
|
|
21
|
-
export * from './permissions
|
|
21
|
+
export * from './permissions.js';
|
|
22
|
+
export * from './policies.js';
|
|
22
23
|
export * from './presets.js';
|
|
23
24
|
export * from './relations.js';
|
|
24
25
|
export * from './revisions.js';
|
package/dist/services/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export * from './access.js';
|
|
1
2
|
export * from './activity.js';
|
|
2
3
|
export * from './assets.js';
|
|
3
4
|
export * from './authentication.js';
|
|
4
|
-
export * from './authorization.js';
|
|
5
5
|
export * from './collections.js';
|
|
6
6
|
export * from './dashboards.js';
|
|
7
7
|
export * from './extensions.js';
|
|
@@ -18,7 +18,8 @@ export * from './notifications.js';
|
|
|
18
18
|
export * from './operations.js';
|
|
19
19
|
export * from './panels.js';
|
|
20
20
|
export * from './payload.js';
|
|
21
|
-
export * from './permissions
|
|
21
|
+
export * from './permissions.js';
|
|
22
|
+
export * from './policies.js';
|
|
22
23
|
export * from './presets.js';
|
|
23
24
|
export * from './relations.js';
|
|
24
25
|
export * from './revisions.js';
|
package/dist/services/items.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export declare class ItemsService<Item extends AnyItem = AnyItem> implements Abs
|
|
|
19
19
|
schema: SchemaOverview;
|
|
20
20
|
cache: Keyv<any> | null;
|
|
21
21
|
constructor(collection: string, options: AbstractServiceOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Create a fork of the current service, allowing instantiation with different options.
|
|
24
|
+
*/
|
|
25
|
+
private fork;
|
|
22
26
|
createMutationTracker(initialCount?: number): MutationTracker;
|
|
23
27
|
getKeysByQuery(query: Query): Promise<PrimaryKey[]>;
|
|
24
28
|
/**
|
|
@@ -27,62 +31,84 @@ export declare class ItemsService<Item extends AnyItem = AnyItem> implements Abs
|
|
|
27
31
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
28
32
|
/**
|
|
29
33
|
* Create multiple new items at once. Inserts all provided records sequentially wrapped in a transaction.
|
|
34
|
+
*
|
|
35
|
+
* Uses `this.createOne` under the hood.
|
|
30
36
|
*/
|
|
31
37
|
createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
32
38
|
/**
|
|
33
|
-
* Get items by query
|
|
39
|
+
* Get items by query.
|
|
34
40
|
*/
|
|
35
41
|
readByQuery(query: Query, opts?: QueryOptions): Promise<Item[]>;
|
|
36
42
|
/**
|
|
37
|
-
* Get single item by primary key
|
|
43
|
+
* Get single item by primary key.
|
|
44
|
+
*
|
|
45
|
+
* Uses `this.readByQuery` under the hood.
|
|
38
46
|
*/
|
|
39
47
|
readOne(key: PrimaryKey, query?: Query, opts?: QueryOptions): Promise<Item>;
|
|
40
48
|
/**
|
|
41
|
-
* Get multiple items by primary keys
|
|
49
|
+
* Get multiple items by primary keys.
|
|
50
|
+
*
|
|
51
|
+
* Uses `this.readByQuery` under the hood.
|
|
42
52
|
*/
|
|
43
53
|
readMany(keys: PrimaryKey[], query?: Query, opts?: QueryOptions): Promise<Item[]>;
|
|
44
54
|
/**
|
|
45
|
-
* Update multiple items by query
|
|
55
|
+
* Update multiple items by query.
|
|
56
|
+
*
|
|
57
|
+
* Uses `this.updateMany` under the hood.
|
|
46
58
|
*/
|
|
47
59
|
updateByQuery(query: Query, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
48
60
|
/**
|
|
49
|
-
* Update a single item by primary key
|
|
61
|
+
* Update a single item by primary key.
|
|
62
|
+
*
|
|
63
|
+
* Uses `this.updateMany` under the hood.
|
|
50
64
|
*/
|
|
51
65
|
updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
52
66
|
/**
|
|
53
|
-
* Update multiple items in a single transaction
|
|
67
|
+
* Update multiple items in a single transaction.
|
|
68
|
+
*
|
|
69
|
+
* Uses `this.updateOne` under the hood.
|
|
54
70
|
*/
|
|
55
71
|
updateBatch(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
56
72
|
/**
|
|
57
|
-
* Update many items by primary key, setting all items to the same change
|
|
73
|
+
* Update many items by primary key, setting all items to the same change.
|
|
58
74
|
*/
|
|
59
75
|
updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
60
76
|
/**
|
|
61
|
-
* Upsert a single item
|
|
77
|
+
* Upsert a single item.
|
|
78
|
+
*
|
|
79
|
+
* Uses `this.createOne` / `this.updateOne` under the hood.
|
|
62
80
|
*/
|
|
63
81
|
upsertOne(payload: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
64
82
|
/**
|
|
65
|
-
* Upsert many items
|
|
83
|
+
* Upsert many items.
|
|
84
|
+
*
|
|
85
|
+
* Uses `this.upsertOne` under the hood.
|
|
66
86
|
*/
|
|
67
87
|
upsertMany(payloads: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
68
88
|
/**
|
|
69
|
-
* Delete multiple items by query
|
|
89
|
+
* Delete multiple items by query.
|
|
90
|
+
*
|
|
91
|
+
* Uses `this.deleteMany` under the hood.
|
|
70
92
|
*/
|
|
71
93
|
deleteByQuery(query: Query, opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
72
94
|
/**
|
|
73
|
-
* Delete a single item by primary key
|
|
95
|
+
* Delete a single item by primary key.
|
|
96
|
+
*
|
|
97
|
+
* Uses `this.deleteMany` under the hood.
|
|
74
98
|
*/
|
|
75
99
|
deleteOne(key: PrimaryKey, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
76
100
|
/**
|
|
77
|
-
* Delete multiple items by primary key
|
|
101
|
+
* Delete multiple items by primary key.
|
|
78
102
|
*/
|
|
79
103
|
deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
|
|
80
104
|
/**
|
|
81
|
-
* Read/treat collection as singleton
|
|
105
|
+
* Read/treat collection as singleton.
|
|
82
106
|
*/
|
|
83
107
|
readSingleton(query: Query, opts?: QueryOptions): Promise<Partial<Item>>;
|
|
84
108
|
/**
|
|
85
|
-
* Upsert/treat collection as singleton
|
|
109
|
+
* Upsert/treat collection as singleton.
|
|
110
|
+
*
|
|
111
|
+
* Uses `this.createOne` / `this.updateOne` under the hood.
|
|
86
112
|
*/
|
|
87
113
|
upsertSingleton(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
88
114
|
}
|