@webiny/api-headless-cms-storage 0.0.0-unstable.9f53ea597d → 6.6.0-alpha.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/__tests__/filtering/getValue.test.ts +58 -0
- package/__tests__/filtering/mocks/entry.noModel.ts +110 -0
- package/__tests__/path/plainObject.test.ts +32 -0
- package/__tests__/transforms/datetime.test.ts +71 -0
- package/{cms → dist/cms}/storageHelpers.d.ts +2 -4
- package/{cms → dist/cms}/storageHelpers.js +5 -10
- package/dist/cms/storageHelpers.js.map +1 -0
- package/dist/features/FilterRegistriesFeature.d.ts +4 -0
- package/dist/features/FilterRegistriesFeature.js +39 -0
- package/dist/features/FilterRegistriesFeature.js.map +1 -0
- package/dist/features/fieldFilterCreate/FieldFilterCreateRegistry.d.ts +7 -0
- package/dist/features/fieldFilterCreate/FieldFilterCreateRegistry.js +20 -0
- package/dist/features/fieldFilterCreate/FieldFilterCreateRegistry.js.map +1 -0
- package/dist/features/fieldFilterCreate/abstractions.d.ts +41 -0
- package/dist/features/fieldFilterCreate/abstractions.js +5 -0
- package/dist/features/fieldFilterCreate/abstractions.js.map +1 -0
- package/dist/features/fieldFilterPath/FieldFilterPathRegistry.d.ts +6 -0
- package/dist/features/fieldFilterPath/FieldFilterPathRegistry.js +14 -0
- package/dist/features/fieldFilterPath/FieldFilterPathRegistry.js.map +1 -0
- package/dist/features/fieldFilterPath/abstractions.d.ts +16 -0
- package/dist/features/fieldFilterPath/abstractions.js +5 -0
- package/dist/features/fieldFilterPath/abstractions.js.map +1 -0
- package/dist/features/fieldFilterValueTransform/FieldFilterValueTransformRegistry.d.ts +6 -0
- package/dist/features/fieldFilterValueTransform/FieldFilterValueTransformRegistry.js +14 -0
- package/dist/features/fieldFilterValueTransform/FieldFilterValueTransformRegistry.js.map +1 -0
- package/dist/features/fieldFilterValueTransform/abstractions.d.ts +14 -0
- package/dist/features/fieldFilterValueTransform/abstractions.js +5 -0
- package/dist/features/fieldFilterValueTransform/abstractions.js.map +1 -0
- package/dist/features/fieldSorting/FieldSortingRegistry.d.ts +6 -0
- package/dist/features/fieldSorting/FieldSortingRegistry.js +14 -0
- package/dist/features/fieldSorting/FieldSortingRegistry.js.map +1 -0
- package/dist/features/fieldSorting/abstractions.d.ts +40 -0
- package/dist/features/fieldSorting/abstractions.js +5 -0
- package/dist/features/fieldSorting/abstractions.js.map +1 -0
- package/{filtering → dist/filtering}/expressions/createExpressions.d.ts +4 -2
- package/{filtering → dist/filtering}/expressions/createExpressions.js +13 -26
- package/dist/filtering/expressions/createExpressions.js.map +1 -0
- package/dist/filtering/fields/createFields.d.ts +13 -0
- package/{filtering → dist/filtering}/fields/createFields.js +15 -27
- package/dist/filtering/fields/createFields.js.map +1 -0
- package/{filtering → dist/filtering}/fields/extractSort.d.ts +2 -2
- package/{filtering → dist/filtering}/fields/extractSort.js +9 -10
- package/dist/filtering/fields/extractSort.js.map +1 -0
- package/{filtering → dist/filtering}/filter.d.ts +4 -2
- package/{filtering → dist/filtering}/filter.js +3 -2
- package/dist/filtering/filter.js.map +1 -0
- package/{filtering → dist/filtering}/sort.d.ts +2 -2
- package/{filtering → dist/filtering}/sort.js +2 -2
- package/dist/filtering/sort.js.map +1 -0
- package/dist/handlers/datetimeTransformHandler.d.ts +2 -0
- package/dist/handlers/datetimeTransformHandler.js +34 -0
- package/dist/handlers/datetimeTransformHandler.js.map +1 -0
- package/dist/handlers/defaultFilterCreateHandler.d.ts +2 -0
- package/dist/handlers/defaultFilterCreateHandler.js +27 -0
- package/dist/handlers/defaultFilterCreateHandler.js.map +1 -0
- package/dist/handlers/locationFolderIdPathHandler.d.ts +2 -0
- package/dist/handlers/locationFolderIdPathHandler.js +18 -0
- package/dist/handlers/locationFolderIdPathHandler.js.map +1 -0
- package/dist/handlers/objectFilterCreateHandler.d.ts +2 -0
- package/dist/handlers/objectFilterCreateHandler.js +62 -0
- package/dist/handlers/objectFilterCreateHandler.js.map +1 -0
- package/dist/handlers/plainObjectPathHandler.d.ts +2 -0
- package/dist/handlers/plainObjectPathHandler.js +14 -0
- package/dist/handlers/plainObjectPathHandler.js.map +1 -0
- package/dist/handlers/refFilterCreateHandler.d.ts +2 -0
- package/dist/handlers/refFilterCreateHandler.js +57 -0
- package/dist/handlers/refFilterCreateHandler.js.map +1 -0
- package/dist/handlers/searchableJsonFilterCreateHandler.d.ts +2 -0
- package/dist/handlers/searchableJsonFilterCreateHandler.js +43 -0
- package/dist/handlers/searchableJsonFilterCreateHandler.js.map +1 -0
- package/{index.d.ts → dist/index.d.ts} +5 -0
- package/{index.js → dist/index.js} +5 -0
- package/dist/package.json +30 -0
- package/package.json +15 -19
- package/src/cms/storageHelpers.ts +92 -0
- package/src/features/FilterRegistriesFeature.ts +40 -0
- package/src/features/fieldFilterCreate/FieldFilterCreateRegistry.ts +25 -0
- package/src/features/fieldFilterCreate/abstractions.ts +51 -0
- package/src/features/fieldFilterPath/FieldFilterPathRegistry.ts +13 -0
- package/src/features/fieldFilterPath/abstractions.ts +22 -0
- package/src/features/fieldFilterValueTransform/FieldFilterValueTransformRegistry.ts +15 -0
- package/src/features/fieldFilterValueTransform/abstractions.ts +21 -0
- package/src/features/fieldSorting/FieldSortingRegistry.ts +20 -0
- package/src/features/fieldSorting/abstractions.ts +49 -0
- package/src/filtering/expressions/createExpressions.ts +170 -0
- package/src/filtering/fields/createFields.ts +124 -0
- package/src/filtering/fields/extractSort.ts +97 -0
- package/src/filtering/fields/systemFields.ts +165 -0
- package/src/filtering/fields/types.ts +46 -0
- package/src/filtering/filter.ts +166 -0
- package/src/filtering/fullTextSearch.ts +40 -0
- package/src/filtering/getValue.ts +64 -0
- package/src/filtering/mapPlugins.ts +30 -0
- package/src/filtering/plugins/defaultFilterCreate.ts +36 -0
- package/src/filtering/plugins/index.ts +13 -0
- package/src/filtering/plugins/objectFilterCreate.ts +100 -0
- package/src/filtering/plugins/refFilterCreate.ts +83 -0
- package/src/filtering/plugins/searchableJsonFilterCreate.ts +78 -0
- package/src/filtering/sort.ts +79 -0
- package/src/filtering/transform.ts +11 -0
- package/src/filtering/values.ts +24 -0
- package/src/filtering/where.ts +24 -0
- package/src/handlers/datetimeTransformHandler.ts +52 -0
- package/src/handlers/defaultFilterCreateHandler.ts +31 -0
- package/src/handlers/locationFolderIdPathHandler.ts +24 -0
- package/src/handlers/objectFilterCreateHandler.ts +86 -0
- package/src/handlers/plainObjectPathHandler.ts +17 -0
- package/src/handlers/refFilterCreateHandler.ts +65 -0
- package/src/handlers/searchableJsonFilterCreateHandler.ts +61 -0
- package/src/index.ts +63 -0
- package/src/path/locationFolderId.ts +29 -0
- package/src/path/plainObject.ts +21 -0
- package/src/plugins/CmsEntryFieldFilterPathPlugin.ts +58 -0
- package/src/plugins/CmsEntryFieldFilterPlugin.ts +59 -0
- package/src/plugins/CmsEntryFieldSortingPlugin.ts +63 -0
- package/src/plugins/CmsFieldFilterValueTransformPlugin.ts +43 -0
- package/src/plugins/index.ts +10 -0
- package/src/transforms/datetime.ts +62 -0
- package/tsconfig.build.json +33 -0
- package/tsconfig.json +33 -0
- package/vitest.config.ts +5 -0
- package/webiny.config.js +8 -0
- package/cms/storageHelpers.js.map +0 -1
- package/filtering/expressions/createExpressions.js.map +0 -1
- package/filtering/fields/createFields.d.ts +0 -11
- package/filtering/fields/createFields.js.map +0 -1
- package/filtering/fields/extractSort.js.map +0 -1
- package/filtering/filter.js.map +0 -1
- package/filtering/sort.js.map +0 -1
- /package/{LICENSE → dist/LICENSE} +0 -0
- /package/{README.md → dist/README.md} +0 -0
- /package/{filtering → dist/filtering}/fields/systemFields.d.ts +0 -0
- /package/{filtering → dist/filtering}/fields/systemFields.js +0 -0
- /package/{filtering → dist/filtering}/fields/systemFields.js.map +0 -0
- /package/{filtering → dist/filtering}/fields/types.d.ts +0 -0
- /package/{filtering → dist/filtering}/fields/types.js +0 -0
- /package/{filtering → dist/filtering}/fullTextSearch.d.ts +0 -0
- /package/{filtering → dist/filtering}/fullTextSearch.js +0 -0
- /package/{filtering → dist/filtering}/fullTextSearch.js.map +0 -0
- /package/{filtering → dist/filtering}/getValue.d.ts +0 -0
- /package/{filtering → dist/filtering}/getValue.js +0 -0
- /package/{filtering → dist/filtering}/getValue.js.map +0 -0
- /package/{filtering → dist/filtering}/mapPlugins.d.ts +0 -0
- /package/{filtering → dist/filtering}/mapPlugins.js +0 -0
- /package/{filtering → dist/filtering}/mapPlugins.js.map +0 -0
- /package/{filtering → dist/filtering}/plugins/defaultFilterCreate.d.ts +0 -0
- /package/{filtering → dist/filtering}/plugins/defaultFilterCreate.js +0 -0
- /package/{filtering → dist/filtering}/plugins/defaultFilterCreate.js.map +0 -0
- /package/{filtering → dist/filtering}/plugins/index.d.ts +0 -0
- /package/{filtering → dist/filtering}/plugins/index.js +0 -0
- /package/{filtering → dist/filtering}/plugins/index.js.map +0 -0
- /package/{filtering → dist/filtering}/plugins/objectFilterCreate.d.ts +0 -0
- /package/{filtering → dist/filtering}/plugins/objectFilterCreate.js +0 -0
- /package/{filtering → dist/filtering}/plugins/objectFilterCreate.js.map +0 -0
- /package/{filtering → dist/filtering}/plugins/refFilterCreate.d.ts +0 -0
- /package/{filtering → dist/filtering}/plugins/refFilterCreate.js +0 -0
- /package/{filtering → dist/filtering}/plugins/refFilterCreate.js.map +0 -0
- /package/{filtering → dist/filtering}/plugins/searchableJsonFilterCreate.d.ts +0 -0
- /package/{filtering → dist/filtering}/plugins/searchableJsonFilterCreate.js +0 -0
- /package/{filtering → dist/filtering}/plugins/searchableJsonFilterCreate.js.map +0 -0
- /package/{filtering → dist/filtering}/transform.d.ts +0 -0
- /package/{filtering → dist/filtering}/transform.js +0 -0
- /package/{filtering → dist/filtering}/transform.js.map +0 -0
- /package/{filtering → dist/filtering}/values.d.ts +0 -0
- /package/{filtering → dist/filtering}/values.js +0 -0
- /package/{filtering → dist/filtering}/values.js.map +0 -0
- /package/{filtering → dist/filtering}/where.d.ts +0 -0
- /package/{filtering → dist/filtering}/where.js +0 -0
- /package/{filtering → dist/filtering}/where.js.map +0 -0
- /package/{path → dist/path}/locationFolderId.d.ts +0 -0
- /package/{path → dist/path}/locationFolderId.js +0 -0
- /package/{path → dist/path}/locationFolderId.js.map +0 -0
- /package/{path → dist/path}/plainObject.d.ts +0 -0
- /package/{path → dist/path}/plainObject.js +0 -0
- /package/{path → dist/path}/plainObject.js.map +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPathPlugin.d.ts +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPathPlugin.js +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPathPlugin.js.map +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPlugin.d.ts +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPlugin.js +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldFilterPlugin.js.map +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldSortingPlugin.d.ts +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldSortingPlugin.js +0 -0
- /package/{plugins → dist/plugins}/CmsEntryFieldSortingPlugin.js.map +0 -0
- /package/{plugins → dist/plugins}/CmsFieldFilterValueTransformPlugin.d.ts +0 -0
- /package/{plugins → dist/plugins}/CmsFieldFilterValueTransformPlugin.js +0 -0
- /package/{plugins → dist/plugins}/CmsFieldFilterValueTransformPlugin.js.map +0 -0
- /package/{plugins → dist/plugins}/index.d.ts +0 -0
- /package/{plugins → dist/plugins}/index.js +0 -0
- /package/{transforms → dist/transforms}/datetime.d.ts +0 -0
- /package/{transforms → dist/transforms}/datetime.js +0 -0
- /package/{transforms → dist/transforms}/datetime.js.map +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import WebinyError from "@webiny/error";
|
|
2
|
+
import type { CmsEntryListWhere } from "@webiny/api-headless-cms/types/index.js";
|
|
3
|
+
import type { Field } from "../fields/types.js";
|
|
4
|
+
import { extractWhereParams } from "../where.js";
|
|
5
|
+
import { transformValue } from "../transform.js";
|
|
6
|
+
import { getBaseFieldType } from "@webiny/api-headless-cms/utils/getBaseFieldType.js";
|
|
7
|
+
import { ValueFilter, ValueFilterRegistry } from "@webiny/db-utils";
|
|
8
|
+
import type { FieldFilterCreateRegistry } from "../../features/fieldFilterCreate/abstractions.js";
|
|
9
|
+
import type { FieldFilterValueTransformRegistry } from "../../features/fieldFilterValueTransform/abstractions.js";
|
|
10
|
+
import { getWhereValues } from "../values.js";
|
|
11
|
+
|
|
12
|
+
interface CreateExpressionParams {
|
|
13
|
+
where: Partial<CmsEntryListWhere>;
|
|
14
|
+
condition: ExpressionCondition;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ICreateExpressionsParams {
|
|
18
|
+
filterCreateRegistry: FieldFilterCreateRegistry.Interface;
|
|
19
|
+
transformRegistry: FieldFilterValueTransformRegistry.Interface;
|
|
20
|
+
valueFilterRegistry: ValueFilterRegistry.Interface;
|
|
21
|
+
where: Partial<CmsEntryListWhere>;
|
|
22
|
+
fields: Record<string, Field>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type ExpressionCondition = "AND" | "OR";
|
|
26
|
+
|
|
27
|
+
export interface Expression {
|
|
28
|
+
expressions: Expression[];
|
|
29
|
+
filters: Filter[];
|
|
30
|
+
condition: ExpressionCondition;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Filter {
|
|
34
|
+
field: Field;
|
|
35
|
+
path: string;
|
|
36
|
+
fieldPathId: string;
|
|
37
|
+
filter: ValueFilter.Interface;
|
|
38
|
+
negate: boolean;
|
|
39
|
+
compareValue: any;
|
|
40
|
+
transformValue: <I = any, O = any>(value: I) => O;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export const createExpressions = (params: ICreateExpressionsParams): Expression => {
|
|
44
|
+
const { where, filterCreateRegistry, transformRegistry, fields, valueFilterRegistry } = params;
|
|
45
|
+
|
|
46
|
+
const getHandler = (type: string) => {
|
|
47
|
+
const fieldType = getBaseFieldType({ type });
|
|
48
|
+
const handler = filterCreateRegistry.get(fieldType) || filterCreateRegistry.getDefault();
|
|
49
|
+
if (handler) {
|
|
50
|
+
return handler;
|
|
51
|
+
}
|
|
52
|
+
throw new WebinyError(
|
|
53
|
+
`There is no filter create handler for the field type "${fieldType}".`,
|
|
54
|
+
"MISSING_FILTER_CREATE_HANDLER",
|
|
55
|
+
{ fieldType }
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const createExpression = ({ where, condition }: CreateExpressionParams): Expression => {
|
|
60
|
+
const expression: Expression = {
|
|
61
|
+
filters: [],
|
|
62
|
+
expressions: [],
|
|
63
|
+
condition
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
for (const key in where) {
|
|
67
|
+
const value = where[key as keyof typeof where];
|
|
68
|
+
if (value === undefined) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (key === "AND") {
|
|
73
|
+
const childWhereList = getWhereValues(value, key);
|
|
74
|
+
const childExpression: Expression = {
|
|
75
|
+
condition: "AND",
|
|
76
|
+
filters: [],
|
|
77
|
+
expressions: []
|
|
78
|
+
};
|
|
79
|
+
for (const childWhere of childWhereList) {
|
|
80
|
+
const result = createExpression({
|
|
81
|
+
where: childWhere,
|
|
82
|
+
condition: "AND"
|
|
83
|
+
});
|
|
84
|
+
childExpression.expressions.push(result);
|
|
85
|
+
}
|
|
86
|
+
expression.expressions.push(childExpression);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (key === "OR") {
|
|
90
|
+
const childWhereList = getWhereValues(value, key);
|
|
91
|
+
const childExpression: Expression = {
|
|
92
|
+
condition: "OR",
|
|
93
|
+
filters: [],
|
|
94
|
+
expressions: []
|
|
95
|
+
};
|
|
96
|
+
for (const childWhere of childWhereList) {
|
|
97
|
+
const result = createExpression({
|
|
98
|
+
where: childWhere,
|
|
99
|
+
condition: "AND"
|
|
100
|
+
});
|
|
101
|
+
childExpression.expressions.push(result);
|
|
102
|
+
}
|
|
103
|
+
expression.expressions.push(childExpression);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const whereParams = extractWhereParams(key);
|
|
108
|
+
if (!whereParams) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const { fieldId, operation, negate } = whereParams;
|
|
113
|
+
|
|
114
|
+
const field = fields[fieldId];
|
|
115
|
+
if (!field) {
|
|
116
|
+
throw new WebinyError(
|
|
117
|
+
`There is no field with the fieldId "${fieldId}".`,
|
|
118
|
+
"FIELD_ERROR",
|
|
119
|
+
{ fieldId }
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const handler = getHandler(field.type);
|
|
124
|
+
const fieldType = getBaseFieldType(field);
|
|
125
|
+
const transformHandler = transformRegistry.get(fieldType);
|
|
126
|
+
|
|
127
|
+
const transformValueCallable = (value: any) => {
|
|
128
|
+
if (!transformHandler) {
|
|
129
|
+
return value;
|
|
130
|
+
}
|
|
131
|
+
return transformHandler.transform({ field, value });
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const result = handler.create({
|
|
135
|
+
key,
|
|
136
|
+
value,
|
|
137
|
+
valueFilterRegistry,
|
|
138
|
+
transformRegistry,
|
|
139
|
+
getHandler,
|
|
140
|
+
operation,
|
|
141
|
+
negate,
|
|
142
|
+
field,
|
|
143
|
+
fields,
|
|
144
|
+
compareValue: transformValue({
|
|
145
|
+
value,
|
|
146
|
+
transform: transformValueCallable
|
|
147
|
+
}),
|
|
148
|
+
transformValue: transformValueCallable
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (!result || (Array.isArray(result) && result.length === 0)) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
expression.filters.push(...(Array.isArray(result) ? result : [result]));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return expression;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const expression = createExpression({
|
|
162
|
+
where,
|
|
163
|
+
condition: "AND"
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (expression.filters.length > 0 || expression.expressions.length !== 1) {
|
|
167
|
+
return expression;
|
|
168
|
+
}
|
|
169
|
+
return expression.expressions[0];
|
|
170
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { CmsModelField } from "@webiny/api-headless-cms/types/index.js";
|
|
2
|
+
import { createSystemFields } from "./systemFields.js";
|
|
3
|
+
import type { Field, FieldParent } from "./types.js";
|
|
4
|
+
import type { FieldFilterPathRegistry } from "../../features/fieldFilterPath/abstractions.js";
|
|
5
|
+
import type { FieldFilterValueTransformRegistry } from "../../features/fieldFilterValueTransform/abstractions.js";
|
|
6
|
+
import { getBaseFieldType } from "@webiny/api-headless-cms/utils/getBaseFieldType.js";
|
|
7
|
+
|
|
8
|
+
interface Params {
|
|
9
|
+
fields: CmsModelField[];
|
|
10
|
+
pathRegistry: FieldFilterPathRegistry.Interface;
|
|
11
|
+
transformRegistry: FieldFilterValueTransformRegistry.Interface;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface FieldCollection {
|
|
15
|
+
[key: string]: Field;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface AddFieldsToCollectionParams {
|
|
19
|
+
fields: CmsModelField[];
|
|
20
|
+
parents: FieldParent[];
|
|
21
|
+
pathRegistry: FieldFilterPathRegistry.Interface;
|
|
22
|
+
transformRegistry: FieldFilterValueTransformRegistry.Interface;
|
|
23
|
+
system: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const createFieldCollection = (params: AddFieldsToCollectionParams): FieldCollection => {
|
|
27
|
+
const { fields, parents, pathRegistry, transformRegistry, system } = params;
|
|
28
|
+
return fields.reduce<FieldCollection>((collection, field) => {
|
|
29
|
+
const fieldType = getBaseFieldType(field);
|
|
30
|
+
const transformHandler = transformRegistry.get(fieldType);
|
|
31
|
+
const pathHandler = pathRegistry.get(fieldType);
|
|
32
|
+
|
|
33
|
+
const fieldId = [
|
|
34
|
+
...parents,
|
|
35
|
+
{
|
|
36
|
+
fieldId: field.fieldId,
|
|
37
|
+
list: field.list
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
.map(f => f.fieldId)
|
|
41
|
+
.join(".");
|
|
42
|
+
|
|
43
|
+
collection[fieldId] = {
|
|
44
|
+
...field,
|
|
45
|
+
parents,
|
|
46
|
+
system,
|
|
47
|
+
createPath: pathParams => {
|
|
48
|
+
if (
|
|
49
|
+
pathHandler &&
|
|
50
|
+
pathHandler.canUse(
|
|
51
|
+
field,
|
|
52
|
+
parents.map(p => p.fieldId)
|
|
53
|
+
)
|
|
54
|
+
) {
|
|
55
|
+
return pathHandler.createPath(pathParams);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return parents
|
|
59
|
+
.map(parent => parent.fieldId)
|
|
60
|
+
.concat([pathParams.field.fieldId])
|
|
61
|
+
.join(".");
|
|
62
|
+
},
|
|
63
|
+
transform: value => {
|
|
64
|
+
if (!transformHandler) {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
return transformHandler.transform({
|
|
68
|
+
field,
|
|
69
|
+
value
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const childFields = field.settings?.fields;
|
|
74
|
+
if (!childFields?.length) {
|
|
75
|
+
return collection;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const result = createFieldCollection({
|
|
79
|
+
fields: childFields,
|
|
80
|
+
parents: [
|
|
81
|
+
...parents,
|
|
82
|
+
{
|
|
83
|
+
fieldId: field.fieldId,
|
|
84
|
+
list: field.list
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
pathRegistry,
|
|
88
|
+
transformRegistry,
|
|
89
|
+
system
|
|
90
|
+
});
|
|
91
|
+
Object.assign(collection, result);
|
|
92
|
+
return collection;
|
|
93
|
+
}, {});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const createFields = (params: Params) => {
|
|
97
|
+
const { fields, pathRegistry, transformRegistry } = params;
|
|
98
|
+
|
|
99
|
+
const collection = createFieldCollection({
|
|
100
|
+
fields: createSystemFields(),
|
|
101
|
+
pathRegistry,
|
|
102
|
+
transformRegistry,
|
|
103
|
+
parents: [],
|
|
104
|
+
system: true
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = createFieldCollection({
|
|
108
|
+
fields,
|
|
109
|
+
pathRegistry,
|
|
110
|
+
transformRegistry,
|
|
111
|
+
parents: [
|
|
112
|
+
{
|
|
113
|
+
fieldId: "values",
|
|
114
|
+
list: false
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
system: false
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
...collection,
|
|
122
|
+
...result
|
|
123
|
+
};
|
|
124
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import WebinyError from "@webiny/error";
|
|
2
|
+
import type { Field } from "./types.js";
|
|
3
|
+
import type { CmsModel } from "@webiny/api-headless-cms/types/index.js";
|
|
4
|
+
import type { FieldSortingRegistry } from "../../features/fieldSorting/abstractions.js";
|
|
5
|
+
|
|
6
|
+
const extractSortInfo = (sortBy: string) => {
|
|
7
|
+
const rootSorting = sortBy.match(/^([a-zA-Z]+)_(ASC|DESC)$/);
|
|
8
|
+
if (rootSorting) {
|
|
9
|
+
return {
|
|
10
|
+
fieldId: rootSorting[1],
|
|
11
|
+
isValues: false,
|
|
12
|
+
order: rootSorting[2] as "ASC" | "DESC"
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const valuesSorting = sortBy.match(/^values_([a-zA-Z0-9]+)_(ASC|DESC)$/);
|
|
16
|
+
if (valuesSorting) {
|
|
17
|
+
return {
|
|
18
|
+
fieldId: valuesSorting[1],
|
|
19
|
+
isValues: true,
|
|
20
|
+
order: valuesSorting[2] as "ASC" | "DESC"
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
throw new WebinyError(
|
|
24
|
+
"Problem in determining the sorting for the entry items.",
|
|
25
|
+
"SORT_EXTRACT_ERROR",
|
|
26
|
+
{
|
|
27
|
+
sortBy
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
interface IResponse {
|
|
33
|
+
valuePath: string;
|
|
34
|
+
reverse: boolean;
|
|
35
|
+
fieldId: string;
|
|
36
|
+
field: Field;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface IParams {
|
|
40
|
+
model: CmsModel;
|
|
41
|
+
sortBy: string;
|
|
42
|
+
fields: Record<string, Field>;
|
|
43
|
+
sortingRegistry: FieldSortingRegistry.Interface;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const extractSort = (params: IParams): IResponse => {
|
|
47
|
+
const { model, sortBy, fields, sortingRegistry } = params;
|
|
48
|
+
const { fieldId, isValues: isValuesSorting, order } = extractSortInfo(sortBy);
|
|
49
|
+
|
|
50
|
+
const field = Object.values(fields).find(f => {
|
|
51
|
+
const isValues = f.parents[0]?.fieldId === "values";
|
|
52
|
+
if (isValues && isValuesSorting) {
|
|
53
|
+
return f.fieldId === fieldId;
|
|
54
|
+
}
|
|
55
|
+
if (f.parents.length > 0) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return f.fieldId === fieldId;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const handler = sortingRegistry.find({
|
|
62
|
+
model,
|
|
63
|
+
field,
|
|
64
|
+
fieldId,
|
|
65
|
+
order,
|
|
66
|
+
sortBy
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (handler) {
|
|
70
|
+
return handler.createSort({
|
|
71
|
+
model,
|
|
72
|
+
fieldId,
|
|
73
|
+
order,
|
|
74
|
+
sortBy,
|
|
75
|
+
field,
|
|
76
|
+
fields
|
|
77
|
+
});
|
|
78
|
+
} else if (!field) {
|
|
79
|
+
throw new WebinyError(
|
|
80
|
+
"Sorting field does not exist in the content model.",
|
|
81
|
+
"SORTING_FIELD_ERROR",
|
|
82
|
+
{
|
|
83
|
+
fieldId,
|
|
84
|
+
fields
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const valuePath = field.createPath({
|
|
89
|
+
field
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
field,
|
|
93
|
+
fieldId,
|
|
94
|
+
valuePath,
|
|
95
|
+
reverse: order === "DESC"
|
|
96
|
+
};
|
|
97
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type { CmsModelField } from "@webiny/api-headless-cms/types/index.js";
|
|
2
|
+
import {
|
|
3
|
+
ENTRY_META_FIELDS,
|
|
4
|
+
isDateTimeEntryMetaField,
|
|
5
|
+
isIdentityEntryMetaField
|
|
6
|
+
} from "@webiny/api-headless-cms/constants.js";
|
|
7
|
+
import lodashStartCase from "lodash/startCase.js";
|
|
8
|
+
import { createModelField } from "@webiny/api-headless-cms";
|
|
9
|
+
|
|
10
|
+
export const createSystemFields = (): CmsModelField[] => {
|
|
11
|
+
const onMetaFields = ENTRY_META_FIELDS.filter(isDateTimeEntryMetaField).map<CmsModelField>(
|
|
12
|
+
fieldName => {
|
|
13
|
+
return createModelField({
|
|
14
|
+
id: fieldName,
|
|
15
|
+
type: "datetime",
|
|
16
|
+
storageId: fieldName,
|
|
17
|
+
fieldId: fieldName,
|
|
18
|
+
label: lodashStartCase(fieldName)
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const byMetaFields = ENTRY_META_FIELDS.filter(isIdentityEntryMetaField).map<CmsModelField>(
|
|
24
|
+
fieldName => {
|
|
25
|
+
return createModelField({
|
|
26
|
+
id: fieldName,
|
|
27
|
+
type: "plainObject",
|
|
28
|
+
storageId: fieldName,
|
|
29
|
+
fieldId: fieldName,
|
|
30
|
+
label: lodashStartCase(fieldName),
|
|
31
|
+
settings: {
|
|
32
|
+
path: `${fieldName}.id`
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return [
|
|
39
|
+
createModelField({
|
|
40
|
+
id: "id",
|
|
41
|
+
type: "text",
|
|
42
|
+
storageId: "id",
|
|
43
|
+
fieldId: "id",
|
|
44
|
+
label: "ID"
|
|
45
|
+
}),
|
|
46
|
+
createModelField({
|
|
47
|
+
id: "entryId",
|
|
48
|
+
type: "text",
|
|
49
|
+
storageId: "entryId",
|
|
50
|
+
fieldId: "entryId",
|
|
51
|
+
label: "Entry ID"
|
|
52
|
+
}),
|
|
53
|
+
|
|
54
|
+
...onMetaFields,
|
|
55
|
+
...byMetaFields,
|
|
56
|
+
|
|
57
|
+
createModelField({
|
|
58
|
+
id: "meta",
|
|
59
|
+
type: "plainObject",
|
|
60
|
+
storageId: "meta",
|
|
61
|
+
fieldId: "meta",
|
|
62
|
+
label: "Meta"
|
|
63
|
+
}),
|
|
64
|
+
createModelField({
|
|
65
|
+
id: "wbyAco_location",
|
|
66
|
+
type: "object",
|
|
67
|
+
storageId: "location",
|
|
68
|
+
label: "Location",
|
|
69
|
+
fieldId: "wbyAco_location",
|
|
70
|
+
settings: {
|
|
71
|
+
fields: [
|
|
72
|
+
createModelField({
|
|
73
|
+
id: "folderId",
|
|
74
|
+
type: "text",
|
|
75
|
+
fieldId: "folderId",
|
|
76
|
+
label: "Folder ID",
|
|
77
|
+
storageId: "folderId",
|
|
78
|
+
settings: {
|
|
79
|
+
path: "location.folderId"
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}),
|
|
85
|
+
|
|
86
|
+
createModelField({
|
|
87
|
+
id: "version",
|
|
88
|
+
type: "number",
|
|
89
|
+
storageId: "version",
|
|
90
|
+
fieldId: "version",
|
|
91
|
+
label: "Version"
|
|
92
|
+
}),
|
|
93
|
+
createModelField({
|
|
94
|
+
id: "status",
|
|
95
|
+
type: "text",
|
|
96
|
+
storageId: "status",
|
|
97
|
+
fieldId: "status",
|
|
98
|
+
label: "Status"
|
|
99
|
+
}),
|
|
100
|
+
createModelField({
|
|
101
|
+
id: "wbyDeleted",
|
|
102
|
+
type: "boolean",
|
|
103
|
+
storageId: "wbyDeleted",
|
|
104
|
+
fieldId: "wbyDeleted",
|
|
105
|
+
label: "Deleted"
|
|
106
|
+
}),
|
|
107
|
+
createModelField({
|
|
108
|
+
id: "state",
|
|
109
|
+
type: "object",
|
|
110
|
+
storageId: "object@state",
|
|
111
|
+
fieldId: "state",
|
|
112
|
+
label: "State",
|
|
113
|
+
settings: {
|
|
114
|
+
fields: [
|
|
115
|
+
createModelField({
|
|
116
|
+
id: "stepId",
|
|
117
|
+
type: "text",
|
|
118
|
+
fieldId: "stepId",
|
|
119
|
+
label: "Step ID",
|
|
120
|
+
storageId: "stepId"
|
|
121
|
+
}),
|
|
122
|
+
createModelField({
|
|
123
|
+
id: "stepName",
|
|
124
|
+
type: "text",
|
|
125
|
+
fieldId: "stepName",
|
|
126
|
+
label: "Step Name",
|
|
127
|
+
storageId: "stepName"
|
|
128
|
+
}),
|
|
129
|
+
createModelField({
|
|
130
|
+
id: "state",
|
|
131
|
+
type: "text",
|
|
132
|
+
fieldId: "state",
|
|
133
|
+
label: "State",
|
|
134
|
+
storageId: "state"
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
}),
|
|
139
|
+
createModelField({
|
|
140
|
+
id: "values",
|
|
141
|
+
type: "object",
|
|
142
|
+
storageId: "values",
|
|
143
|
+
fieldId: "values",
|
|
144
|
+
label: "Values"
|
|
145
|
+
}),
|
|
146
|
+
createModelField({
|
|
147
|
+
id: "live",
|
|
148
|
+
type: "object",
|
|
149
|
+
storageId: "live",
|
|
150
|
+
fieldId: "live",
|
|
151
|
+
label: "Live",
|
|
152
|
+
settings: {
|
|
153
|
+
fields: [
|
|
154
|
+
createModelField({
|
|
155
|
+
id: "version",
|
|
156
|
+
type: "number",
|
|
157
|
+
fieldId: "version",
|
|
158
|
+
label: "Version",
|
|
159
|
+
storageId: "version"
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
];
|
|
165
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CmsModelField } from "@webiny/api-headless-cms/types/index.js";
|
|
2
|
+
import type { CreatePathCallable } from "../../plugins/CmsEntryFieldFilterPathPlugin.js";
|
|
3
|
+
|
|
4
|
+
interface FieldValueTransform {
|
|
5
|
+
(value: any): any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface FieldParent {
|
|
9
|
+
fieldId: string;
|
|
10
|
+
list?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Field
|
|
14
|
+
extends
|
|
15
|
+
Partial<Omit<CmsModelField, "id" | "type" | "storageId" | "fieldId">>,
|
|
16
|
+
Pick<CmsModelField, "id" | "type" | "storageId" | "fieldId"> {
|
|
17
|
+
/*
|
|
18
|
+
* A list of fieldId of all parents of the current field.
|
|
19
|
+
*
|
|
20
|
+
* This is used to check if we need to iterate through an array of parent values.
|
|
21
|
+
*/
|
|
22
|
+
parents: FieldParent[];
|
|
23
|
+
/*
|
|
24
|
+
* The method which creates a path for the filtering.
|
|
25
|
+
*
|
|
26
|
+
* Always exists. In most cases it will return some fixed value.
|
|
27
|
+
* When having a CmsEntryFieldFilterPathPlugin then it is executed to create a path.
|
|
28
|
+
*/
|
|
29
|
+
createPath: CreatePathCallable;
|
|
30
|
+
/*
|
|
31
|
+
* In most cases, return value of this method is what ever is the input.
|
|
32
|
+
*
|
|
33
|
+
* In some cases there might be a CmsFieldFilterValueTransformPlugin, which transforms value to a comparable one.
|
|
34
|
+
* For example, time in format 15:45:58 is not comparable, so we transform it into the seconds and then compare.
|
|
35
|
+
*/
|
|
36
|
+
transform: FieldValueTransform;
|
|
37
|
+
/*
|
|
38
|
+
* Is the field a system field?
|
|
39
|
+
* System fields are built into the code and cannot be changed.
|
|
40
|
+
*/
|
|
41
|
+
system: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface FilterItemFromStorage {
|
|
45
|
+
<T = any>(field: CmsModelField, value: any): Promise<T>;
|
|
46
|
+
}
|