mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
@@ -1,11 +1,23 @@
|
||||
import { AST, NestedCollectionAST } from '../types/ast';
|
||||
import { clone, uniq, pick } from 'lodash';
|
||||
import database, { schemaInspector } from './index';
|
||||
import database from './index';
|
||||
import SchemaInspector from 'knex-schema-inspector';
|
||||
import { Query, Item } from '../types';
|
||||
import PayloadService from '../services/payload';
|
||||
import applyQuery from '../utils/apply-query';
|
||||
import Knex from 'knex';
|
||||
|
||||
type RunASTOptions = {
|
||||
query?: AST['query'],
|
||||
knex?: Knex
|
||||
}
|
||||
|
||||
export default async function runAST(ast: AST, options?: RunASTOptions) {
|
||||
const query = options?.query || ast.query;
|
||||
const knex = options?.knex || database;
|
||||
|
||||
const schemaInspector = SchemaInspector(knex);
|
||||
|
||||
export default async function runAST(ast: AST, query = ast.query) {
|
||||
const toplevelFields: string[] = [];
|
||||
const tempFields: string[] = [];
|
||||
const nestedCollections: NestedCollectionAST[] = [];
|
||||
@@ -14,7 +26,7 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
({ column }) => column
|
||||
);
|
||||
|
||||
const payloadService = new PayloadService(ast.name);
|
||||
const payloadService = new PayloadService(ast.name, { knex });
|
||||
|
||||
for (const child of ast.children) {
|
||||
if (child.type === 'field') {
|
||||
@@ -40,7 +52,7 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
tempFields.push(primaryKeyField);
|
||||
}
|
||||
|
||||
let dbQuery = database.select([...toplevelFields, ...tempFields]).from(ast.name);
|
||||
let dbQuery = knex.select([...toplevelFields, ...tempFields]).from(ast.name);
|
||||
|
||||
// Query defaults
|
||||
query.limit = typeof query.limit === 'number' ? query.limit : 100;
|
||||
@@ -125,7 +137,7 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
}
|
||||
}
|
||||
|
||||
const nestedResults = await runAST(batch, batchQuery);
|
||||
const nestedResults = await runAST(batch, { query: batchQuery, knex });
|
||||
|
||||
results = results.map((record) => {
|
||||
if (m2o) {
|
||||
|
||||
@@ -168,7 +168,7 @@ export default class ItemsService implements AbstractService {
|
||||
const authorizationService = new AuthorizationService({
|
||||
accountability: this.accountability,
|
||||
});
|
||||
let ast = await getASTFromQuery(this.collection, query, this.accountability);
|
||||
let ast = await getASTFromQuery(this.collection, query, { accountability: this.accountability, knex: this.knex });
|
||||
|
||||
if (this.accountability && this.accountability.admin === false) {
|
||||
ast = await authorizationService.processAST(ast);
|
||||
@@ -204,19 +204,24 @@ export default class ItemsService implements AbstractService {
|
||||
let ast = await getASTFromQuery(
|
||||
this.collection,
|
||||
queryWithFilter,
|
||||
this.accountability,
|
||||
action
|
||||
{
|
||||
accountability: this.accountability,
|
||||
action,
|
||||
knex: this.knex,
|
||||
}
|
||||
);
|
||||
|
||||
if (this.accountability && this.accountability.admin !== true) {
|
||||
const authorizationService = new AuthorizationService({
|
||||
accountability: this.accountability,
|
||||
knex: this.knex,
|
||||
});
|
||||
ast = await authorizationService.processAST(ast, action);
|
||||
}
|
||||
|
||||
const records = await runAST(ast);
|
||||
const records = await runAST(ast, { knex: this.knex });
|
||||
return Array.isArray(key) ? records : records[0];
|
||||
return [] as Item;
|
||||
}
|
||||
|
||||
update(data: Partial<Item>, keys: PrimaryKey[]): Promise<PrimaryKey[]>;
|
||||
@@ -301,7 +306,6 @@ export default class ItemsService implements AbstractService {
|
||||
}
|
||||
|
||||
const itemsService = new ItemsService(this.collection, { knex: trx });
|
||||
|
||||
const snapshots = await itemsService.readByKey(keys);
|
||||
|
||||
const revisionRecords = activityPrimaryKeys.map((key, index) => ({
|
||||
|
||||
@@ -13,26 +13,39 @@ import {
|
||||
} from '../types';
|
||||
import database from '../database';
|
||||
import { clone } from 'lodash';
|
||||
import Knex from 'knex';
|
||||
|
||||
type GetASTOptions = {
|
||||
accountability?: Accountability | null;
|
||||
action?: PermissionsAction;
|
||||
knex?: Knex;
|
||||
}
|
||||
|
||||
export default async function getASTFromQuery(
|
||||
collection: string,
|
||||
query: Query,
|
||||
accountability?: Accountability | null,
|
||||
action?: PermissionsAction
|
||||
options?: GetASTOptions
|
||||
// accountability?: Accountability | null,
|
||||
// action?: PermissionsAction
|
||||
): Promise<AST> {
|
||||
query = clone(query);
|
||||
|
||||
const accountability = options?.accountability;
|
||||
const action = options?.action || 'read';
|
||||
const knex = options?.knex || database;
|
||||
|
||||
/**
|
||||
* we might not need al this info at all times, but it's easier to fetch it all once, than trying to fetch it for every
|
||||
* requested field. @todo look into utilizing graphql/dataloader for this purpose
|
||||
*/
|
||||
const relations = await database.select<Relation[]>('*').from('directus_relations');
|
||||
const relations = await knex.select<Relation[]>('*').from('directus_relations');
|
||||
|
||||
const permissions =
|
||||
accountability && accountability.admin !== true
|
||||
? await database
|
||||
? await knex
|
||||
.select<{ collection: string; fields: string }[]>('collection', 'fields')
|
||||
.from('directus_permissions')
|
||||
.where({ role: accountability.role, action: action || 'read' })
|
||||
.where({ role: accountability.role, action: action })
|
||||
: null;
|
||||
|
||||
const ast: AST = {
|
||||
|
||||
Reference in New Issue
Block a user