@webiny/api-headless-cms-utils-os 0.0.0-unstable.5387e5f7c8 → 0.0.0-unstable.a85ef555b2
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/features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.d.ts +3 -1
- package/features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.js +15 -5
- package/features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.js.map +1 -1
- package/features/CmsEntryOpenSearchBodyBuilder/abstractions.d.ts +4 -0
- package/features/CmsEntryOpenSearchBodyBuilder/abstractions.js.map +1 -1
- package/operations/entry/elasticsearch/fields/system.d.ts +7 -0
- package/operations/entry/elasticsearch/fields/system.js +58 -0
- package/operations/entry/elasticsearch/fields/system.js.map +1 -0
- package/operations/entry/elasticsearch/fields.d.ts +4 -2
- package/operations/entry/elasticsearch/fields.js +6 -4
- package/operations/entry/elasticsearch/fields.js.map +1 -1
- package/operations/entry/elasticsearch/fullTextSearch.js +10 -1
- package/operations/entry/elasticsearch/fullTextSearch.js.map +1 -1
- package/operations/entry/elasticsearch/initialQuery.d.ts +4 -0
- package/operations/entry/elasticsearch/initialQuery.js +2 -4
- package/operations/entry/elasticsearch/initialQuery.js.map +1 -1
- package/operations/entry/elasticsearch/initialQuery.test.d.ts +1 -0
- package/operations/entry/elasticsearch/initialQuery.test.js +48 -0
- package/operations/entry/elasticsearch/initialQuery.test.js.map +1 -0
- package/package.json +8 -7
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SearchBody } from "@webiny/api-opensearch/types.js";
|
|
2
2
|
import { OpenSearchFieldFactory } from "@webiny/api-opensearch/exports/api/opensearch.js";
|
|
3
3
|
import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/exports/api/cms/graphql.js";
|
|
4
|
+
import { CmsEntrySystemField } from "@webiny/api-headless-cms/features/contentEntry/EntrySystemField/index.js";
|
|
4
5
|
import { CmsEntryOpenSearchFieldIndexRegistry } from "../../features/CmsEntryOpenSearchFieldIndex/index.js";
|
|
5
6
|
import { CmsEntryOpenSearchBodyModifier } from "../../features/CmsEntryOpenSearchBodyModifier/index.js";
|
|
6
7
|
import { CmsEntryOpenSearchSortModifier } from "../../features/CmsEntryOpenSearchSortModifier/index.js";
|
|
@@ -21,7 +22,8 @@ declare class CmsEntryOpenSearchBodyBuilderImpl implements CmsEntryOpenSearchBod
|
|
|
21
22
|
private readonly valueSearchRegistry;
|
|
22
23
|
private readonly fullTextSearches;
|
|
23
24
|
private readonly fieldFactory;
|
|
24
|
-
|
|
25
|
+
private readonly entrySystemFields;
|
|
26
|
+
constructor(execFiltering: CmsEntryOpenSearchExecFiltering.Interface, fieldPathFactory: CmsEntryOpenSearchFieldPathFactory.Interface, fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface, fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface, bodyModifiers: CmsEntryOpenSearchBodyModifier.Interface[], sortModifiers: CmsEntryOpenSearchSortModifier.Interface[], queryModifiers: CmsEntryOpenSearchQueryModifier.Interface[], valueSearchRegistry: CmsEntryOpenSearchValueSearchRegistry.Interface, fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[], fieldFactory: OpenSearchFieldFactory.Interface, entrySystemFields: CmsEntrySystemField.Interface[]);
|
|
25
27
|
build(params: CmsEntryOpenSearchBodyBuilderAbstraction.Params): SearchBody;
|
|
26
28
|
}
|
|
27
29
|
export declare const CmsEntryOpenSearchBodyBuilder: typeof CmsEntryOpenSearchBodyBuilderImpl & {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenSearchFieldFactory } from "@webiny/api-opensearch/exports/api/opensearch.js";
|
|
2
2
|
import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/exports/api/cms/graphql.js";
|
|
3
|
+
import { CmsEntrySystemField } from "@webiny/api-headless-cms/features/contentEntry/EntrySystemField/index.js";
|
|
3
4
|
import { CmsEntryOpenSearchFieldIndexRegistry } from "../CmsEntryOpenSearchFieldIndex/index.js";
|
|
4
5
|
import { CmsEntryOpenSearchBodyModifier } from "../CmsEntryOpenSearchBodyModifier/index.js";
|
|
5
6
|
import { CmsEntryOpenSearchSortModifier } from "../CmsEntryOpenSearchSortModifier/index.js";
|
|
@@ -16,7 +17,7 @@ import { assignMinimumShouldMatchToQuery } from "../../operations/entry/elastics
|
|
|
16
17
|
import { createElasticsearchSort } from "./sort.js";
|
|
17
18
|
import { CmsEntryOpenSearchBodyBuilder } from "./abstractions.js";
|
|
18
19
|
class CmsEntryOpenSearchBodyBuilderImpl {
|
|
19
|
-
constructor(execFiltering, fieldPathFactory, fieldRegistry, fieldIndexRegistry, bodyModifiers, sortModifiers, queryModifiers, valueSearchRegistry, fullTextSearches, fieldFactory){
|
|
20
|
+
constructor(execFiltering, fieldPathFactory, fieldRegistry, fieldIndexRegistry, bodyModifiers, sortModifiers, queryModifiers, valueSearchRegistry, fullTextSearches, fieldFactory, entrySystemFields){
|
|
20
21
|
this.execFiltering = execFiltering;
|
|
21
22
|
this.fieldPathFactory = fieldPathFactory;
|
|
22
23
|
this.fieldRegistry = fieldRegistry;
|
|
@@ -27,14 +28,16 @@ class CmsEntryOpenSearchBodyBuilderImpl {
|
|
|
27
28
|
this.valueSearchRegistry = valueSearchRegistry;
|
|
28
29
|
this.fullTextSearches = fullTextSearches;
|
|
29
30
|
this.fieldFactory = fieldFactory;
|
|
31
|
+
this.entrySystemFields = entrySystemFields;
|
|
30
32
|
}
|
|
31
33
|
build(params) {
|
|
32
|
-
const { model } = params;
|
|
34
|
+
const { model, shared } = params;
|
|
33
35
|
const { fields, search: term, where, sort: initialSort, after, limit } = params.params;
|
|
34
36
|
const modelFields = createModelFields({
|
|
35
37
|
model,
|
|
36
38
|
fieldRegistry: this.fieldRegistry,
|
|
37
|
-
fieldIndexRegistry: this.fieldIndexRegistry
|
|
39
|
+
fieldIndexRegistry: this.fieldIndexRegistry,
|
|
40
|
+
systemFields: this.entrySystemFields.map((systemField)=>systemField.field)
|
|
38
41
|
});
|
|
39
42
|
const applicableQueryModifiers = this.queryModifiers.filter((m)=>!m.modelId || m.modelId === model.modelId);
|
|
40
43
|
const applicableSortModifiers = this.sortModifiers.filter((m)=>!m.modelId || m.modelId === model.modelId);
|
|
@@ -46,7 +49,8 @@ class CmsEntryOpenSearchBodyBuilderImpl {
|
|
|
46
49
|
});
|
|
47
50
|
const query = createInitialQuery({
|
|
48
51
|
where,
|
|
49
|
-
model
|
|
52
|
+
model,
|
|
53
|
+
shared
|
|
50
54
|
});
|
|
51
55
|
applyFullTextSearch({
|
|
52
56
|
model,
|
|
@@ -136,7 +140,13 @@ const CmsEntryOpenSearchBodyBuilder_CmsEntryOpenSearchBodyBuilder = CmsEntryOpen
|
|
|
136
140
|
multiple: true
|
|
137
141
|
}
|
|
138
142
|
],
|
|
139
|
-
OpenSearchFieldFactory
|
|
143
|
+
OpenSearchFieldFactory,
|
|
144
|
+
[
|
|
145
|
+
CmsEntrySystemField,
|
|
146
|
+
{
|
|
147
|
+
multiple: true
|
|
148
|
+
}
|
|
149
|
+
]
|
|
140
150
|
]
|
|
141
151
|
});
|
|
142
152
|
export { CmsEntryOpenSearchBodyBuilder_CmsEntryOpenSearchBodyBuilder as CmsEntryOpenSearchBodyBuilder };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.js","sources":["../../../src/features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.ts"],"sourcesContent":["import type {\n QueryDslBoolQuery as BoolQueryConfig,\n SearchBody\n} from \"@webiny/api-opensearch/types.js\";\nimport { OpenSearchFieldFactory } from \"@webiny/api-opensearch/exports/api/opensearch.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/exports/api/cms/graphql.js\";\nimport { CmsEntryOpenSearchFieldIndexRegistry } from \"~/features/CmsEntryOpenSearchFieldIndex/index.js\";\nimport { CmsEntryOpenSearchBodyModifier } from \"~/features/CmsEntryOpenSearchBodyModifier/index.js\";\nimport { CmsEntryOpenSearchSortModifier } from \"~/features/CmsEntryOpenSearchSortModifier/index.js\";\nimport { CmsEntryOpenSearchQueryModifier } from \"~/features/CmsEntryOpenSearchQueryModifier/index.js\";\nimport { CmsEntryOpenSearchValueSearchRegistry } from \"~/features/CmsEntryOpenSearchValueSearch/index.js\";\nimport { CmsEntryOpenSearchFullTextSearch } from \"~/features/CmsEntryOpenSearchFullTextSearch/index.js\";\nimport { CmsEntryOpenSearchExecFiltering } from \"~/features/CmsEntryOpenSearchExecFiltering/index.js\";\nimport { CmsEntryOpenSearchFieldPathFactory } from \"~/features/CmsEntryOpenSearchFieldPathFactory/index.js\";\nimport { createModelFields } from \"~/operations/entry/elasticsearch/fields.js\";\nimport { createFullTextSearchFields } from \"~/operations/entry/elasticsearch/fullTextSearchFields.js\";\nimport { createInitialQuery } from \"~/operations/entry/elasticsearch/initialQuery.js\";\nimport { applyFullTextSearch } from \"~/operations/entry/elasticsearch/fullTextSearch.js\";\nimport { assignMinimumShouldMatchToQuery } from \"~/operations/entry/elasticsearch/assignMinimumShouldMatchToQuery.js\";\nimport { createElasticsearchSort } from \"./sort.js\";\nimport { CmsEntryOpenSearchBodyBuilder as CmsEntryOpenSearchBodyBuilderAbstraction } from \"./abstractions.js\";\n\nclass CmsEntryOpenSearchBodyBuilderImpl\n implements CmsEntryOpenSearchBodyBuilderAbstraction.Interface\n{\n public constructor(\n private readonly execFiltering: CmsEntryOpenSearchExecFiltering.Interface,\n private readonly fieldPathFactory: CmsEntryOpenSearchFieldPathFactory.Interface,\n private readonly fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface,\n private readonly fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface,\n private readonly bodyModifiers: CmsEntryOpenSearchBodyModifier.Interface[],\n private readonly sortModifiers: CmsEntryOpenSearchSortModifier.Interface[],\n private readonly queryModifiers: CmsEntryOpenSearchQueryModifier.Interface[],\n private readonly valueSearchRegistry: CmsEntryOpenSearchValueSearchRegistry.Interface,\n private readonly fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[],\n private readonly fieldFactory: OpenSearchFieldFactory.Interface\n ) {}\n\n public build(params: CmsEntryOpenSearchBodyBuilderAbstraction.Params): SearchBody {\n const { model } = params;\n const { fields, search: term, where, sort: initialSort, after, limit } = params.params;\n\n const modelFields = createModelFields({\n model,\n fieldRegistry: this.fieldRegistry,\n fieldIndexRegistry: this.fieldIndexRegistry\n });\n\n const applicableQueryModifiers = this.queryModifiers.filter(m => {\n return !m.modelId || m.modelId === model.modelId;\n });\n const applicableSortModifiers = this.sortModifiers.filter(\n m => !m.modelId || m.modelId === model.modelId\n );\n const applicableBodyModifiers = this.bodyModifiers.filter(m => {\n return !m.modelId || m.modelId === model.modelId;\n });\n\n const fullTextSearchFields = createFullTextSearchFields({\n fields: modelFields,\n term,\n targets: fields\n });\n\n const query = createInitialQuery({\n where,\n model\n });\n\n applyFullTextSearch({\n model,\n fullTextSearches: this.fullTextSearches,\n query,\n term,\n fields: fullTextSearchFields\n });\n\n this.execFiltering.execute({\n model,\n fields: modelFields,\n where,\n query\n });\n\n for (const modifier of applicableQueryModifiers) {\n modifier.modifyQuery({ query, model, where });\n }\n\n const sort = createElasticsearchSort({\n sort: initialSort,\n modelFields,\n model,\n fieldPathFactory: this.fieldPathFactory,\n valueSearchRegistry: this.valueSearchRegistry,\n fieldFactory: this.fieldFactory\n });\n\n for (const modifier of applicableSortModifiers) {\n modifier.modifySort({\n sort,\n model\n });\n }\n\n const boolQuery: BoolQueryConfig = {\n must: query.must.length > 0 ? query.must : undefined,\n must_not: query.must_not.length > 0 ? query.must_not : undefined,\n should: query.should.length > 0 ? query.should : undefined,\n filter: query.filter.length > 0 ? query.filter : undefined\n };\n\n assignMinimumShouldMatchToQuery({\n query: boolQuery\n });\n\n const body: SearchBody = {\n query: {\n bool: boolQuery\n },\n sort,\n size: (limit || 0) + 1,\n search_after: after,\n track_total_hits: true\n };\n\n for (const modifier of applicableBodyModifiers) {\n modifier.modifyBody({\n body,\n model,\n where\n });\n }\n\n return body;\n }\n}\n\nexport const CmsEntryOpenSearchBodyBuilder =\n CmsEntryOpenSearchBodyBuilderAbstraction.createImplementation({\n implementation: CmsEntryOpenSearchBodyBuilderImpl,\n dependencies: [\n CmsEntryOpenSearchExecFiltering,\n CmsEntryOpenSearchFieldPathFactory,\n CmsModelFieldToGraphQLRegistry,\n CmsEntryOpenSearchFieldIndexRegistry,\n [CmsEntryOpenSearchBodyModifier, { multiple: true }],\n [CmsEntryOpenSearchSortModifier, { multiple: true }],\n [CmsEntryOpenSearchQueryModifier, { multiple: true }],\n CmsEntryOpenSearchValueSearchRegistry,\n [CmsEntryOpenSearchFullTextSearch, { multiple: true }],\n OpenSearchFieldFactory\n ]\n });\n"],"names":["CmsEntryOpenSearchBodyBuilderImpl","execFiltering","fieldPathFactory","fieldRegistry","fieldIndexRegistry","bodyModifiers","sortModifiers","queryModifiers","valueSearchRegistry","fullTextSearches","fieldFactory","params","model","fields","term","where","initialSort","after","limit","modelFields","createModelFields","applicableQueryModifiers","m","applicableSortModifiers","applicableBodyModifiers","fullTextSearchFields","createFullTextSearchFields","query","createInitialQuery","applyFullTextSearch","modifier","sort","createElasticsearchSort","boolQuery","undefined","assignMinimumShouldMatchToQuery","body","CmsEntryOpenSearchBodyBuilder","CmsEntryOpenSearchBodyBuilderAbstraction","CmsEntryOpenSearchExecFiltering","CmsEntryOpenSearchFieldPathFactory","CmsModelFieldToGraphQLRegistry","CmsEntryOpenSearchFieldIndexRegistry","CmsEntryOpenSearchBodyModifier","CmsEntryOpenSearchSortModifier","CmsEntryOpenSearchQueryModifier","CmsEntryOpenSearchValueSearchRegistry","CmsEntryOpenSearchFullTextSearch","OpenSearchFieldFactory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.js","sources":["../../../src/features/CmsEntryOpenSearchBodyBuilder/CmsEntryOpenSearchBodyBuilder.ts"],"sourcesContent":["import type {\n QueryDslBoolQuery as BoolQueryConfig,\n SearchBody\n} from \"@webiny/api-opensearch/types.js\";\nimport { OpenSearchFieldFactory } from \"@webiny/api-opensearch/exports/api/opensearch.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/exports/api/cms/graphql.js\";\nimport { CmsEntrySystemField } from \"@webiny/api-headless-cms/features/contentEntry/EntrySystemField/index.js\";\nimport { CmsEntryOpenSearchFieldIndexRegistry } from \"~/features/CmsEntryOpenSearchFieldIndex/index.js\";\nimport { CmsEntryOpenSearchBodyModifier } from \"~/features/CmsEntryOpenSearchBodyModifier/index.js\";\nimport { CmsEntryOpenSearchSortModifier } from \"~/features/CmsEntryOpenSearchSortModifier/index.js\";\nimport { CmsEntryOpenSearchQueryModifier } from \"~/features/CmsEntryOpenSearchQueryModifier/index.js\";\nimport { CmsEntryOpenSearchValueSearchRegistry } from \"~/features/CmsEntryOpenSearchValueSearch/index.js\";\nimport { CmsEntryOpenSearchFullTextSearch } from \"~/features/CmsEntryOpenSearchFullTextSearch/index.js\";\nimport { CmsEntryOpenSearchExecFiltering } from \"~/features/CmsEntryOpenSearchExecFiltering/index.js\";\nimport { CmsEntryOpenSearchFieldPathFactory } from \"~/features/CmsEntryOpenSearchFieldPathFactory/index.js\";\nimport { createModelFields } from \"~/operations/entry/elasticsearch/fields.js\";\nimport { createFullTextSearchFields } from \"~/operations/entry/elasticsearch/fullTextSearchFields.js\";\nimport { createInitialQuery } from \"~/operations/entry/elasticsearch/initialQuery.js\";\nimport { applyFullTextSearch } from \"~/operations/entry/elasticsearch/fullTextSearch.js\";\nimport { assignMinimumShouldMatchToQuery } from \"~/operations/entry/elasticsearch/assignMinimumShouldMatchToQuery.js\";\nimport { createElasticsearchSort } from \"./sort.js\";\nimport { CmsEntryOpenSearchBodyBuilder as CmsEntryOpenSearchBodyBuilderAbstraction } from \"./abstractions.js\";\n\nclass CmsEntryOpenSearchBodyBuilderImpl\n implements CmsEntryOpenSearchBodyBuilderAbstraction.Interface\n{\n public constructor(\n private readonly execFiltering: CmsEntryOpenSearchExecFiltering.Interface,\n private readonly fieldPathFactory: CmsEntryOpenSearchFieldPathFactory.Interface,\n private readonly fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface,\n private readonly fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface,\n private readonly bodyModifiers: CmsEntryOpenSearchBodyModifier.Interface[],\n private readonly sortModifiers: CmsEntryOpenSearchSortModifier.Interface[],\n private readonly queryModifiers: CmsEntryOpenSearchQueryModifier.Interface[],\n private readonly valueSearchRegistry: CmsEntryOpenSearchValueSearchRegistry.Interface,\n private readonly fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[],\n private readonly fieldFactory: OpenSearchFieldFactory.Interface,\n private readonly entrySystemFields: CmsEntrySystemField.Interface[]\n ) {}\n\n public build(params: CmsEntryOpenSearchBodyBuilderAbstraction.Params): SearchBody {\n const { model, shared } = params;\n const { fields, search: term, where, sort: initialSort, after, limit } = params.params;\n\n const modelFields = createModelFields({\n model,\n fieldRegistry: this.fieldRegistry,\n fieldIndexRegistry: this.fieldIndexRegistry,\n systemFields: this.entrySystemFields.map(systemField => systemField.field)\n });\n\n const applicableQueryModifiers = this.queryModifiers.filter(m => {\n return !m.modelId || m.modelId === model.modelId;\n });\n const applicableSortModifiers = this.sortModifiers.filter(\n m => !m.modelId || m.modelId === model.modelId\n );\n const applicableBodyModifiers = this.bodyModifiers.filter(m => {\n return !m.modelId || m.modelId === model.modelId;\n });\n\n const fullTextSearchFields = createFullTextSearchFields({\n fields: modelFields,\n term,\n targets: fields\n });\n\n const query = createInitialQuery({\n where,\n model,\n shared\n });\n\n applyFullTextSearch({\n model,\n fullTextSearches: this.fullTextSearches,\n query,\n term,\n fields: fullTextSearchFields\n });\n\n this.execFiltering.execute({\n model,\n fields: modelFields,\n where,\n query\n });\n\n for (const modifier of applicableQueryModifiers) {\n modifier.modifyQuery({ query, model, where });\n }\n\n const sort = createElasticsearchSort({\n sort: initialSort,\n modelFields,\n model,\n fieldPathFactory: this.fieldPathFactory,\n valueSearchRegistry: this.valueSearchRegistry,\n fieldFactory: this.fieldFactory\n });\n\n for (const modifier of applicableSortModifiers) {\n modifier.modifySort({\n sort,\n model\n });\n }\n\n const boolQuery: BoolQueryConfig = {\n must: query.must.length > 0 ? query.must : undefined,\n must_not: query.must_not.length > 0 ? query.must_not : undefined,\n should: query.should.length > 0 ? query.should : undefined,\n filter: query.filter.length > 0 ? query.filter : undefined\n };\n\n assignMinimumShouldMatchToQuery({\n query: boolQuery\n });\n\n const body: SearchBody = {\n query: {\n bool: boolQuery\n },\n sort,\n size: (limit || 0) + 1,\n search_after: after,\n track_total_hits: true\n };\n\n for (const modifier of applicableBodyModifiers) {\n modifier.modifyBody({\n body,\n model,\n where\n });\n }\n\n return body;\n }\n}\n\nexport const CmsEntryOpenSearchBodyBuilder =\n CmsEntryOpenSearchBodyBuilderAbstraction.createImplementation({\n implementation: CmsEntryOpenSearchBodyBuilderImpl,\n dependencies: [\n CmsEntryOpenSearchExecFiltering,\n CmsEntryOpenSearchFieldPathFactory,\n CmsModelFieldToGraphQLRegistry,\n CmsEntryOpenSearchFieldIndexRegistry,\n [CmsEntryOpenSearchBodyModifier, { multiple: true }],\n [CmsEntryOpenSearchSortModifier, { multiple: true }],\n [CmsEntryOpenSearchQueryModifier, { multiple: true }],\n CmsEntryOpenSearchValueSearchRegistry,\n [CmsEntryOpenSearchFullTextSearch, { multiple: true }],\n OpenSearchFieldFactory,\n [CmsEntrySystemField, { multiple: true }]\n ]\n });\n"],"names":["CmsEntryOpenSearchBodyBuilderImpl","execFiltering","fieldPathFactory","fieldRegistry","fieldIndexRegistry","bodyModifiers","sortModifiers","queryModifiers","valueSearchRegistry","fullTextSearches","fieldFactory","entrySystemFields","params","model","shared","fields","term","where","initialSort","after","limit","modelFields","createModelFields","systemField","applicableQueryModifiers","m","applicableSortModifiers","applicableBodyModifiers","fullTextSearchFields","createFullTextSearchFields","query","createInitialQuery","applyFullTextSearch","modifier","sort","createElasticsearchSort","boolQuery","undefined","assignMinimumShouldMatchToQuery","body","CmsEntryOpenSearchBodyBuilder","CmsEntryOpenSearchBodyBuilderAbstraction","CmsEntryOpenSearchExecFiltering","CmsEntryOpenSearchFieldPathFactory","CmsModelFieldToGraphQLRegistry","CmsEntryOpenSearchFieldIndexRegistry","CmsEntryOpenSearchBodyModifier","CmsEntryOpenSearchSortModifier","CmsEntryOpenSearchQueryModifier","CmsEntryOpenSearchValueSearchRegistry","CmsEntryOpenSearchFullTextSearch","OpenSearchFieldFactory","CmsEntrySystemField"],"mappings":"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"}
|
|
@@ -3,6 +3,10 @@ import type { CmsEntryListParams, CmsEntryListWhere } from "@webiny/api-headless
|
|
|
3
3
|
import type { PrimitiveValue, SearchBody } from "@webiny/api-opensearch/types.js";
|
|
4
4
|
export interface ICmsEntryOpenSearchBodyBuilderParams {
|
|
5
5
|
model: CmsModel;
|
|
6
|
+
/**
|
|
7
|
+
* Whether the model's index is shared between tenants, from CmsModelOpenSearchIndexProvider.
|
|
8
|
+
*/
|
|
9
|
+
shared: boolean;
|
|
6
10
|
params: Omit<CmsEntryListParams, "where" | "after"> & {
|
|
7
11
|
where: CmsEntryListWhere;
|
|
8
12
|
after?: PrimitiveValue[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features/CmsEntryOpenSearchBodyBuilder/abstractions.js","sources":["../../../src/features/CmsEntryOpenSearchBodyBuilder/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport type {\n CmsEntryListParams,\n CmsEntryListWhere\n} from \"@webiny/api-headless-cms/types/index.js\";\nimport type { PrimitiveValue, SearchBody } from \"@webiny/api-opensearch/types.js\";\n\nexport interface ICmsEntryOpenSearchBodyBuilderParams {\n model: CmsModel;\n params: Omit<CmsEntryListParams, \"where\" | \"after\"> & {\n where: CmsEntryListWhere;\n after?: PrimitiveValue[];\n };\n}\n\nexport interface ICmsEntryOpenSearchBodyBuilder {\n build(params: ICmsEntryOpenSearchBodyBuilderParams): SearchBody;\n}\n\nexport const CmsEntryOpenSearchBodyBuilder = createAbstraction<ICmsEntryOpenSearchBodyBuilder>(\n \"Cms/Entry/OpenSearch/BodyBuilder\"\n);\n\nexport namespace CmsEntryOpenSearchBodyBuilder {\n export type Interface = ICmsEntryOpenSearchBodyBuilder;\n export type Params = ICmsEntryOpenSearchBodyBuilderParams;\n}\n"],"names":["CmsEntryOpenSearchBodyBuilder","createAbstraction"],"mappings":";
|
|
1
|
+
{"version":3,"file":"features/CmsEntryOpenSearchBodyBuilder/abstractions.js","sources":["../../../src/features/CmsEntryOpenSearchBodyBuilder/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport type {\n CmsEntryListParams,\n CmsEntryListWhere\n} from \"@webiny/api-headless-cms/types/index.js\";\nimport type { PrimitiveValue, SearchBody } from \"@webiny/api-opensearch/types.js\";\n\nexport interface ICmsEntryOpenSearchBodyBuilderParams {\n model: CmsModel;\n /**\n * Whether the model's index is shared between tenants, from CmsModelOpenSearchIndexProvider.\n */\n shared: boolean;\n params: Omit<CmsEntryListParams, \"where\" | \"after\"> & {\n where: CmsEntryListWhere;\n after?: PrimitiveValue[];\n };\n}\n\nexport interface ICmsEntryOpenSearchBodyBuilder {\n build(params: ICmsEntryOpenSearchBodyBuilderParams): SearchBody;\n}\n\nexport const CmsEntryOpenSearchBodyBuilder = createAbstraction<ICmsEntryOpenSearchBodyBuilder>(\n \"Cms/Entry/OpenSearch/BodyBuilder\"\n);\n\nexport namespace CmsEntryOpenSearchBodyBuilder {\n export type Interface = ICmsEntryOpenSearchBodyBuilder;\n export type Params = ICmsEntryOpenSearchBodyBuilderParams;\n}\n"],"names":["CmsEntryOpenSearchBodyBuilder","createAbstraction"],"mappings":";AAwBO,MAAMA,gCAAgCC,kBACzC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ModelFields } from "../../../../operations/entry/elasticsearch/types.js";
|
|
2
|
+
import type { CmsModelField } from "@webiny/api-headless-cms/types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Filter fields for the fields registered as `CmsEntrySystemField`. The `system` object is indexed
|
|
5
|
+
* as-is (raw storage ids), so a text field resolves to `system.<path>.keyword`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const createEntrySystemFields: (fields: CmsModelField[]) => ModelFields;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createSystemField } from "./createSystemField.js";
|
|
2
|
+
const systemParent = {
|
|
3
|
+
fieldId: "system",
|
|
4
|
+
type: "object",
|
|
5
|
+
storageId: "system"
|
|
6
|
+
};
|
|
7
|
+
const addFields = (result, fields, parents)=>{
|
|
8
|
+
for (const field of fields){
|
|
9
|
+
const path = [
|
|
10
|
+
...parents.map((parent)=>parent.fieldId),
|
|
11
|
+
field.fieldId
|
|
12
|
+
].join(".");
|
|
13
|
+
result[path] = {
|
|
14
|
+
type: field.type,
|
|
15
|
+
systemField: true,
|
|
16
|
+
searchable: true,
|
|
17
|
+
sortable: false,
|
|
18
|
+
parents,
|
|
19
|
+
field
|
|
20
|
+
};
|
|
21
|
+
const children = field.settings?.fields;
|
|
22
|
+
if (children?.length) addFields(result, children, [
|
|
23
|
+
...parents,
|
|
24
|
+
{
|
|
25
|
+
fieldId: field.fieldId,
|
|
26
|
+
type: field.type,
|
|
27
|
+
storageId: field.storageId
|
|
28
|
+
}
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const createEntrySystemFields = (fields)=>{
|
|
33
|
+
if (0 === fields.length) return {};
|
|
34
|
+
const result = {
|
|
35
|
+
system: {
|
|
36
|
+
type: "object",
|
|
37
|
+
systemField: true,
|
|
38
|
+
searchable: true,
|
|
39
|
+
sortable: false,
|
|
40
|
+
field: createSystemField({
|
|
41
|
+
storageId: "system",
|
|
42
|
+
fieldId: "system",
|
|
43
|
+
type: "object",
|
|
44
|
+
settings: {
|
|
45
|
+
fields
|
|
46
|
+
}
|
|
47
|
+
}),
|
|
48
|
+
parents: []
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
addFields(result, fields, [
|
|
52
|
+
systemParent
|
|
53
|
+
]);
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
export { createEntrySystemFields };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations/entry/elasticsearch/fields/system.js","sources":["../../../../../src/operations/entry/elasticsearch/fields/system.ts"],"sourcesContent":["import type { ModelFieldParent, ModelFields } from \"~/operations/entry/elasticsearch/types.js\";\nimport type { CmsModelField } from \"@webiny/api-headless-cms/types/index.js\";\nimport { createSystemField } from \"./createSystemField.js\";\n\nconst systemParent: ModelFieldParent = {\n fieldId: \"system\",\n type: \"object\",\n storageId: \"system\"\n};\n\n/**\n * ObjectFilter resolves one level at a time, so every nested object needs its own entry.\n */\nconst addFields = (result: ModelFields, fields: CmsModelField[], parents: ModelFieldParent[]) => {\n for (const field of fields) {\n const path = [...parents.map(parent => parent.fieldId), field.fieldId].join(\".\");\n result[path] = {\n type: field.type,\n systemField: true,\n searchable: true,\n sortable: false,\n parents,\n field\n };\n const children = field.settings?.fields;\n if (!children?.length) {\n continue;\n }\n addFields(result, children, [\n ...parents,\n {\n fieldId: field.fieldId,\n type: field.type,\n storageId: field.storageId\n }\n ]);\n }\n};\n\n/**\n * Filter fields for the fields registered as `CmsEntrySystemField`. The `system` object is indexed\n * as-is (raw storage ids), so a text field resolves to `system.<path>.keyword`.\n */\nexport const createEntrySystemFields = (fields: CmsModelField[]): ModelFields => {\n if (fields.length === 0) {\n return {};\n }\n const result: ModelFields = {\n system: {\n type: \"object\",\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"system\",\n fieldId: \"system\",\n type: \"object\",\n settings: {\n fields\n }\n }),\n parents: []\n }\n };\n addFields(result, fields, [systemParent]);\n return result;\n};\n"],"names":["systemParent","addFields","result","fields","parents","field","path","parent","children","createEntrySystemFields","createSystemField"],"mappings":";AAIA,MAAMA,eAAiC;IACnC,SAAS;IACT,MAAM;IACN,WAAW;AACf;AAKA,MAAMC,YAAY,CAACC,QAAqBC,QAAyBC;IAC7D,KAAK,MAAMC,SAASF,OAAQ;QACxB,MAAMG,OAAO;eAAIF,QAAQ,GAAG,CAACG,CAAAA,SAAUA,OAAO,OAAO;YAAGF,MAAM,OAAO;SAAC,CAAC,IAAI,CAAC;QAC5EH,MAAM,CAACI,KAAK,GAAG;YACX,MAAMD,MAAM,IAAI;YAChB,aAAa;YACb,YAAY;YACZ,UAAU;YACVD;YACAC;QACJ;QACA,MAAMG,WAAWH,MAAM,QAAQ,EAAE;QACjC,IAAKG,UAAU,QAGfP,UAAUC,QAAQM,UAAU;eACrBJ;YACH;gBACI,SAASC,MAAM,OAAO;gBACtB,MAAMA,MAAM,IAAI;gBAChB,WAAWA,MAAM,SAAS;YAC9B;SACH;IACL;AACJ;AAMO,MAAMI,0BAA0B,CAACN;IACpC,IAAIA,AAAkB,MAAlBA,OAAO,MAAM,EACb,OAAO,CAAC;IAEZ,MAAMD,SAAsB;QACxB,QAAQ;YACJ,MAAM;YACN,aAAa;YACb,YAAY;YACZ,UAAU;YACV,OAAOQ,kBAAkB;gBACrB,WAAW;gBACX,SAAS;gBACT,MAAM;gBACN,UAAU;oBACNP;gBACJ;YACJ;YACA,SAAS,EAAE;QACf;IACJ;IACAF,UAAUC,QAAQC,QAAQ;QAACH;KAAa;IACxC,OAAOE;AACX"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import type { CmsModel } from "@webiny/api-headless-cms/types/index.js";
|
|
1
|
+
import type { CmsModel, CmsModelField } from "@webiny/api-headless-cms/types/index.js";
|
|
2
2
|
import { CmsModelFieldToGraphQLRegistry } from "@webiny/api-headless-cms/features/graphql/index.js";
|
|
3
3
|
import { CmsEntryOpenSearchFieldIndexRegistry } from "../../../features/CmsEntryOpenSearchFieldIndex/index.js";
|
|
4
4
|
interface ICreateModelFieldsParams {
|
|
5
5
|
model: CmsModel;
|
|
6
6
|
fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface;
|
|
7
7
|
fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface;
|
|
8
|
+
/** Fields registered as `CmsEntrySystemField`, filterable under `system`. */
|
|
9
|
+
systemFields: CmsModelField[];
|
|
8
10
|
}
|
|
9
|
-
export declare const createModelFields: ({ model, fieldRegistry, fieldIndexRegistry }: ICreateModelFieldsParams) => {
|
|
11
|
+
export declare const createModelFields: ({ model, fieldRegistry, fieldIndexRegistry, systemFields }: ICreateModelFieldsParams) => {
|
|
10
12
|
[x: string]: import("./types.js").ModelField;
|
|
11
13
|
};
|
|
12
14
|
export {};
|
|
@@ -5,7 +5,8 @@ import { liveFields } from "./fields/live.js";
|
|
|
5
5
|
import { createSystemField } from "./fields/createSystemField.js";
|
|
6
6
|
import { stateFields } from "./fields/state.js";
|
|
7
7
|
import { locationFields } from "./fields/location.js";
|
|
8
|
-
|
|
8
|
+
import { createEntrySystemFields } from "./fields/system.js";
|
|
9
|
+
const createSystemFields = (entrySystemFields)=>{
|
|
9
10
|
const onMetaFields = ENTRY_META_FIELDS.filter(isDateTimeEntryMetaField).reduce((current, fieldName)=>({
|
|
10
11
|
...current,
|
|
11
12
|
[fieldName]: {
|
|
@@ -128,7 +129,8 @@ const createSystemFields = ()=>{
|
|
|
128
129
|
parents: []
|
|
129
130
|
},
|
|
130
131
|
...stateFields,
|
|
131
|
-
...liveFields
|
|
132
|
+
...liveFields,
|
|
133
|
+
...createEntrySystemFields(entrySystemFields)
|
|
132
134
|
};
|
|
133
135
|
};
|
|
134
136
|
const buildFieldsList = (params)=>{
|
|
@@ -171,7 +173,7 @@ const buildFieldsList = (params)=>{
|
|
|
171
173
|
return result;
|
|
172
174
|
}, {});
|
|
173
175
|
};
|
|
174
|
-
const createModelFields = ({ model, fieldRegistry, fieldIndexRegistry })=>{
|
|
176
|
+
const createModelFields = ({ model, fieldRegistry, fieldIndexRegistry, systemFields })=>{
|
|
175
177
|
const fields = model.fields;
|
|
176
178
|
const unmappedTypes = fieldIndexRegistry.getAll().reduce((acc, fieldIndex)=>{
|
|
177
179
|
if (!fieldIndex.unmappedType) return acc;
|
|
@@ -188,7 +190,7 @@ const createModelFields = ({ model, fieldRegistry, fieldIndexRegistry })=>{
|
|
|
188
190
|
return types;
|
|
189
191
|
}, {});
|
|
190
192
|
return {
|
|
191
|
-
...createSystemFields(),
|
|
193
|
+
...createSystemFields(systemFields),
|
|
192
194
|
...buildFieldsList({
|
|
193
195
|
fields,
|
|
194
196
|
plugins: fieldTypePlugins,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations/entry/elasticsearch/fields.js","sources":["../../../../src/operations/entry/elasticsearch/fields.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { CmsModel, CmsModelField } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { ModelFieldParent, ModelFields } from \"./types.js\";\nimport {\n ENTRY_META_FIELDS,\n isDateTimeEntryMetaField,\n isIdentityEntryMetaField\n} from \"@webiny/api-headless-cms/constants.js\";\nimport { getBaseFieldType } from \"@webiny/api-headless-cms/utils/getBaseFieldType.js\";\nimport { liveFields } from \"./fields/live.js\";\nimport { createSystemField } from \"./fields/createSystemField.js\";\nimport { stateFields } from \"./fields/state.js\";\nimport { locationFields } from \"./fields/location.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/features/graphql/index.js\";\nimport { CmsEntryOpenSearchFieldIndexRegistry } from \"~/features/CmsEntryOpenSearchFieldIndex/index.js\";\n\nconst createSystemFields = (): ModelFields => {\n const onMetaFields = ENTRY_META_FIELDS.filter(isDateTimeEntryMetaField).reduce(\n (current, fieldName) => {\n return {\n ...current,\n [fieldName]: {\n type: \"date\",\n unmappedType: \"date\",\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: fieldName,\n fieldId: fieldName,\n type: \"text\",\n settings: {\n type: \"dateTimeWithoutTimezone\"\n }\n }),\n parents: []\n }\n };\n },\n {}\n );\n\n const byMetaFields = ENTRY_META_FIELDS.filter(isIdentityEntryMetaField).reduce(\n (current, fieldName) => {\n return {\n ...current,\n [fieldName]: {\n type: \"text\",\n unmappedType: undefined,\n systemField: true,\n searchable: true,\n sortable: true,\n path: `${fieldName}.id`,\n field: createSystemField({\n storageId: fieldName,\n fieldId: fieldName,\n type: \"text\"\n }),\n parents: []\n }\n };\n },\n {}\n );\n\n return {\n id: {\n type: \"text\",\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"id\",\n fieldId: \"id\",\n type: \"text\"\n }),\n parents: []\n },\n entryId: {\n type: \"text\",\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"entryId\",\n fieldId: \"entryId\",\n type: \"text\"\n }),\n parents: []\n },\n\n ...onMetaFields,\n ...byMetaFields,\n\n ...locationFields,\n version: {\n type: \"number\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"version\",\n fieldId: \"version\",\n type: \"number\"\n }),\n parents: []\n },\n status: {\n type: \"string\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"status\",\n fieldId: \"status\",\n type: \"string\"\n }),\n parents: []\n },\n wbyDeleted: {\n type: \"boolean\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"wbyDeleted\",\n fieldId: \"wbyDeleted\",\n type: \"boolean\"\n }),\n parents: []\n },\n binOriginalFolderId: {\n type: \"text\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"binOriginalFolderId\",\n fieldId: \"binOriginalFolderId\",\n type: \"text\"\n }),\n parents: []\n },\n ...stateFields,\n ...liveFields\n };\n};\n\ninterface UnmappedFieldTypes {\n [type: string]: (field: Pick<CmsModelField, \"fieldId\" | \"type\">) => string | undefined;\n}\n\ninterface FieldTypePlugin {\n unmappedType?: (field: Pick<CmsModelField, \"fieldId\" | \"type\">) => string | undefined;\n searchable: boolean;\n sortable: boolean;\n isFullTextSearchable?: boolean;\n}\n\ninterface FieldTypePlugins {\n [key: string]: FieldTypePlugin;\n}\n\ninterface BuildParams {\n plugins: FieldTypePlugins;\n fields: CmsModelField[];\n parents: ModelFieldParent[];\n}\n\nconst buildFieldsList = (params: BuildParams): ModelFields => {\n const { plugins, fields, parents } = params;\n\n return fields.reduce<ModelFields>((result, field) => {\n const fieldType = getBaseFieldType(field);\n const plugin = plugins[fieldType];\n if (!plugin) {\n throw new WebinyError(`There is no plugin for field type \"${field.type}\".`);\n }\n\n const { searchable, sortable, unmappedType, isFullTextSearchable: fullTextSearch } = plugin;\n /**\n * If a field has child fields, go through them and add them to a result.\n */\n const childFields = field.settings?.fields || [];\n if (childFields.length > 0) {\n /**\n * Let's build all the child fields\n */\n const childResult = buildFieldsList({\n fields: childFields,\n plugins,\n parents: [\n ...parents,\n {\n fieldId: field.fieldId,\n storageId: field.storageId,\n type: fieldType\n }\n ]\n });\n Object.assign(result, childResult);\n }\n\n const identifier = [...parents.map(p => p.fieldId), field.fieldId].join(\".\");\n\n result[identifier] = {\n type: fieldType,\n parents,\n searchable,\n sortable,\n fullTextSearch,\n unmappedType: typeof unmappedType === \"function\" ? unmappedType(field) : undefined,\n systemField: false,\n field\n };\n\n return result;\n }, {});\n};\n\ninterface ICreateModelFieldsParams {\n model: CmsModel;\n fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface;\n fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface;\n}\n\nexport const createModelFields = ({\n model,\n fieldRegistry,\n fieldIndexRegistry\n}: ICreateModelFieldsParams) => {\n const fields = model.fields;\n /**\n * Collect all unmappedType from field index registry.\n */\n const unmappedTypes = fieldIndexRegistry\n .getAll()\n .reduce<UnmappedFieldTypes>((acc, fieldIndex) => {\n if (!fieldIndex.unmappedType) {\n return acc;\n }\n acc[fieldIndex.fieldType] = fieldIndex.unmappedType;\n return acc;\n }, {});\n /**\n * Collect all field types from the plugins.\n */\n const fieldTypePlugins = fieldRegistry.getAll().reduce<FieldTypePlugins>((types, field) => {\n types[field.fieldType] = {\n unmappedType: unmappedTypes[field.fieldType],\n searchable: field.isSearchable,\n sortable: field.isSortable,\n isFullTextSearchable: field.isFullTextSearchable\n };\n return types;\n }, {});\n\n return {\n ...createSystemFields(),\n ...buildFieldsList({\n fields,\n plugins: fieldTypePlugins,\n parents: [\n {\n fieldId: \"values\",\n type: \"object\",\n storageId: \"values\"\n }\n ]\n })\n };\n};\n"],"names":["createSystemFields","onMetaFields","ENTRY_META_FIELDS","isDateTimeEntryMetaField","current","fieldName","createSystemField","byMetaFields","isIdentityEntryMetaField","undefined","locationFields","stateFields","liveFields","buildFieldsList","params","plugins","fields","parents","result","field","fieldType","getBaseFieldType","plugin","WebinyError","searchable","sortable","unmappedType","fullTextSearch","childFields","childResult","Object","identifier","p","createModelFields","model","fieldRegistry","fieldIndexRegistry","unmappedTypes","acc","fieldIndex","fieldTypePlugins","types"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"operations/entry/elasticsearch/fields.js","sources":["../../../../src/operations/entry/elasticsearch/fields.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { CmsModel, CmsModelField } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { ModelFieldParent, ModelFields } from \"./types.js\";\nimport {\n ENTRY_META_FIELDS,\n isDateTimeEntryMetaField,\n isIdentityEntryMetaField\n} from \"@webiny/api-headless-cms/constants.js\";\nimport { getBaseFieldType } from \"@webiny/api-headless-cms/utils/getBaseFieldType.js\";\nimport { liveFields } from \"./fields/live.js\";\nimport { createSystemField } from \"./fields/createSystemField.js\";\nimport { stateFields } from \"./fields/state.js\";\nimport { locationFields } from \"./fields/location.js\";\nimport { createEntrySystemFields } from \"./fields/system.js\";\nimport { CmsModelFieldToGraphQLRegistry } from \"@webiny/api-headless-cms/features/graphql/index.js\";\nimport { CmsEntryOpenSearchFieldIndexRegistry } from \"~/features/CmsEntryOpenSearchFieldIndex/index.js\";\n\nconst createSystemFields = (entrySystemFields: CmsModelField[]): ModelFields => {\n const onMetaFields = ENTRY_META_FIELDS.filter(isDateTimeEntryMetaField).reduce(\n (current, fieldName) => {\n return {\n ...current,\n [fieldName]: {\n type: \"date\",\n unmappedType: \"date\",\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: fieldName,\n fieldId: fieldName,\n type: \"text\",\n settings: {\n type: \"dateTimeWithoutTimezone\"\n }\n }),\n parents: []\n }\n };\n },\n {}\n );\n\n const byMetaFields = ENTRY_META_FIELDS.filter(isIdentityEntryMetaField).reduce(\n (current, fieldName) => {\n return {\n ...current,\n [fieldName]: {\n type: \"text\",\n unmappedType: undefined,\n systemField: true,\n searchable: true,\n sortable: true,\n path: `${fieldName}.id`,\n field: createSystemField({\n storageId: fieldName,\n fieldId: fieldName,\n type: \"text\"\n }),\n parents: []\n }\n };\n },\n {}\n );\n\n return {\n id: {\n type: \"text\",\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"id\",\n fieldId: \"id\",\n type: \"text\"\n }),\n parents: []\n },\n entryId: {\n type: \"text\",\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"entryId\",\n fieldId: \"entryId\",\n type: \"text\"\n }),\n parents: []\n },\n\n ...onMetaFields,\n ...byMetaFields,\n\n ...locationFields,\n version: {\n type: \"number\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: true,\n field: createSystemField({\n storageId: \"version\",\n fieldId: \"version\",\n type: \"number\"\n }),\n parents: []\n },\n status: {\n type: \"string\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"status\",\n fieldId: \"status\",\n type: \"string\"\n }),\n parents: []\n },\n wbyDeleted: {\n type: \"boolean\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"wbyDeleted\",\n fieldId: \"wbyDeleted\",\n type: \"boolean\"\n }),\n parents: []\n },\n binOriginalFolderId: {\n type: \"text\",\n unmappedType: undefined,\n keyword: false,\n systemField: true,\n searchable: true,\n sortable: false,\n field: createSystemField({\n storageId: \"binOriginalFolderId\",\n fieldId: \"binOriginalFolderId\",\n type: \"text\"\n }),\n parents: []\n },\n ...stateFields,\n ...liveFields,\n ...createEntrySystemFields(entrySystemFields)\n };\n};\n\ninterface UnmappedFieldTypes {\n [type: string]: (field: Pick<CmsModelField, \"fieldId\" | \"type\">) => string | undefined;\n}\n\ninterface FieldTypePlugin {\n unmappedType?: (field: Pick<CmsModelField, \"fieldId\" | \"type\">) => string | undefined;\n searchable: boolean;\n sortable: boolean;\n isFullTextSearchable?: boolean;\n}\n\ninterface FieldTypePlugins {\n [key: string]: FieldTypePlugin;\n}\n\ninterface BuildParams {\n plugins: FieldTypePlugins;\n fields: CmsModelField[];\n parents: ModelFieldParent[];\n}\n\nconst buildFieldsList = (params: BuildParams): ModelFields => {\n const { plugins, fields, parents } = params;\n\n return fields.reduce<ModelFields>((result, field) => {\n const fieldType = getBaseFieldType(field);\n const plugin = plugins[fieldType];\n if (!plugin) {\n throw new WebinyError(`There is no plugin for field type \"${field.type}\".`);\n }\n\n const { searchable, sortable, unmappedType, isFullTextSearchable: fullTextSearch } = plugin;\n /**\n * If a field has child fields, go through them and add them to a result.\n */\n const childFields = field.settings?.fields || [];\n if (childFields.length > 0) {\n /**\n * Let's build all the child fields\n */\n const childResult = buildFieldsList({\n fields: childFields,\n plugins,\n parents: [\n ...parents,\n {\n fieldId: field.fieldId,\n storageId: field.storageId,\n type: fieldType\n }\n ]\n });\n Object.assign(result, childResult);\n }\n\n const identifier = [...parents.map(p => p.fieldId), field.fieldId].join(\".\");\n\n result[identifier] = {\n type: fieldType,\n parents,\n searchable,\n sortable,\n fullTextSearch,\n unmappedType: typeof unmappedType === \"function\" ? unmappedType(field) : undefined,\n systemField: false,\n field\n };\n\n return result;\n }, {});\n};\n\ninterface ICreateModelFieldsParams {\n model: CmsModel;\n fieldRegistry: CmsModelFieldToGraphQLRegistry.Interface;\n fieldIndexRegistry: CmsEntryOpenSearchFieldIndexRegistry.Interface;\n /** Fields registered as `CmsEntrySystemField`, filterable under `system`. */\n systemFields: CmsModelField[];\n}\n\nexport const createModelFields = ({\n model,\n fieldRegistry,\n fieldIndexRegistry,\n systemFields\n}: ICreateModelFieldsParams) => {\n const fields = model.fields;\n /**\n * Collect all unmappedType from field index registry.\n */\n const unmappedTypes = fieldIndexRegistry\n .getAll()\n .reduce<UnmappedFieldTypes>((acc, fieldIndex) => {\n if (!fieldIndex.unmappedType) {\n return acc;\n }\n acc[fieldIndex.fieldType] = fieldIndex.unmappedType;\n return acc;\n }, {});\n /**\n * Collect all field types from the plugins.\n */\n const fieldTypePlugins = fieldRegistry.getAll().reduce<FieldTypePlugins>((types, field) => {\n types[field.fieldType] = {\n unmappedType: unmappedTypes[field.fieldType],\n searchable: field.isSearchable,\n sortable: field.isSortable,\n isFullTextSearchable: field.isFullTextSearchable\n };\n return types;\n }, {});\n\n return {\n ...createSystemFields(systemFields),\n ...buildFieldsList({\n fields,\n plugins: fieldTypePlugins,\n parents: [\n {\n fieldId: \"values\",\n type: \"object\",\n storageId: \"values\"\n }\n ]\n })\n };\n};\n"],"names":["createSystemFields","entrySystemFields","onMetaFields","ENTRY_META_FIELDS","isDateTimeEntryMetaField","current","fieldName","createSystemField","byMetaFields","isIdentityEntryMetaField","undefined","locationFields","stateFields","liveFields","createEntrySystemFields","buildFieldsList","params","plugins","fields","parents","result","field","fieldType","getBaseFieldType","plugin","WebinyError","searchable","sortable","unmappedType","fullTextSearch","childFields","childResult","Object","identifier","p","createModelFields","model","fieldRegistry","fieldIndexRegistry","systemFields","unmappedTypes","acc","fieldIndex","fieldTypePlugins","types"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ const defaultFullTextSearch = {
|
|
|
5
5
|
query.must.push({
|
|
6
6
|
query_string: {
|
|
7
7
|
allow_leading_wildcard: true,
|
|
8
|
+
lenient: true,
|
|
8
9
|
fields: Object.values(fields).map(createFieldPath),
|
|
9
10
|
query: `*${prepareTerm(term)}*`,
|
|
10
11
|
default_operator: "and"
|
|
@@ -38,7 +39,15 @@ const applyFullTextSearch = (params)=>{
|
|
|
38
39
|
createFieldPath: (field)=>{
|
|
39
40
|
if ("function" == typeof field.path) return field.path(term);
|
|
40
41
|
if (field.systemField) return field.path || field.field.storageId;
|
|
41
|
-
|
|
42
|
+
const parents = field.parents.length > 0 ? field.parents.map((p)=>p.storageId) : [
|
|
43
|
+
"values"
|
|
44
|
+
];
|
|
45
|
+
const path = [
|
|
46
|
+
...parents,
|
|
47
|
+
field.path || field.field.storageId
|
|
48
|
+
].join(".");
|
|
49
|
+
if ("searchable-json" === field.type) return `${path}.*`;
|
|
50
|
+
return path;
|
|
42
51
|
},
|
|
43
52
|
fields,
|
|
44
53
|
query,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations/entry/elasticsearch/fullTextSearch.js","sources":["../../../../src/operations/entry/elasticsearch/fullTextSearch.ts"],"sourcesContent":["import type { OpenSearchBoolQueryConfig } from \"@webiny/api-opensearch/types.js\";\nimport { normalizeValue } from \"@webiny/api-opensearch\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { CmsEntryOpenSearchFullTextSearch } from \"~/features/CmsEntryOpenSearchFullTextSearch/index.js\";\nimport type { ModelFields } from \"~/operations/entry/elasticsearch/types.js\";\n\n/**\n * Our default implementation works with the AND operator for the multiple words query string.\n */\nconst defaultFullTextSearch: CmsEntryOpenSearchFullTextSearch.Interface = {\n apply: params => {\n const { query, term, fields, createFieldPath, prepareTerm } = params;\n\n query.must.push({\n query_string: {\n allow_leading_wildcard: true,\n fields: Object.values(fields).map(createFieldPath),\n query: `*${prepareTerm(term)}*`,\n default_operator: \"and\"\n }\n });\n }\n};\n\ninterface GetFullTextSearchParams {\n fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[];\n model: CmsModel;\n}\nconst getFullTextSearch = (\n params: GetFullTextSearchParams\n): CmsEntryOpenSearchFullTextSearch.Interface => {\n const { fullTextSearches, model } = params;\n /**\n * We need to reverse the list, so we can take the last one first - possibility to override existing implementations.\n */\n const reversed = [...fullTextSearches].reverse();\n /**\n * We need to find the most specific implementation for the given model.\n * Also, we need to use the first possible implementation if the specific one is not found.\n */\n let fallback: CmsEntryOpenSearchFullTextSearch.Interface | null = null;\n for (const item of reversed) {\n const models = item.models || [];\n /**\n * We take the first available implementation for the given model.\n */\n if (models.includes(model.modelId)) {\n return item;\n } else if (!fallback && models.length === 0) {\n /**\n * Then we set the first possible implementation, which has no models defined, as the default one.\n * It is important not to set the one which has models defined as they are specifically for the targeted model.\n */\n fallback = item;\n }\n }\n\n return fallback || defaultFullTextSearch;\n};\n\ninterface Params {\n fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[];\n model: CmsModel;\n query: OpenSearchBoolQueryConfig;\n term?: string;\n fields: ModelFields;\n}\nexport const applyFullTextSearch = (params: Params): void => {\n const { fullTextSearches, query, term, fields, model } = params;\n const keys = Object.keys(fields);\n if (!term || term.length === 0 || keys.length === 0) {\n return;\n }\n\n const fullTextSearch = getFullTextSearch({\n fullTextSearches,\n model\n });\n\n fullTextSearch.apply({\n model,\n createFieldPath: field => {\n if (typeof field.path === \"function\") {\n return field.path(term);\n } else if (field.systemField) {\n return field.path || field.field.storageId;\n }\n
|
|
1
|
+
{"version":3,"file":"operations/entry/elasticsearch/fullTextSearch.js","sources":["../../../../src/operations/entry/elasticsearch/fullTextSearch.ts"],"sourcesContent":["import type { OpenSearchBoolQueryConfig } from \"@webiny/api-opensearch/types.js\";\nimport { normalizeValue } from \"@webiny/api-opensearch\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport type { CmsEntryOpenSearchFullTextSearch } from \"~/features/CmsEntryOpenSearchFullTextSearch/index.js\";\nimport type { ModelFields } from \"~/operations/entry/elasticsearch/types.js\";\n\n/**\n * Our default implementation works with the AND operator for the multiple words query string.\n */\nconst defaultFullTextSearch: CmsEntryOpenSearchFullTextSearch.Interface = {\n apply: params => {\n const { query, term, fields, createFieldPath, prepareTerm } = params;\n\n query.must.push({\n query_string: {\n allow_leading_wildcard: true,\n /**\n * Searchable JSON fields are dynamically mapped, so their subfields can be of any type (date, number, boolean...).\n * Wildcard queries are not allowed on those types, so we need to ignore them instead of failing the whole query.\n */\n lenient: true,\n fields: Object.values(fields).map(createFieldPath),\n query: `*${prepareTerm(term)}*`,\n default_operator: \"and\"\n }\n });\n }\n};\n\ninterface GetFullTextSearchParams {\n fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[];\n model: CmsModel;\n}\nconst getFullTextSearch = (\n params: GetFullTextSearchParams\n): CmsEntryOpenSearchFullTextSearch.Interface => {\n const { fullTextSearches, model } = params;\n /**\n * We need to reverse the list, so we can take the last one first - possibility to override existing implementations.\n */\n const reversed = [...fullTextSearches].reverse();\n /**\n * We need to find the most specific implementation for the given model.\n * Also, we need to use the first possible implementation if the specific one is not found.\n */\n let fallback: CmsEntryOpenSearchFullTextSearch.Interface | null = null;\n for (const item of reversed) {\n const models = item.models || [];\n /**\n * We take the first available implementation for the given model.\n */\n if (models.includes(model.modelId)) {\n return item;\n } else if (!fallback && models.length === 0) {\n /**\n * Then we set the first possible implementation, which has no models defined, as the default one.\n * It is important not to set the one which has models defined as they are specifically for the targeted model.\n */\n fallback = item;\n }\n }\n\n return fallback || defaultFullTextSearch;\n};\n\ninterface Params {\n fullTextSearches: CmsEntryOpenSearchFullTextSearch.Interface[];\n model: CmsModel;\n query: OpenSearchBoolQueryConfig;\n term?: string;\n fields: ModelFields;\n}\nexport const applyFullTextSearch = (params: Params): void => {\n const { fullTextSearches, query, term, fields, model } = params;\n const keys = Object.keys(fields);\n if (!term || term.length === 0 || keys.length === 0) {\n return;\n }\n\n const fullTextSearch = getFullTextSearch({\n fullTextSearches,\n model\n });\n\n fullTextSearch.apply({\n model,\n createFieldPath: field => {\n if (typeof field.path === \"function\") {\n return field.path(term);\n } else if (field.systemField) {\n return field.path || field.field.storageId;\n }\n /**\n * Fields can live inside object fields, so we need to prepend the storage ids of all the parents.\n * Root fields have the `values` parent only.\n */\n const parents =\n field.parents.length > 0 ? field.parents.map(p => p.storageId) : [\"values\"];\n const path = [...parents, field.path || field.field.storageId].join(\".\");\n /*\n * Searchable JSON fields are indexed as objects, so the searchable values live on the\n * nested keys. Target all of them with a wildcard.\n */\n if (field.type === \"searchable-json\") {\n return `${path}.*`;\n }\n return path;\n },\n fields,\n query,\n term,\n prepareTerm: normalizeValue\n });\n};\n"],"names":["defaultFullTextSearch","params","query","term","fields","createFieldPath","prepareTerm","Object","getFullTextSearch","fullTextSearches","model","reversed","fallback","item","models","applyFullTextSearch","keys","fullTextSearch","field","parents","p","path","normalizeValue"],"mappings":";AASA,MAAMA,wBAAoE;IACtE,OAAOC,CAAAA;QACH,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAEC,MAAM,EAAEC,eAAe,EAAEC,WAAW,EAAE,GAAGL;QAE9DC,MAAM,IAAI,CAAC,IAAI,CAAC;YACZ,cAAc;gBACV,wBAAwB;gBAKxB,SAAS;gBACT,QAAQK,OAAO,MAAM,CAACH,QAAQ,GAAG,CAACC;gBAClC,OAAO,CAAC,CAAC,EAAEC,YAAYH,MAAM,CAAC,CAAC;gBAC/B,kBAAkB;YACtB;QACJ;IACJ;AACJ;AAMA,MAAMK,oBAAoB,CACtBP;IAEA,MAAM,EAAEQ,gBAAgB,EAAEC,KAAK,EAAE,GAAGT;IAIpC,MAAMU,WAAW;WAAIF;KAAiB,CAAC,OAAO;IAK9C,IAAIG,WAA8D;IAClE,KAAK,MAAMC,QAAQF,SAAU;QACzB,MAAMG,SAASD,KAAK,MAAM,IAAI,EAAE;QAIhC,IAAIC,OAAO,QAAQ,CAACJ,MAAM,OAAO,GAC7B,OAAOG;QACJ,IAAI,CAACD,YAAYE,AAAkB,MAAlBA,OAAO,MAAM,EAKjCF,WAAWC;IAEnB;IAEA,OAAOD,YAAYZ;AACvB;AASO,MAAMe,sBAAsB,CAACd;IAChC,MAAM,EAAEQ,gBAAgB,EAAEP,KAAK,EAAEC,IAAI,EAAEC,MAAM,EAAEM,KAAK,EAAE,GAAGT;IACzD,MAAMe,OAAOT,OAAO,IAAI,CAACH;IACzB,IAAI,CAACD,QAAQA,AAAgB,MAAhBA,KAAK,MAAM,IAAUa,AAAgB,MAAhBA,KAAK,MAAM,EACzC;IAGJ,MAAMC,iBAAiBT,kBAAkB;QACrCC;QACAC;IACJ;IAEAO,eAAe,KAAK,CAAC;QACjBP;QACA,iBAAiBQ,CAAAA;YACb,IAAI,AAAsB,cAAtB,OAAOA,MAAM,IAAI,EACjB,OAAOA,MAAM,IAAI,CAACf;YACf,IAAIe,MAAM,WAAW,EACxB,OAAOA,MAAM,IAAI,IAAIA,MAAM,KAAK,CAAC,SAAS;YAM9C,MAAMC,UACFD,MAAM,OAAO,CAAC,MAAM,GAAG,IAAIA,MAAM,OAAO,CAAC,GAAG,CAACE,CAAAA,IAAKA,EAAE,SAAS,IAAI;gBAAC;aAAS;YAC/E,MAAMC,OAAO;mBAAIF;gBAASD,MAAM,IAAI,IAAIA,MAAM,KAAK,CAAC,SAAS;aAAC,CAAC,IAAI,CAAC;YAKpE,IAAIA,AAAe,sBAAfA,MAAM,IAAI,EACV,OAAO,GAAGG,KAAK,EAAE,CAAC;YAEtB,OAAOA;QACX;QACAjB;QACAF;QACAC;QACA,aAAamB;IACjB;AACJ"}
|
|
@@ -2,6 +2,10 @@ import type { OpenSearchBoolQueryConfig } from "@webiny/api-opensearch/types.js"
|
|
|
2
2
|
import type { CmsEntryListWhere, CmsModel } from "@webiny/api-headless-cms/types/index.js";
|
|
3
3
|
export declare const createBaseQuery: () => OpenSearchBoolQueryConfig;
|
|
4
4
|
interface Params {
|
|
5
|
+
/**
|
|
6
|
+
* Whether the model's index is shared between tenants, from CmsModelOpenSearchIndexProvider.
|
|
7
|
+
*/
|
|
8
|
+
shared: boolean;
|
|
5
9
|
model: CmsModel;
|
|
6
10
|
where: CmsEntryListWhere;
|
|
7
11
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import error from "@webiny/error";
|
|
2
2
|
import { createLatestRecordType, createPublishedRecordType } from "../recordType.js";
|
|
3
|
-
import { isSharedOpenSearchIndex } from "@webiny/api-opensearch";
|
|
4
3
|
const createBaseQuery = ()=>({
|
|
5
4
|
must: [],
|
|
6
5
|
must_not: [],
|
|
@@ -8,10 +7,9 @@ const createBaseQuery = ()=>({
|
|
|
8
7
|
filter: []
|
|
9
8
|
});
|
|
10
9
|
const createInitialQuery = (params)=>{
|
|
11
|
-
const { model, where } = params;
|
|
10
|
+
const { model, where, shared } = params;
|
|
12
11
|
const query = createBaseQuery();
|
|
13
|
-
|
|
14
|
-
if (sharedIndex) {
|
|
12
|
+
if (shared) {
|
|
15
13
|
query.filter.push({
|
|
16
14
|
term: {
|
|
17
15
|
"tenant.keyword": model.tenant
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations/entry/elasticsearch/initialQuery.js","sources":["../../../../src/operations/entry/elasticsearch/initialQuery.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { OpenSearchBoolQueryConfig } from \"@webiny/api-opensearch/types.js\";\nimport type { CmsEntryListWhere, CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { createLatestRecordType, createPublishedRecordType } from \"../recordType.js\";\
|
|
1
|
+
{"version":3,"file":"operations/entry/elasticsearch/initialQuery.js","sources":["../../../../src/operations/entry/elasticsearch/initialQuery.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport type { OpenSearchBoolQueryConfig } from \"@webiny/api-opensearch/types.js\";\nimport type { CmsEntryListWhere, CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { createLatestRecordType, createPublishedRecordType } from \"../recordType.js\";\n\nexport const createBaseQuery = (): OpenSearchBoolQueryConfig => {\n return {\n must: [],\n must_not: [],\n should: [],\n filter: []\n };\n};\n\ninterface Params {\n /**\n * Whether the model's index is shared between tenants, from CmsModelOpenSearchIndexProvider.\n */\n shared: boolean;\n model: CmsModel;\n where: CmsEntryListWhere;\n}\n/**\n * Latest and published are specific in Elasticsearch to that extend that they are tagged in the __type property.\n * We allow either published or either latest.\n * Latest is used in the manage API and published in the read API.\n *\n *\n * We add the query.filter terms because we do not need scored search here and it is a bit faster.\n */\nexport const createInitialQuery = (params: Params): OpenSearchBoolQueryConfig => {\n const { model, where, shared } = params;\n\n const query = createBaseQuery();\n\n /**\n * When the index is shared between tenants, filter records by tenant ID. The model's index\n * provider decides, so a decorator that isolates or shares an index per model is respected.\n */\n if (shared) {\n /**\n * Tenant for the filtering is taken from the model.\n *\n * TODO determine if we want to send it in the \"where\" parameter?\n */\n query.filter.push({\n term: {\n \"tenant.keyword\": model.tenant\n }\n });\n /**\n * Also, we must search only in selected model.\n */\n query.filter.push({\n term: {\n \"modelId.keyword\": model.modelId\n }\n });\n }\n\n /**\n * We must transform published and latest where args into something that is understandable by our Elasticsearch\n */\n if (where.published === true) {\n query.filter.push({\n term: {\n \"__type.keyword\": createPublishedRecordType()\n }\n });\n } else if (where.latest === true) {\n query.filter.push({\n term: {\n \"__type.keyword\": createLatestRecordType()\n }\n });\n }\n //\n /**\n * We do not allow filtering without the published or latest parameter.\n * Also, we do not want to set the default one, as there is a large possibility for user error when filtering.\n */\n else {\n throw new WebinyError(\n `Cannot call Elasticsearch query when not setting \"published\" or \"latest\".`,\n \"OPENSEARCH_UNSUPPORTED_QUERY\",\n {\n where\n }\n );\n }\n /**\n * We need to remove fields that actually do not exist on the record - it will break otherwise.\n * This will modify the original object, which is what we want.\n */\n delete where.published;\n delete where.latest;\n\n return query;\n};\n"],"names":["createBaseQuery","createInitialQuery","params","model","where","shared","query","createPublishedRecordType","createLatestRecordType","WebinyError"],"mappings":";;AAKO,MAAMA,kBAAkB,IACpB;QACH,MAAM,EAAE;QACR,UAAU,EAAE;QACZ,QAAQ,EAAE;QACV,QAAQ,EAAE;IACd;AAmBG,MAAMC,qBAAqB,CAACC;IAC/B,MAAM,EAAEC,KAAK,EAAEC,KAAK,EAAEC,MAAM,EAAE,GAAGH;IAEjC,MAAMI,QAAQN;IAMd,IAAIK,QAAQ;QAMRC,MAAM,MAAM,CAAC,IAAI,CAAC;YACd,MAAM;gBACF,kBAAkBH,MAAM,MAAM;YAClC;QACJ;QAIAG,MAAM,MAAM,CAAC,IAAI,CAAC;YACd,MAAM;gBACF,mBAAmBH,MAAM,OAAO;YACpC;QACJ;IACJ;IAKA,IAAIC,AAAoB,SAApBA,MAAM,SAAS,EACfE,MAAM,MAAM,CAAC,IAAI,CAAC;QACd,MAAM;YACF,kBAAkBC;QACtB;IACJ;SACG,IAAIH,AAAiB,SAAjBA,MAAM,MAAM,EACnBE,MAAM,MAAM,CAAC,IAAI,CAAC;QACd,MAAM;YACF,kBAAkBE;QACtB;IACJ;SAQA,MAAM,IAAIC,MACN,6EACA,gCACA;QACIL;IACJ;IAOR,OAAOA,MAAM,SAAS;IACtB,OAAOA,MAAM,MAAM;IAEnB,OAAOE;AACX"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { createInitialQuery } from "./initialQuery.js";
|
|
3
|
+
const model = {
|
|
4
|
+
modelId: "article",
|
|
5
|
+
tenant: "acme"
|
|
6
|
+
};
|
|
7
|
+
const tenantFilter = {
|
|
8
|
+
term: {
|
|
9
|
+
"tenant.keyword": "acme"
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const modelFilter = {
|
|
13
|
+
term: {
|
|
14
|
+
"modelId.keyword": "article"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
describe("createInitialQuery", ()=>{
|
|
18
|
+
const original = process.env.OPENSEARCH_SHARED_INDEXES;
|
|
19
|
+
afterEach(()=>{
|
|
20
|
+
process.env.OPENSEARCH_SHARED_INDEXES = original;
|
|
21
|
+
});
|
|
22
|
+
it("filters by tenant and model when the index is shared, even if the variable says otherwise", ()=>{
|
|
23
|
+
process.env.OPENSEARCH_SHARED_INDEXES = "false";
|
|
24
|
+
const query = createInitialQuery({
|
|
25
|
+
model: model,
|
|
26
|
+
where: {
|
|
27
|
+
latest: true
|
|
28
|
+
},
|
|
29
|
+
shared: true
|
|
30
|
+
});
|
|
31
|
+
expect(query.filter).toContainEqual(tenantFilter);
|
|
32
|
+
expect(query.filter).toContainEqual(modelFilter);
|
|
33
|
+
});
|
|
34
|
+
it("doesn't filter by tenant when the index isn't shared, even if the variable says it is", ()=>{
|
|
35
|
+
process.env.OPENSEARCH_SHARED_INDEXES = "true";
|
|
36
|
+
const query = createInitialQuery({
|
|
37
|
+
model: model,
|
|
38
|
+
where: {
|
|
39
|
+
latest: true
|
|
40
|
+
},
|
|
41
|
+
shared: false
|
|
42
|
+
});
|
|
43
|
+
expect(query.filter).not.toContainEqual(tenantFilter);
|
|
44
|
+
expect(query.filter).not.toContainEqual(modelFilter);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=initialQuery.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations/entry/elasticsearch/initialQuery.test.js","sources":["../../../../src/operations/entry/elasticsearch/initialQuery.test.ts"],"sourcesContent":["import { afterEach, describe, expect, it } from \"vitest\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types/index.js\";\nimport { createInitialQuery } from \"./initialQuery.js\";\n\nconst model = { modelId: \"article\", tenant: \"acme\" } as CmsModel;\n\nconst tenantFilter = { term: { \"tenant.keyword\": \"acme\" } };\nconst modelFilter = { term: { \"modelId.keyword\": \"article\" } };\n\n/*\n * Whether entries are filtered by tenant must follow the model's index (CmsModelOpenSearchIndex),\n * not the OPENSEARCH_SHARED_INDEXES variable. A decorator can isolate or share an index per model,\n * so the two can disagree.\n */\ndescribe(\"createInitialQuery\", () => {\n const original = process.env.OPENSEARCH_SHARED_INDEXES;\n\n afterEach(() => {\n process.env.OPENSEARCH_SHARED_INDEXES = original;\n });\n\n it(\"filters by tenant and model when the index is shared, even if the variable says otherwise\", () => {\n process.env.OPENSEARCH_SHARED_INDEXES = \"false\";\n\n const query = createInitialQuery({ model, where: { latest: true }, shared: true });\n\n expect(query.filter).toContainEqual(tenantFilter);\n expect(query.filter).toContainEqual(modelFilter);\n });\n\n it(\"doesn't filter by tenant when the index isn't shared, even if the variable says it is\", () => {\n process.env.OPENSEARCH_SHARED_INDEXES = \"true\";\n\n const query = createInitialQuery({ model, where: { latest: true }, shared: false });\n\n expect(query.filter).not.toContainEqual(tenantFilter);\n expect(query.filter).not.toContainEqual(modelFilter);\n });\n});\n"],"names":["model","tenantFilter","modelFilter","describe","original","process","afterEach","it","query","createInitialQuery","expect"],"mappings":";;AAIA,MAAMA,QAAQ;IAAE,SAAS;IAAW,QAAQ;AAAO;AAEnD,MAAMC,eAAe;IAAE,MAAM;QAAE,kBAAkB;IAAO;AAAE;AAC1D,MAAMC,cAAc;IAAE,MAAM;QAAE,mBAAmB;IAAU;AAAE;AAO7DC,SAAS,sBAAsB;IAC3B,MAAMC,WAAWC,QAAQ,GAAG,CAAC,yBAAyB;IAEtDC,UAAU;QACND,QAAQ,GAAG,CAAC,yBAAyB,GAAGD;IAC5C;IAEAG,GAAG,6FAA6F;QAC5FF,QAAQ,GAAG,CAAC,yBAAyB,GAAG;QAExC,MAAMG,QAAQC,mBAAmB;YAAET,OAAAA;YAAO,OAAO;gBAAE,QAAQ;YAAK;YAAG,QAAQ;QAAK;QAEhFU,OAAOF,MAAM,MAAM,EAAE,cAAc,CAACP;QACpCS,OAAOF,MAAM,MAAM,EAAE,cAAc,CAACN;IACxC;IAEAK,GAAG,yFAAyF;QACxFF,QAAQ,GAAG,CAAC,yBAAyB,GAAG;QAExC,MAAMG,QAAQC,mBAAmB;YAAET,OAAAA;YAAO,OAAO;gBAAE,QAAQ;YAAK;YAAG,QAAQ;QAAM;QAEjFU,OAAOF,MAAM,MAAM,EAAE,GAAG,CAAC,cAAc,CAACP;QACxCS,OAAOF,MAAM,MAAM,EAAE,GAAG,CAAC,cAAc,CAACN;IAC5C;AACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/api-headless-cms-utils-os",
|
|
3
|
-
"version": "0.0.0-unstable.
|
|
3
|
+
"version": "0.0.0-unstable.a85ef555b2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"author": "Webiny Ltd.",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@webiny/api-headless-cms": "0.0.0-unstable.
|
|
19
|
-
"@webiny/api-opensearch": "0.0.0-unstable.
|
|
20
|
-
"@webiny/error": "0.0.0-unstable.
|
|
21
|
-
"@webiny/feature": "0.0.0-unstable.
|
|
18
|
+
"@webiny/api-headless-cms": "0.0.0-unstable.a85ef555b2",
|
|
19
|
+
"@webiny/api-opensearch": "0.0.0-unstable.a85ef555b2",
|
|
20
|
+
"@webiny/error": "0.0.0-unstable.a85ef555b2",
|
|
21
|
+
"@webiny/feature": "0.0.0-unstable.a85ef555b2"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@webiny/build-tools": "0.0.0-unstable.
|
|
25
|
-
"typescript": "7.0.2"
|
|
24
|
+
"@webiny/build-tools": "0.0.0-unstable.a85ef555b2",
|
|
25
|
+
"typescript": "7.0.2",
|
|
26
|
+
"vitest": "4.1.11"
|
|
26
27
|
},
|
|
27
28
|
"publishConfig": {
|
|
28
29
|
"access": "public"
|