directus 9.20.4 → 9.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/drivers/openid.js +3 -1
- package/dist/cli/commands/schema/apply.js +0 -2
- package/dist/cli/commands/schema/snapshot.js +0 -2
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/controllers/extensions.js +4 -13
- package/dist/database/helpers/date/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/date/dialects/sqlite.js +4 -0
- package/dist/database/helpers/date/types.d.ts +1 -1
- package/dist/database/helpers/date/types.js +4 -0
- package/dist/database/helpers/fn/dialects/mssql.d.ts +8 -8
- package/dist/database/helpers/fn/dialects/mssql.js +22 -16
- package/dist/database/helpers/fn/dialects/mysql.d.ts +8 -8
- package/dist/database/helpers/fn/dialects/mysql.js +22 -16
- package/dist/database/helpers/fn/dialects/postgres.d.ts +8 -8
- package/dist/database/helpers/fn/dialects/postgres.js +22 -16
- package/dist/database/helpers/fn/types.d.ts +1 -1
- package/dist/database/helpers/index.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +1 -0
- package/dist/database/helpers/schema/dialects/cockroachdb.js +11 -0
- package/dist/database/helpers/schema/types.d.ts +3 -2
- package/dist/database/helpers/schema/types.js +5 -0
- package/dist/database/migrations/run.js +29 -3
- package/dist/database/run-ast.d.ts +1 -1
- package/dist/database/run-ast.js +1 -1
- package/dist/env.d.ts +4 -0
- package/dist/env.js +9 -4
- package/dist/env.test.d.ts +1 -8
- package/dist/exceptions/database/contains-null-values.d.ts +1 -1
- package/dist/exceptions/database/dialects/types.d.ts +6 -6
- package/dist/exceptions/database/invalid-foreign-key.d.ts +1 -1
- package/dist/exceptions/database/not-null-violation.d.ts +1 -1
- package/dist/exceptions/database/record-not-unique.d.ts +1 -1
- package/dist/exceptions/database/value-out-of-range.d.ts +1 -1
- package/dist/exceptions/database/value-too-long.d.ts +1 -1
- package/dist/exceptions/hit-rate-limit.d.ts +1 -1
- package/dist/exceptions/method-not-allowed.d.ts +1 -1
- package/dist/exceptions/service-unavailable.d.ts +1 -1
- package/dist/extensions.d.ts +7 -7
- package/dist/extensions.js +92 -89
- package/dist/logger.d.ts +1 -0
- package/dist/messenger.d.ts +1 -1
- package/dist/middleware/authenticate.d.ts +1 -0
- package/dist/middleware/schema.js +1 -1
- package/dist/middleware/validate-batch.d.ts +2 -0
- package/dist/operations/condition/index.d.ts +1 -1
- package/dist/operations/condition/index.js +1 -1
- package/dist/operations/condition/index.test.d.ts +1 -0
- package/dist/operations/exec/index.d.ts +1 -1
- package/dist/operations/item-create/index.d.ts +1 -1
- package/dist/operations/item-delete/index.d.ts +1 -1
- package/dist/operations/item-read/index.d.ts +1 -1
- package/dist/operations/item-update/index.d.ts +1 -1
- package/dist/operations/log/index.d.ts +1 -1
- package/dist/operations/mail/index.d.ts +1 -1
- package/dist/operations/notification/index.d.ts +1 -1
- package/dist/operations/request/index.d.ts +1 -1
- package/dist/operations/sleep/index.d.ts +1 -1
- package/dist/operations/transform/index.d.ts +1 -1
- package/dist/operations/trigger/index.d.ts +1 -1
- package/dist/operations/trigger/index.js +5 -2
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/services/authorization.js +7 -3
- package/dist/services/collections.d.ts +1 -1
- package/dist/services/collections.js +112 -13
- package/dist/services/fields.d.ts +5 -4
- package/dist/services/fields.js +118 -50
- package/dist/services/fields.test.d.ts +1 -0
- package/dist/services/graphql/index.js +4 -1
- package/dist/services/graphql/utils/process-error.d.ts +4 -0
- package/dist/services/graphql/utils/process-error.js +26 -0
- package/dist/services/graphql/utils/process-error.test.d.ts +1 -0
- package/dist/services/items.d.ts +1 -1
- package/dist/services/items.js +39 -13
- package/dist/services/mail/index.d.ts +2 -2
- package/dist/services/mail/index.js +2 -1
- package/dist/services/mail/templates/base.liquid +4 -4
- package/dist/services/notifications.js +9 -4
- package/dist/services/notifications.test.d.ts +1 -0
- package/dist/services/payload.d.ts +2 -2
- package/dist/services/payload.js +14 -12
- package/dist/services/relations.d.ts +4 -4
- package/dist/services/relations.js +66 -8
- package/dist/services/users.js +8 -2
- package/dist/services/users.test.d.ts +1 -0
- package/dist/types/assets.d.ts +7 -7
- package/dist/types/ast.d.ts +7 -7
- package/dist/types/auth.d.ts +4 -4
- package/dist/types/collection.d.ts +2 -2
- package/dist/types/events.d.ts +1 -1
- package/dist/types/files.d.ts +2 -2
- package/dist/types/items.d.ts +5 -5
- package/dist/types/migration.d.ts +1 -1
- package/dist/types/revision.d.ts +1 -1
- package/dist/types/services.d.ts +1 -1
- package/dist/types/snapshot.d.ts +4 -4
- package/dist/types/webhooks.d.ts +2 -2
- package/dist/utils/apply-snapshot.js +32 -13
- package/dist/utils/get-ast-from-query.d.ts +1 -1
- package/dist/utils/get-column-path.d.ts +2 -2
- package/dist/utils/get-module-default.d.ts +1 -1
- package/dist/utils/get-relation-info.d.ts +1 -1
- package/dist/utils/get-schema.d.ts +6 -2
- package/dist/utils/get-schema.js +1 -1
- package/dist/utils/get-snapshot.js +1 -1
- package/dist/utils/job-queue.d.ts +1 -1
- package/dist/utils/merge-permissions.d.ts +1 -0
- package/dist/utils/reduce-schema.js +3 -1
- package/package.json +69 -80
- package/dist/__mocks__/cache.d.ts +0 -5
- package/dist/__mocks__/cache.js +0 -7
- package/dist/__utils__/items-utils.d.ts +0 -2
- package/dist/__utils__/items-utils.js +0 -36
- package/dist/__utils__/schemas.d.ts +0 -13
- package/dist/__utils__/schemas.js +0 -304
- package/dist/__utils__/snapshots.d.ts +0 -5
- package/dist/__utils__/snapshots.js +0 -897
- package/dist/cli/index.test.js +0 -63
- package/dist/controllers/files.test.js +0 -49
- package/dist/database/migrations/run.test.js +0 -92
- package/dist/env.test.js +0 -40
- package/dist/middleware/authenticate.test.js +0 -214
- package/dist/middleware/extract-token.test.js +0 -60
- package/dist/middleware/validate-batch.test.js +0 -82
- package/dist/operations/exec/index.test.js +0 -95
- package/dist/services/files.test.js +0 -89
- package/dist/services/items.test.js +0 -765
- package/dist/services/payload.test.js +0 -196
- package/dist/services/specifications.test.js +0 -96
- package/dist/utils/apply-snapshot.test.js +0 -305
- package/dist/utils/async-handler.test.js +0 -18
- package/dist/utils/calculate-field-depth.test.js +0 -76
- package/dist/utils/filter-items.test.js +0 -60
- package/dist/utils/get-auth-providers.test.js +0 -72
- package/dist/utils/get-cache-key.test.js +0 -74
- package/dist/utils/get-column-path.test.js +0 -136
- package/dist/utils/get-config-from-env.test.js +0 -19
- package/dist/utils/get-relation-info.test.js +0 -88
- package/dist/utils/get-relation-type.test.js +0 -69
- package/dist/utils/get-string-byte-size.test.js +0 -8
- package/dist/utils/is-directus-jwt.test.js +0 -26
- package/dist/utils/jwt.test.js +0 -36
- package/dist/utils/merge-permissions.test.js +0 -80
- package/dist/utils/validate-keys.test.js +0 -97
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const logger_1 = __importDefault(require("../../../logger"));
|
|
7
|
+
const processError = (accountability, error) => {
|
|
8
|
+
logger_1.default.error(error);
|
|
9
|
+
if ((accountability === null || accountability === void 0 ? void 0 : accountability.admin) === true) {
|
|
10
|
+
return {
|
|
11
|
+
...error,
|
|
12
|
+
extensions: {
|
|
13
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return {
|
|
19
|
+
message: 'An unexpected error occurred.',
|
|
20
|
+
extensions: {
|
|
21
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.default = processError;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/services/items.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Accountability, PermissionsAction, Query, SchemaOverview } from '@direc
|
|
|
2
2
|
import Keyv from 'keyv';
|
|
3
3
|
import { Knex } from 'knex';
|
|
4
4
|
import { AbstractService, AbstractServiceOptions, Item as AnyItem, MutationOptions, PrimaryKey } from '../types';
|
|
5
|
-
export
|
|
5
|
+
export type QueryOptions = {
|
|
6
6
|
stripNonRequested?: boolean;
|
|
7
7
|
permissionsAction?: PermissionsAction;
|
|
8
8
|
emitEvents?: boolean;
|
package/dist/services/items.js
CHANGED
|
@@ -193,19 +193,34 @@ class ItemsService {
|
|
|
193
193
|
* Create multiple new items at once. Inserts all provided records sequentially wrapped in a transaction.
|
|
194
194
|
*/
|
|
195
195
|
async createMany(data, opts) {
|
|
196
|
-
const primaryKeys = await this.knex.transaction(async (trx) => {
|
|
196
|
+
const { primaryKeys, nestedActionEvents } = await this.knex.transaction(async (trx) => {
|
|
197
197
|
const service = new ItemsService(this.collection, {
|
|
198
198
|
accountability: this.accountability,
|
|
199
199
|
schema: this.schema,
|
|
200
200
|
knex: trx,
|
|
201
201
|
});
|
|
202
202
|
const primaryKeys = [];
|
|
203
|
+
const nestedActionEvents = [];
|
|
203
204
|
for (const payload of data) {
|
|
204
|
-
const primaryKey = await service.createOne(payload, {
|
|
205
|
+
const primaryKey = await service.createOne(payload, {
|
|
206
|
+
...(opts || {}),
|
|
207
|
+
autoPurgeCache: false,
|
|
208
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
209
|
+
});
|
|
205
210
|
primaryKeys.push(primaryKey);
|
|
206
211
|
}
|
|
207
|
-
return primaryKeys;
|
|
212
|
+
return { primaryKeys, nestedActionEvents };
|
|
208
213
|
});
|
|
214
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false) {
|
|
215
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
216
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction)) {
|
|
217
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
opts.bypassEmitAction(nestedActionEvent);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
209
224
|
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
210
225
|
await this.cache.clear();
|
|
211
226
|
}
|
|
@@ -325,20 +340,31 @@ class ItemsService {
|
|
|
325
340
|
* Update multiple items in a single transaction
|
|
326
341
|
*/
|
|
327
342
|
async updateBatch(data, opts) {
|
|
343
|
+
if (!Array.isArray(data)) {
|
|
344
|
+
throw new exceptions_1.InvalidPayloadException('Input should be an array of items.');
|
|
345
|
+
}
|
|
328
346
|
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
329
347
|
const keys = [];
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
348
|
+
try {
|
|
349
|
+
await this.knex.transaction(async (trx) => {
|
|
350
|
+
const service = new ItemsService(this.collection, {
|
|
351
|
+
accountability: this.accountability,
|
|
352
|
+
knex: trx,
|
|
353
|
+
schema: this.schema,
|
|
354
|
+
});
|
|
355
|
+
for (const item of data) {
|
|
356
|
+
if (!item[primaryKeyField])
|
|
357
|
+
throw new exceptions_1.InvalidPayloadException(`Item in update misses primary key.`);
|
|
358
|
+
const combinedOpts = Object.assign({ autoPurgeCache: false }, opts);
|
|
359
|
+
keys.push(await service.updateOne(item[primaryKeyField], (0, lodash_1.omit)(item, primaryKeyField), combinedOpts));
|
|
360
|
+
}
|
|
335
361
|
});
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
362
|
+
}
|
|
363
|
+
finally {
|
|
364
|
+
if (this.cache && env_1.default.CACHE_AUTO_PURGE && (opts === null || opts === void 0 ? void 0 : opts.autoPurgeCache) !== false) {
|
|
365
|
+
await this.cache.clear();
|
|
340
366
|
}
|
|
341
|
-
}
|
|
367
|
+
}
|
|
342
368
|
return keys;
|
|
343
369
|
}
|
|
344
370
|
/**
|
|
@@ -2,7 +2,7 @@ import { Knex } from 'knex';
|
|
|
2
2
|
import { AbstractServiceOptions } from '../../types';
|
|
3
3
|
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
4
4
|
import { Transporter, SendMailOptions } from 'nodemailer';
|
|
5
|
-
export
|
|
5
|
+
export type EmailOptions = SendMailOptions & {
|
|
6
6
|
template?: {
|
|
7
7
|
name: string;
|
|
8
8
|
data: Record<string, any>;
|
|
@@ -14,7 +14,7 @@ export declare class MailService {
|
|
|
14
14
|
knex: Knex;
|
|
15
15
|
mailer: Transporter;
|
|
16
16
|
constructor(opts: AbstractServiceOptions);
|
|
17
|
-
send(options: EmailOptions): Promise<
|
|
17
|
+
send<T>(options: EmailOptions): Promise<T>;
|
|
18
18
|
private renderTemplate;
|
|
19
19
|
private getDefaultTemplateData;
|
|
20
20
|
}
|
|
@@ -52,7 +52,8 @@ class MailService {
|
|
|
52
52
|
.map((line) => line.trim())
|
|
53
53
|
.join('\n');
|
|
54
54
|
}
|
|
55
|
-
await this.mailer.sendMail({ ...emailOptions, from, html });
|
|
55
|
+
const info = await this.mailer.sendMail({ ...emailOptions, from, html });
|
|
56
|
+
return info;
|
|
56
57
|
}
|
|
57
58
|
async renderTemplate(template, variables) {
|
|
58
59
|
const customTemplatePath = path_1.default.resolve(env_1.default.EXTENSIONS_PATH, 'templates', template + '.liquid');
|
|
@@ -125,14 +125,14 @@ blockquote > p {
|
|
|
125
125
|
<tbody>
|
|
126
126
|
<tr>
|
|
127
127
|
<td align="left" valign="top" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:0 0 30px 0">
|
|
128
|
-
<table><tbody><tr><td align="center" valign="middle" style="background-color:{{ projectColor }};width:48px;height:48px;border-radius:4px;padding:6px;">
|
|
129
|
-
<img id="logo" src="{{ projectLogo }}" alt="{{ projectName }} Logo" width="40" height="auto" border="0" style="-ms-interpolation-mode:bicubic; border:0; height:
|
|
128
|
+
<table><tbody><tr><td align="center" valign="middle" style="background-color:{{ projectColor }};max-width:48px;max-height:48px;border-radius:4px;padding:6px;">
|
|
129
|
+
<img id="logo" src="{{ projectLogo }}" alt="{{ projectName }} Logo" width="40" height="auto" border="0" style="-ms-interpolation-mode:bicubic; border:0; height:40px; line-height:100%; outline:none; text-decoration:none; display:block; width:40px; object-fit:contain;">
|
|
130
130
|
</td></tr></tbody></table>
|
|
131
131
|
</td>
|
|
132
132
|
</tr>
|
|
133
133
|
<tr>
|
|
134
134
|
<td id="content" align="left" valign="top" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:40px 50px 50px 50px; font-family:Open Sans, Helvetica, Arial, sans-serif; border-radius:4px; box-shadow:0 4px 0 #15253A; background-color:#FFFFFE; color:#172940; font-size:15px; line-height:26px; margin:0" bgcolor="#FFFFFE">
|
|
135
|
-
<div
|
|
135
|
+
<div style="color: inherit; font-size: inherit; line-height: inherit;">
|
|
136
136
|
|
|
137
137
|
{% block content %}{{ html }}{% endblock %}
|
|
138
138
|
|
|
@@ -142,7 +142,7 @@ blockquote > p {
|
|
|
142
142
|
<tr>
|
|
143
143
|
<td align="center" valign="middle" style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; mso-table-lspace:0pt; mso-table-rspace:0pt; padding:25px 0; font-family:Open Sans, Helvetica, Arial, sans-serif; color:#FFFFFE">
|
|
144
144
|
<p style="margin-bottom: 1em; color: #A2B5CD;font-size: 12px; line-height: 16px;">
|
|
145
|
-
Sent by the team at {{ projectName }} — <a style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; text-decoration:none; color:#A2B5CD"
|
|
145
|
+
Sent by the team at {{ projectName }}{% if url %} — <a style="-webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; text-decoration:none; color:#A2B5CD" href="{{ url }}" target="_blank">Manage Your Account</a>{% endif %}<br>
|
|
146
146
|
{% block footer %}{% endblock %}
|
|
147
147
|
</p>
|
|
148
148
|
</td>
|
|
@@ -6,9 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.NotificationsService = void 0;
|
|
7
7
|
const items_1 = require("./items");
|
|
8
8
|
const md_1 = require("../utils/md");
|
|
9
|
+
const url_1 = require("../utils/url");
|
|
9
10
|
const users_1 = require("./users");
|
|
10
11
|
const mail_1 = require("./mail");
|
|
11
12
|
const logger_1 = __importDefault(require("../logger"));
|
|
13
|
+
const env_1 = __importDefault(require("../env"));
|
|
12
14
|
class NotificationsService extends items_1.ItemsService {
|
|
13
15
|
constructor(options) {
|
|
14
16
|
super('directus_notifications', options);
|
|
@@ -28,16 +30,19 @@ class NotificationsService extends items_1.ItemsService {
|
|
|
28
30
|
return response;
|
|
29
31
|
}
|
|
30
32
|
async sendEmail(data) {
|
|
33
|
+
var _a;
|
|
31
34
|
if (data.recipient) {
|
|
32
|
-
const user = await this.usersService.readOne(data.recipient, {
|
|
35
|
+
const user = await this.usersService.readOne(data.recipient, {
|
|
36
|
+
fields: ['id', 'email', 'email_notifications', 'role.app_access'],
|
|
37
|
+
});
|
|
38
|
+
const manageUserAccountUrl = new url_1.Url(env_1.default.PUBLIC_URL).addPath('admin', 'users', user.id).toString();
|
|
39
|
+
const html = data.message ? (0, md_1.md)(data.message) : '';
|
|
33
40
|
if (user.email && user.email_notifications === true) {
|
|
34
41
|
try {
|
|
35
42
|
await this.mailService.send({
|
|
36
43
|
template: {
|
|
37
44
|
name: 'base',
|
|
38
|
-
data: {
|
|
39
|
-
html: data.message ? (0, md_1.md)(data.message) : '',
|
|
40
|
-
},
|
|
45
|
+
data: ((_a = user.role) === null || _a === void 0 ? void 0 : _a.app_access) ? { url: manageUserAccountUrl, html } : { html },
|
|
41
46
|
},
|
|
42
47
|
to: user.email,
|
|
43
48
|
subject: data.subject,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,8 +2,8 @@ import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
|
2
2
|
import { Knex } from 'knex';
|
|
3
3
|
import { Helpers } from '../database/helpers';
|
|
4
4
|
import { AbstractServiceOptions, ActionEventParams, Item, MutationOptions, PrimaryKey } from '../types';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
type Action = 'create' | 'read' | 'update';
|
|
6
|
+
type Transformers = {
|
|
7
7
|
[type: string]: (context: {
|
|
8
8
|
action: Action;
|
|
9
9
|
value: any;
|
package/dist/services/payload.js
CHANGED
|
@@ -102,7 +102,9 @@ class PayloadService {
|
|
|
102
102
|
async 'cast-csv'({ action, value }) {
|
|
103
103
|
if (Array.isArray(value) === false && typeof value !== 'string')
|
|
104
104
|
return;
|
|
105
|
-
if (action === 'read'
|
|
105
|
+
if (action === 'read') {
|
|
106
|
+
if (Array.isArray(value))
|
|
107
|
+
return value;
|
|
106
108
|
if (value === '')
|
|
107
109
|
return [];
|
|
108
110
|
return value.split(',');
|
|
@@ -346,7 +348,7 @@ class PayloadService {
|
|
|
346
348
|
if (Object.keys(fieldsToUpdate).length > 0) {
|
|
347
349
|
await itemsService.updateOne(relatedPrimaryKey, relatedRecord, {
|
|
348
350
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
349
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
351
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
350
352
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
351
353
|
});
|
|
352
354
|
}
|
|
@@ -354,7 +356,7 @@ class PayloadService {
|
|
|
354
356
|
else {
|
|
355
357
|
relatedPrimaryKey = await itemsService.createOne(relatedRecord, {
|
|
356
358
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
357
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
359
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
358
360
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
359
361
|
});
|
|
360
362
|
}
|
|
@@ -406,7 +408,7 @@ class PayloadService {
|
|
|
406
408
|
if (Object.keys(fieldsToUpdate).length > 0) {
|
|
407
409
|
await itemsService.updateOne(relatedPrimaryKey, relatedRecord, {
|
|
408
410
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
409
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
411
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
410
412
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
411
413
|
});
|
|
412
414
|
}
|
|
@@ -414,7 +416,7 @@ class PayloadService {
|
|
|
414
416
|
else {
|
|
415
417
|
relatedPrimaryKey = await itemsService.createOne(relatedRecord, {
|
|
416
418
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
417
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
419
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
418
420
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
419
421
|
});
|
|
420
422
|
}
|
|
@@ -496,7 +498,7 @@ class PayloadService {
|
|
|
496
498
|
}
|
|
497
499
|
savedPrimaryKeys.push(...(await itemsService.upsertMany(recordsToUpsert, {
|
|
498
500
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
499
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
501
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
500
502
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
501
503
|
})));
|
|
502
504
|
const query = {
|
|
@@ -519,14 +521,14 @@ class PayloadService {
|
|
|
519
521
|
if (relation.meta.one_deselect_action === 'delete') {
|
|
520
522
|
// There's no revision for a deletion
|
|
521
523
|
await itemsService.deleteByQuery(query, {
|
|
522
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
524
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
523
525
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
524
526
|
});
|
|
525
527
|
}
|
|
526
528
|
else {
|
|
527
529
|
await itemsService.updateByQuery(query, { [relation.field]: null }, {
|
|
528
530
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
529
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
531
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
530
532
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
531
533
|
});
|
|
532
534
|
}
|
|
@@ -567,7 +569,7 @@ class PayloadService {
|
|
|
567
569
|
}
|
|
568
570
|
await itemsService.createMany(createPayload, {
|
|
569
571
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
570
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
572
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
571
573
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
572
574
|
});
|
|
573
575
|
}
|
|
@@ -579,7 +581,7 @@ class PayloadService {
|
|
|
579
581
|
[relation.field]: parent || payload[currentPrimaryKeyField],
|
|
580
582
|
}, {
|
|
581
583
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
582
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
584
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
583
585
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
584
586
|
});
|
|
585
587
|
}
|
|
@@ -603,14 +605,14 @@ class PayloadService {
|
|
|
603
605
|
};
|
|
604
606
|
if (relation.meta.one_deselect_action === 'delete') {
|
|
605
607
|
await itemsService.deleteByQuery(query, {
|
|
606
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
608
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
607
609
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
608
610
|
});
|
|
609
611
|
}
|
|
610
612
|
else {
|
|
611
613
|
await itemsService.updateByQuery(query, { [relation.field]: null }, {
|
|
612
614
|
onRevisionCreate: (pk) => revisions.push(pk),
|
|
613
|
-
bypassEmitAction: (params) => nestedActionEvents.push(params),
|
|
615
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
614
616
|
emitEvents: opts === null || opts === void 0 ? void 0 : opts.emitEvents,
|
|
615
617
|
});
|
|
616
618
|
}
|
|
@@ -4,7 +4,7 @@ import { ItemsService, QueryOptions } from './items';
|
|
|
4
4
|
import { PermissionsService } from './permissions';
|
|
5
5
|
import SchemaInspector from '@directus/schema';
|
|
6
6
|
import Keyv from 'keyv';
|
|
7
|
-
import { AbstractServiceOptions } from '../types';
|
|
7
|
+
import { AbstractServiceOptions, MutationOptions } from '../types';
|
|
8
8
|
import { Helpers } from '../database/helpers';
|
|
9
9
|
export declare class RelationsService {
|
|
10
10
|
knex: Knex;
|
|
@@ -21,17 +21,17 @@ export declare class RelationsService {
|
|
|
21
21
|
/**
|
|
22
22
|
* Create a new relationship / foreign key constraint
|
|
23
23
|
*/
|
|
24
|
-
createOne(relation: Partial<Relation
|
|
24
|
+
createOne(relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Update an existing foreign key constraint
|
|
27
27
|
*
|
|
28
28
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
29
29
|
*/
|
|
30
|
-
updateOne(collection: string, field: string, relation: Partial<Relation
|
|
30
|
+
updateOne(collection: string, field: string, relation: Partial<Relation>, opts?: MutationOptions): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Delete an existing relationship
|
|
33
33
|
*/
|
|
34
|
-
deleteOne(collection: string, field: string): Promise<void>;
|
|
34
|
+
deleteOne(collection: string, field: string, opts?: MutationOptions): Promise<void>;
|
|
35
35
|
/**
|
|
36
36
|
* Whether or not the current user has read access to relations
|
|
37
37
|
*/
|
|
@@ -37,6 +37,8 @@ const database_1 = __importStar(require("../database"));
|
|
|
37
37
|
const get_default_index_name_1 = require("../utils/get-default-index-name");
|
|
38
38
|
const cache_1 = require("../cache");
|
|
39
39
|
const helpers_1 = require("../database/helpers");
|
|
40
|
+
const emitter_1 = __importDefault(require("../emitter"));
|
|
41
|
+
const get_schema_1 = require("../utils/get-schema");
|
|
40
42
|
class RelationsService {
|
|
41
43
|
constructor(options) {
|
|
42
44
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -125,7 +127,7 @@ class RelationsService {
|
|
|
125
127
|
/**
|
|
126
128
|
* Create a new relationship / foreign key constraint
|
|
127
129
|
*/
|
|
128
|
-
async createOne(relation) {
|
|
130
|
+
async createOne(relation, opts) {
|
|
129
131
|
if (this.accountability && this.accountability.admin !== true) {
|
|
130
132
|
throw new exceptions_1.ForbiddenException();
|
|
131
133
|
}
|
|
@@ -153,6 +155,7 @@ class RelationsService {
|
|
|
153
155
|
throw new exceptions_1.InvalidPayloadException(`Field "${relation.field}" in collection "${relation.collection}" already has an associated relationship`);
|
|
154
156
|
}
|
|
155
157
|
const runPostColumnChange = await this.helpers.schema.preColumnChange();
|
|
158
|
+
const nestedActionEvents = [];
|
|
156
159
|
try {
|
|
157
160
|
const metaRow = {
|
|
158
161
|
...(relation.meta || {}),
|
|
@@ -181,14 +184,25 @@ class RelationsService {
|
|
|
181
184
|
// allowed to extract the relations regardless of permissions to directus_relations. This
|
|
182
185
|
// happens in `filterForbidden` down below
|
|
183
186
|
});
|
|
184
|
-
await relationsItemService.createOne(metaRow
|
|
187
|
+
await relationsItemService.createOne(metaRow, {
|
|
188
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
189
|
+
});
|
|
185
190
|
});
|
|
186
191
|
}
|
|
187
192
|
finally {
|
|
188
193
|
if (runPostColumnChange) {
|
|
189
194
|
await this.helpers.schema.postColumnChange();
|
|
190
195
|
}
|
|
191
|
-
|
|
196
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
197
|
+
await (0, cache_1.clearSystemCache)();
|
|
198
|
+
}
|
|
199
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
200
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
201
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
202
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
203
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
192
206
|
}
|
|
193
207
|
}
|
|
194
208
|
/**
|
|
@@ -196,7 +210,7 @@ class RelationsService {
|
|
|
196
210
|
*
|
|
197
211
|
* Note: You can update anything under meta, but only the `on_delete` trigger under schema
|
|
198
212
|
*/
|
|
199
|
-
async updateOne(collection, field, relation) {
|
|
213
|
+
async updateOne(collection, field, relation, opts) {
|
|
200
214
|
if (this.accountability && this.accountability.admin !== true) {
|
|
201
215
|
throw new exceptions_1.ForbiddenException();
|
|
202
216
|
}
|
|
@@ -211,6 +225,7 @@ class RelationsService {
|
|
|
211
225
|
throw new exceptions_1.InvalidPayloadException(`Field "${field}" in collection "${collection}" doesn't have a relationship.`);
|
|
212
226
|
}
|
|
213
227
|
const runPostColumnChange = await this.helpers.schema.preColumnChange();
|
|
228
|
+
const nestedActionEvents = [];
|
|
214
229
|
try {
|
|
215
230
|
await this.knex.transaction(async (trx) => {
|
|
216
231
|
if (existingRelation.related_collection) {
|
|
@@ -221,6 +236,8 @@ class RelationsService {
|
|
|
221
236
|
if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.schema) {
|
|
222
237
|
constraintName = existingRelation.schema.constraint_name || constraintName;
|
|
223
238
|
table.dropForeign(field, constraintName);
|
|
239
|
+
constraintName = this.helpers.schema.constraintName(constraintName);
|
|
240
|
+
existingRelation.schema.constraint_name = constraintName;
|
|
224
241
|
}
|
|
225
242
|
this.alterType(table, relation);
|
|
226
243
|
const builder = table
|
|
@@ -240,7 +257,9 @@ class RelationsService {
|
|
|
240
257
|
});
|
|
241
258
|
if (relation.meta) {
|
|
242
259
|
if (existingRelation === null || existingRelation === void 0 ? void 0 : existingRelation.meta) {
|
|
243
|
-
await relationsItemService.updateOne(existingRelation.meta.id, relation.meta
|
|
260
|
+
await relationsItemService.updateOne(existingRelation.meta.id, relation.meta, {
|
|
261
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
262
|
+
});
|
|
244
263
|
}
|
|
245
264
|
else {
|
|
246
265
|
await relationsItemService.createOne({
|
|
@@ -248,6 +267,8 @@ class RelationsService {
|
|
|
248
267
|
many_collection: relation.collection,
|
|
249
268
|
many_field: relation.field,
|
|
250
269
|
one_collection: existingRelation.related_collection || null,
|
|
270
|
+
}, {
|
|
271
|
+
bypassEmitAction: (params) => (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
|
251
272
|
});
|
|
252
273
|
}
|
|
253
274
|
}
|
|
@@ -257,13 +278,22 @@ class RelationsService {
|
|
|
257
278
|
if (runPostColumnChange) {
|
|
258
279
|
await this.helpers.schema.postColumnChange();
|
|
259
280
|
}
|
|
260
|
-
|
|
281
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
282
|
+
await (0, cache_1.clearSystemCache)();
|
|
283
|
+
}
|
|
284
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
285
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
286
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
287
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
288
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
261
291
|
}
|
|
262
292
|
}
|
|
263
293
|
/**
|
|
264
294
|
* Delete an existing relationship
|
|
265
295
|
*/
|
|
266
|
-
async deleteOne(collection, field) {
|
|
296
|
+
async deleteOne(collection, field, opts) {
|
|
267
297
|
if (this.accountability && this.accountability.admin !== true) {
|
|
268
298
|
throw new exceptions_1.ForbiddenException();
|
|
269
299
|
}
|
|
@@ -278,6 +308,7 @@ class RelationsService {
|
|
|
278
308
|
throw new exceptions_1.InvalidPayloadException(`Field "${field}" in collection "${collection}" doesn't have a relationship.`);
|
|
279
309
|
}
|
|
280
310
|
const runPostColumnChange = await this.helpers.schema.preColumnChange();
|
|
311
|
+
const nestedActionEvents = [];
|
|
281
312
|
try {
|
|
282
313
|
await this.knex.transaction(async (trx) => {
|
|
283
314
|
var _a;
|
|
@@ -292,13 +323,40 @@ class RelationsService {
|
|
|
292
323
|
if (existingRelation.meta) {
|
|
293
324
|
await trx('directus_relations').delete().where({ many_collection: collection, many_field: field });
|
|
294
325
|
}
|
|
326
|
+
const actionEvent = {
|
|
327
|
+
event: 'relations.delete',
|
|
328
|
+
meta: {
|
|
329
|
+
payload: [field],
|
|
330
|
+
collection: collection,
|
|
331
|
+
},
|
|
332
|
+
context: {
|
|
333
|
+
database: this.knex,
|
|
334
|
+
schema: this.schema,
|
|
335
|
+
accountability: this.accountability,
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
if (opts === null || opts === void 0 ? void 0 : opts.bypassEmitAction) {
|
|
339
|
+
opts.bypassEmitAction(actionEvent);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
nestedActionEvents.push(actionEvent);
|
|
343
|
+
}
|
|
295
344
|
});
|
|
296
345
|
}
|
|
297
346
|
finally {
|
|
298
347
|
if (runPostColumnChange) {
|
|
299
348
|
await this.helpers.schema.postColumnChange();
|
|
300
349
|
}
|
|
301
|
-
|
|
350
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.autoPurgeSystemCache) !== false) {
|
|
351
|
+
await (0, cache_1.clearSystemCache)();
|
|
352
|
+
}
|
|
353
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvents) !== false && nestedActionEvents.length > 0) {
|
|
354
|
+
const updatedSchema = await (0, get_schema_1.getSchema)();
|
|
355
|
+
for (const nestedActionEvent of nestedActionEvents) {
|
|
356
|
+
nestedActionEvent.context.schema = updatedSchema;
|
|
357
|
+
emitter_1.default.emitAction(nestedActionEvent.event, nestedActionEvent.meta, nestedActionEvent.context);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
302
360
|
}
|
|
303
361
|
}
|
|
304
362
|
/**
|
package/dist/services/users.js
CHANGED
|
@@ -203,10 +203,16 @@ class UsersService extends items_1.ItemsService {
|
|
|
203
203
|
throw new exceptions_2.InvalidPayloadException(`You can't change the "tfa_secret" value manually.`);
|
|
204
204
|
}
|
|
205
205
|
if (data.provider !== undefined) {
|
|
206
|
-
|
|
206
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
207
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "provider" value manually.`);
|
|
208
|
+
}
|
|
209
|
+
data.auth_data = null;
|
|
207
210
|
}
|
|
208
211
|
if (data.external_identifier !== undefined) {
|
|
209
|
-
|
|
212
|
+
if (this.accountability && this.accountability.admin !== true) {
|
|
213
|
+
throw new exceptions_2.InvalidPayloadException(`You can't change the "external_identifier" value manually.`);
|
|
214
|
+
}
|
|
215
|
+
data.auth_data = null;
|
|
210
216
|
}
|
|
211
217
|
return await super.updateMany(keys, data, opts);
|
|
212
218
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/assets.d.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { ResizeOptions, Sharp } from 'sharp';
|
|
2
2
|
export declare const TransformationMethods: readonly ["toFormat", "jpeg", "png", "tiff", "webp", "resize", "extend", "extract", "trim", "rotate", "flip", "flop", "sharpen", "median", "blur", "flatten", "gamma", "negate", "normalise", "normalize", "clahe", "convolve", "threshold", "linear", "recomb", "modulate", "tint", "greyscale", "grayscale", "toColorspace", "toColourspace", "removeAlpha", "ensureAlpha", "extractChannel", "bandbool"];
|
|
3
|
-
|
|
4
|
-
export
|
|
3
|
+
type AllowedSharpMethods = Pick<Sharp, typeof TransformationMethods[number]>;
|
|
4
|
+
export type TransformationMap = {
|
|
5
5
|
[M in keyof AllowedSharpMethods]: readonly [M, ...Parameters<AllowedSharpMethods[M]>];
|
|
6
6
|
};
|
|
7
|
-
export
|
|
8
|
-
export
|
|
7
|
+
export type Transformation = TransformationMap[keyof TransformationMap];
|
|
8
|
+
export type TransformationParams = {
|
|
9
9
|
key?: string;
|
|
10
10
|
transforms?: Transformation[];
|
|
11
11
|
};
|
|
12
|
-
export
|
|
12
|
+
export type TransformationPreset = TransformationPresetFormat & TransformationPresetResize & TransformationParams & {
|
|
13
13
|
key: string;
|
|
14
14
|
};
|
|
15
|
-
export
|
|
15
|
+
export type TransformationPresetFormat = {
|
|
16
16
|
format?: 'jpg' | 'jpeg' | 'png' | 'webp' | 'tiff';
|
|
17
17
|
quality?: number;
|
|
18
18
|
};
|
|
19
|
-
export
|
|
19
|
+
export type TransformationPresetResize = Pick<ResizeOptions, 'width' | 'height' | 'fit' | 'withoutEnlargement'>;
|
|
20
20
|
export {};
|
package/dist/types/ast.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Query, Relation } from '@directus/shared/types';
|
|
2
|
-
export
|
|
2
|
+
export type M2ONode = {
|
|
3
3
|
type: 'm2o';
|
|
4
4
|
name: string;
|
|
5
5
|
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
@@ -9,7 +9,7 @@ export declare type M2ONode = {
|
|
|
9
9
|
parentKey: string;
|
|
10
10
|
relatedKey: string;
|
|
11
11
|
};
|
|
12
|
-
export
|
|
12
|
+
export type A2MNode = {
|
|
13
13
|
type: 'a2o';
|
|
14
14
|
names: string[];
|
|
15
15
|
children: {
|
|
@@ -25,7 +25,7 @@ export declare type A2MNode = {
|
|
|
25
25
|
relation: Relation;
|
|
26
26
|
parentKey: string;
|
|
27
27
|
};
|
|
28
|
-
export
|
|
28
|
+
export type O2MNode = {
|
|
29
29
|
type: 'o2m';
|
|
30
30
|
name: string;
|
|
31
31
|
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|
|
@@ -35,20 +35,20 @@ export declare type O2MNode = {
|
|
|
35
35
|
parentKey: string;
|
|
36
36
|
relatedKey: string;
|
|
37
37
|
};
|
|
38
|
-
export
|
|
39
|
-
export
|
|
38
|
+
export type NestedCollectionNode = M2ONode | O2MNode | A2MNode;
|
|
39
|
+
export type FieldNode = {
|
|
40
40
|
type: 'field';
|
|
41
41
|
name: string;
|
|
42
42
|
fieldKey: string;
|
|
43
43
|
};
|
|
44
|
-
export
|
|
44
|
+
export type FunctionFieldNode = {
|
|
45
45
|
type: 'functionField';
|
|
46
46
|
name: string;
|
|
47
47
|
fieldKey: string;
|
|
48
48
|
query: Query;
|
|
49
49
|
relatedCollection: string;
|
|
50
50
|
};
|
|
51
|
-
export
|
|
51
|
+
export type AST = {
|
|
52
52
|
type: 'root';
|
|
53
53
|
name: string;
|
|
54
54
|
children: (NestedCollectionNode | FieldNode | FunctionFieldNode)[];
|