directus

Форк
0
/
get-column-path.ts 
102 строки · 3.1 Кб
1
import type { Relation, SchemaOverview } from '@directus/types';
2
import { InvalidQueryError } from '@directus/errors';
3
import { getRelationInfo } from './get-relation-info.js';
4

5
export type AliasMap = { [key: string]: { alias: string; collection: string } };
6

7
export type ColPathProps = {
8
	path: string[];
9
	collection: string;
10
	aliasMap: AliasMap;
11
	relations: Relation[];
12
	schema?: SchemaOverview;
13
};
14

15
export type ColPathResult = {
16
	columnPath: string;
17
	targetCollection: string;
18
	addNestedPkField: string | undefined;
19
};
20

21
/**
22
 * Converts a Directus field list path to the correct SQL names based on the constructed alias map.
23
 * For example: ['author', 'role', 'name'] -> 'ljnsv.name'
24
 * Also returns the target collection of the column: 'directus_roles'
25
 * If the last filter path is an alias field, a nested PK is appended to the path
26
 */
27
export function getColumnPath({ path, collection, aliasMap, relations, schema }: ColPathProps) {
28
	return followRelation(path);
29

30
	function followRelation(
31
		pathParts: string[],
32
		parentCollection: string = collection,
33
		parentFields?: string,
34
		addNestedPkField?: string,
35
	): ColPathResult {
36
		/**
37
		 * For A2M fields, the path can contain an optional collection scope <field>:<scope>
38
		 */
39
		const pathRoot = pathParts[0]!.split(':')[0];
40
		const { relation, relationType } = getRelationInfo(relations, parentCollection, pathRoot!);
41

42
		if (!relation) {
43
			throw new InvalidQueryError({ reason: `"${parentCollection}.${pathRoot}" is not a relational field` });
44
		}
45

46
		const alias = parentFields ? aliasMap[`${parentFields}.${pathParts[0]}`]?.alias : aliasMap[pathParts[0]!]?.alias;
47
		const remainingParts = pathParts.slice(1);
48

49
		let parent: string;
50

51
		if (relationType === 'a2o') {
52
			const pathScope = pathParts[0]!.split(':')[1];
53

54
			if (!pathScope) {
55
				throw new InvalidQueryError({
56
					reason: `You have to provide a collection scope when sorting on a many-to-any item`,
57
				});
58
			}
59

60
			parent = pathScope;
61
		} else if (relationType === 'm2o') {
62
			parent = relation.related_collection!;
63
		} else {
64
			parent = relation.collection;
65
		}
66

67
		// Top level alias field
68
		if (schema && !((remainingParts[0] ?? parent).includes('(') && (remainingParts[0] ?? parent).includes(')'))) {
69
			if (remainingParts.length === 0) {
70
				remainingParts.push(schema.collections[parent]!.primary);
71
				addNestedPkField = schema.collections[parent]!.primary;
72
			}
73
			// Nested level alias field
74
			else if (
75
				remainingParts.length === 1 &&
76
				schema.collections[parent]!.fields[remainingParts[0]!]!.type === 'alias'
77
			) {
78
				remainingParts.push(schema.collections[relation!.related_collection!]!.primary);
79
				addNestedPkField = schema.collections[relation!.related_collection!]!.primary;
80
			}
81
		}
82

83
		if (remainingParts.length === 1) {
84
			return {
85
				columnPath: `${alias || parent}.${remainingParts[0]}`,
86
				targetCollection: parent,
87
				addNestedPkField,
88
			};
89
		}
90

91
		if (remainingParts.length) {
92
			return followRelation(
93
				remainingParts,
94
				parent,
95
				`${parentFields ? parentFields + '.' : ''}${pathParts[0]}`,
96
				addNestedPkField,
97
			);
98
		}
99

100
		return { columnPath: '', targetCollection: '', addNestedPkField };
101
	}
102
}
103

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.