@dotcms/client 0.0.1-alpha.38 → 0.0.1-alpha.39
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/.eslintrc.json +18 -0
- package/jest.config.ts +15 -0
- package/package.json +3 -15
- package/project.json +72 -0
- package/src/index.ts +30 -0
- package/src/lib/client/content/builders/collection/collection.spec.ts +515 -0
- package/src/lib/client/content/builders/collection/{collection.d.ts → collection.ts} +209 -19
- package/src/lib/client/content/{content-api.d.ts → content-api.ts} +14 -4
- package/src/lib/client/content/shared/{const.d.ts → const.ts} +5 -3
- package/src/lib/client/content/shared/{types.d.ts → types.ts} +19 -2
- package/src/lib/client/content/shared/{utils.d.ts → utils.ts} +9 -1
- package/src/lib/client/models/{index.d.ts → index.ts} +8 -1
- package/src/lib/client/models/{types.d.ts → types.ts} +1 -0
- package/src/lib/client/sdk-js-client.spec.ts +483 -0
- package/src/lib/client/{sdk-js-client.d.ts → sdk-js-client.ts} +181 -15
- package/src/lib/editor/listeners/listeners.spec.ts +119 -0
- package/src/lib/editor/listeners/listeners.ts +223 -0
- package/src/lib/editor/models/{client.model.d.ts → client.model.ts} +19 -16
- package/src/lib/editor/models/{editor.model.d.ts → editor.model.ts} +9 -5
- package/src/lib/editor/models/{listeners.model.d.ts → listeners.model.ts} +9 -6
- package/src/lib/editor/sdk-editor-vtl.ts +31 -0
- package/src/lib/editor/sdk-editor.spec.ts +116 -0
- package/src/lib/editor/sdk-editor.ts +105 -0
- package/src/lib/editor/utils/editor.utils.spec.ts +206 -0
- package/src/lib/editor/utils/{editor.utils.d.ts → editor.utils.ts} +121 -22
- package/src/lib/query-builder/lucene-syntax/{Equals.d.ts → Equals.ts} +45 -11
- package/src/lib/query-builder/lucene-syntax/{Field.d.ts → Field.ts} +13 -5
- package/src/lib/query-builder/lucene-syntax/{NotOperand.d.ts → NotOperand.ts} +13 -5
- package/src/lib/query-builder/lucene-syntax/{Operand.d.ts → Operand.ts} +21 -7
- package/src/lib/query-builder/sdk-query-builder.spec.ts +159 -0
- package/src/lib/query-builder/{sdk-query-builder.d.ts → sdk-query-builder.ts} +16 -5
- package/src/lib/query-builder/utils/{index.d.ts → index.ts} +49 -12
- package/src/lib/utils/graphql/transforms.spec.ts +150 -0
- package/src/lib/utils/graphql/transforms.ts +99 -0
- package/src/lib/utils/page/common-utils.spec.ts +37 -0
- package/src/lib/utils/page/common-utils.ts +64 -0
- package/tsconfig.json +22 -0
- package/tsconfig.lib.json +13 -0
- package/tsconfig.spec.json +9 -0
- package/index.cjs.d.ts +0 -1
- package/index.cjs.default.js +0 -1
- package/index.cjs.js +0 -1953
- package/index.cjs.mjs +0 -2
- package/index.esm.d.ts +0 -1
- package/index.esm.js +0 -1944
- package/src/index.d.ts +0 -6
- package/src/lib/editor/listeners/listeners.d.ts +0 -50
- package/src/lib/editor/sdk-editor-vtl.d.ts +0 -6
- package/src/lib/editor/sdk-editor.d.ts +0 -54
- package/src/lib/utils/graphql/transforms.d.ts +0 -24
- package/src/lib/utils/page/common-utils.d.ts +0 -33
- /package/src/lib/query-builder/lucene-syntax/{index.d.ts → index.ts} +0 -0
- /package/src/lib/utils/{index.d.ts → index.ts} +0 -0
|
@@ -15,6 +15,7 @@ interface ContentletBound {
|
|
|
15
15
|
height: number;
|
|
16
16
|
payload: string;
|
|
17
17
|
}
|
|
18
|
+
|
|
18
19
|
/**
|
|
19
20
|
* Bound information for a container.
|
|
20
21
|
*
|
|
@@ -34,6 +35,7 @@ interface ContainerBound {
|
|
|
34
35
|
payload: string;
|
|
35
36
|
contentlets: ContentletBound[];
|
|
36
37
|
}
|
|
38
|
+
|
|
37
39
|
/**
|
|
38
40
|
* Calculates the bounding information for each page element within the given containers.
|
|
39
41
|
*
|
|
@@ -47,7 +49,26 @@ interface ContainerBound {
|
|
|
47
49
|
* console.log(bounds);
|
|
48
50
|
* ```
|
|
49
51
|
*/
|
|
50
|
-
export
|
|
52
|
+
export function getPageElementBound(containers: HTMLDivElement[]): ContainerBound[] {
|
|
53
|
+
return containers.map((container) => {
|
|
54
|
+
const containerRect = container.getBoundingClientRect();
|
|
55
|
+
const contentlets = Array.from(
|
|
56
|
+
container.querySelectorAll('[data-dot-object="contentlet"]')
|
|
57
|
+
) as HTMLDivElement[];
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
x: containerRect.x,
|
|
61
|
+
y: containerRect.y,
|
|
62
|
+
width: containerRect.width,
|
|
63
|
+
height: containerRect.height,
|
|
64
|
+
payload: JSON.stringify({
|
|
65
|
+
container: getContainerData(container)
|
|
66
|
+
}),
|
|
67
|
+
contentlets: getContentletsBound(containerRect, contentlets)
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
51
72
|
/**
|
|
52
73
|
* Calculates the bounding information for each contentlet inside a container.
|
|
53
74
|
*
|
|
@@ -63,7 +84,33 @@ export declare function getPageElementBound(containers: HTMLDivElement[]): Conta
|
|
|
63
84
|
* console.log(bounds); // Element bounds within the container
|
|
64
85
|
* ```
|
|
65
86
|
*/
|
|
66
|
-
export
|
|
87
|
+
export function getContentletsBound(
|
|
88
|
+
containerRect: DOMRect,
|
|
89
|
+
contentlets: HTMLDivElement[]
|
|
90
|
+
): ContentletBound[] {
|
|
91
|
+
return contentlets.map((contentlet) => {
|
|
92
|
+
const contentletRect = contentlet.getBoundingClientRect();
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
x: 0,
|
|
96
|
+
y: contentletRect.y - containerRect.y,
|
|
97
|
+
width: contentletRect.width,
|
|
98
|
+
height: contentletRect.height,
|
|
99
|
+
payload: JSON.stringify({
|
|
100
|
+
container: contentlet.dataset?.['dotContainer']
|
|
101
|
+
? JSON.parse(contentlet.dataset?.['dotContainer'])
|
|
102
|
+
: getClosestContainerData(contentlet),
|
|
103
|
+
contentlet: {
|
|
104
|
+
identifier: contentlet.dataset?.['dotIdentifier'],
|
|
105
|
+
title: contentlet.dataset?.['dotTitle'],
|
|
106
|
+
inode: contentlet.dataset?.['dotInode'],
|
|
107
|
+
contentType: contentlet.dataset?.['dotType']
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
67
114
|
/**
|
|
68
115
|
* Get container data from VTLS.
|
|
69
116
|
*
|
|
@@ -77,12 +124,15 @@ export declare function getContentletsBound(containerRect: DOMRect, contentlets:
|
|
|
77
124
|
* console.log(data);
|
|
78
125
|
* ```
|
|
79
126
|
*/
|
|
80
|
-
export
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
127
|
+
export function getContainerData(container: HTMLElement) {
|
|
128
|
+
return {
|
|
129
|
+
acceptTypes: container.dataset?.['dotAcceptTypes'] || '',
|
|
130
|
+
identifier: container.dataset?.['dotIdentifier'] || '',
|
|
131
|
+
maxContentlets: container.dataset?.['maxContentlets'] || '',
|
|
132
|
+
uuid: container.dataset?.['dotUuid'] || ''
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
86
136
|
/**
|
|
87
137
|
* Get the closest container data from the contentlet.
|
|
88
138
|
*
|
|
@@ -96,12 +146,22 @@ export declare function getContainerData(container: HTMLElement): {
|
|
|
96
146
|
* console.log(data);
|
|
97
147
|
* ```
|
|
98
148
|
*/
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
149
|
+
export function getClosestContainerData(element: Element) {
|
|
150
|
+
// Find the closest ancestor element with data-dot-object="container" attribute
|
|
151
|
+
const container = element.closest('[data-dot-object="container"]') as HTMLElement;
|
|
152
|
+
|
|
153
|
+
// If a container element is found
|
|
154
|
+
if (container) {
|
|
155
|
+
// Return the dataset of the container element
|
|
156
|
+
return getContainerData(container);
|
|
157
|
+
} else {
|
|
158
|
+
// If no container element is found, return null
|
|
159
|
+
console.warn('No container found for the contentlet');
|
|
160
|
+
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
105
165
|
/**
|
|
106
166
|
* Find the closest contentlet element based on HTMLElement.
|
|
107
167
|
*
|
|
@@ -113,7 +173,19 @@ export declare function getClosestContainerData(element: Element): {
|
|
|
113
173
|
* const contentlet = findDotElement(element);
|
|
114
174
|
* console.log(contentlet);
|
|
115
175
|
*/
|
|
116
|
-
export
|
|
176
|
+
export function findDotElement(element: HTMLElement | null): HTMLElement | null {
|
|
177
|
+
if (!element) return null;
|
|
178
|
+
|
|
179
|
+
if (
|
|
180
|
+
element?.dataset?.['dotObject'] === 'contentlet' ||
|
|
181
|
+
(element?.dataset?.['dotObject'] === 'container' && element.children.length === 0)
|
|
182
|
+
) {
|
|
183
|
+
return element;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return findDotElement(element?.['parentElement']);
|
|
187
|
+
}
|
|
188
|
+
|
|
117
189
|
/**
|
|
118
190
|
* Find the closest VTL file element based on HTMLElement.
|
|
119
191
|
*
|
|
@@ -125,7 +197,16 @@ export declare function findDotElement(element: HTMLElement | null): HTMLElement
|
|
|
125
197
|
* const vtlFile = findDotVTLElement(element);
|
|
126
198
|
* console.log(vtlFile);
|
|
127
199
|
*/
|
|
128
|
-
export
|
|
200
|
+
export function findDotVTLElement(element: HTMLElement | null): HTMLElement | null {
|
|
201
|
+
if (!element) return null;
|
|
202
|
+
|
|
203
|
+
if (element.dataset && element.dataset?.['dotObject'] === 'vtl-file') {
|
|
204
|
+
return element;
|
|
205
|
+
} else {
|
|
206
|
+
return findDotElement(element?.['parentElement']);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
129
210
|
/**
|
|
130
211
|
* Find VTL data within a target element.
|
|
131
212
|
*
|
|
@@ -139,10 +220,23 @@ export declare function findDotVTLElement(element: HTMLElement | null): HTMLElem
|
|
|
139
220
|
* console.log(vtlData);
|
|
140
221
|
* ```
|
|
141
222
|
*/
|
|
142
|
-
export
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
223
|
+
export function findVTLData(target: HTMLElement) {
|
|
224
|
+
const vltElements = target.querySelectorAll(
|
|
225
|
+
'[data-dot-object="vtl-file"]'
|
|
226
|
+
) as NodeListOf<HTMLElement>;
|
|
227
|
+
|
|
228
|
+
if (!vltElements.length) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return Array.from(vltElements).map((vltElement) => {
|
|
233
|
+
return {
|
|
234
|
+
inode: vltElement.dataset?.['dotInode'],
|
|
235
|
+
name: vltElement.dataset?.['dotUrl']
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
146
240
|
/**
|
|
147
241
|
* Check if the scroll position is at the bottom of the page.
|
|
148
242
|
*
|
|
@@ -155,5 +249,10 @@ export declare function findVTLData(target: HTMLElement): {
|
|
|
155
249
|
* }
|
|
156
250
|
* ```
|
|
157
251
|
*/
|
|
158
|
-
export
|
|
159
|
-
|
|
252
|
+
export function scrollIsInBottom() {
|
|
253
|
+
const documentHeight = document.documentElement.scrollHeight;
|
|
254
|
+
const viewportHeight = window.innerHeight;
|
|
255
|
+
const scrollY = window.scrollY;
|
|
256
|
+
|
|
257
|
+
return scrollY + viewportHeight >= documentHeight;
|
|
258
|
+
}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { Field } from './Field';
|
|
2
2
|
import { NotOperand } from './NotOperand';
|
|
3
3
|
import { Operand } from './Operand';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
OPERAND,
|
|
7
|
+
buildExcludeField,
|
|
8
|
+
buildField,
|
|
9
|
+
buildNotOperand,
|
|
10
|
+
buildOperand,
|
|
11
|
+
buildRawEquals,
|
|
12
|
+
sanitizeQuery
|
|
13
|
+
} from '../utils';
|
|
14
|
+
|
|
4
15
|
/**
|
|
5
16
|
* 'Equal' Is a Typescript class that provides the ability to use terms in the lucene query string.
|
|
6
17
|
* A term is a value used to search for a specific value in a document. It can be a word or a phrase.
|
|
@@ -10,10 +21,13 @@ import { Operand } from './Operand';
|
|
|
10
21
|
* @export
|
|
11
22
|
* @class Equal
|
|
12
23
|
*/
|
|
13
|
-
export
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
constructor(query: string)
|
|
24
|
+
export class Equals {
|
|
25
|
+
#query = '';
|
|
26
|
+
|
|
27
|
+
constructor(private query: string) {
|
|
28
|
+
this.#query = this.query;
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
/**
|
|
18
32
|
* This method appends to the query a term that should be excluded in the search.
|
|
19
33
|
*
|
|
@@ -27,7 +41,10 @@ export declare class Equals {
|
|
|
27
41
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
28
42
|
* @memberof Equal
|
|
29
43
|
*/
|
|
30
|
-
excludeField(field: string): Field
|
|
44
|
+
excludeField(field: string): Field {
|
|
45
|
+
return buildExcludeField(this.#query, field);
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
/**
|
|
32
49
|
* This method appends to the query a field that should be included in the search.
|
|
33
50
|
*
|
|
@@ -40,7 +57,10 @@ export declare class Equals {
|
|
|
40
57
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
41
58
|
* @memberof Equal
|
|
42
59
|
*/
|
|
43
|
-
field(field: string): Field
|
|
60
|
+
field(field: string): Field {
|
|
61
|
+
return buildField(this.#query, field);
|
|
62
|
+
}
|
|
63
|
+
|
|
44
64
|
/**
|
|
45
65
|
* This method appends to the query an operand to use logic operators in the query.
|
|
46
66
|
*
|
|
@@ -54,7 +74,10 @@ export declare class Equals {
|
|
|
54
74
|
* @return {*} {Operand} - An instance of a Lucene Operand. An operand is a logical operator used to combine terms or phrases in a query.
|
|
55
75
|
* @memberof Equal
|
|
56
76
|
*/
|
|
57
|
-
or(): Operand
|
|
77
|
+
or(): Operand {
|
|
78
|
+
return buildOperand(this.#query, OPERAND.OR);
|
|
79
|
+
}
|
|
80
|
+
|
|
58
81
|
/**
|
|
59
82
|
* This method appends to the query an operand to use logic operators in the query.
|
|
60
83
|
*
|
|
@@ -67,7 +90,10 @@ export declare class Equals {
|
|
|
67
90
|
* @return {*} {Operand} - An instance of a Lucene Operand. An operand is a logical operator used to combine terms or phrases in a query.
|
|
68
91
|
* @memberof Equal
|
|
69
92
|
*/
|
|
70
|
-
and(): Operand
|
|
93
|
+
and(): Operand {
|
|
94
|
+
return buildOperand(this.#query, OPERAND.AND);
|
|
95
|
+
}
|
|
96
|
+
|
|
71
97
|
/**
|
|
72
98
|
* This method appends to the query an operand to use logic operators in the query.
|
|
73
99
|
*
|
|
@@ -80,7 +106,10 @@ export declare class Equals {
|
|
|
80
106
|
* @return {*} {NotOperand} - An instance of a Lucene Not Operand. A not operand is a logical operator used to exclude terms or phrases in a query.
|
|
81
107
|
* @memberof Equal
|
|
82
108
|
*/
|
|
83
|
-
not(): NotOperand
|
|
109
|
+
not(): NotOperand {
|
|
110
|
+
return buildNotOperand(this.#query);
|
|
111
|
+
}
|
|
112
|
+
|
|
84
113
|
/**
|
|
85
114
|
* This method allows to pass a raw query string to the query builder.
|
|
86
115
|
* This raw query should end in a Lucene Equal.
|
|
@@ -97,7 +126,10 @@ export declare class Equals {
|
|
|
97
126
|
* @return {*} {Equal} - An instance of a Lucene Equal. A term is a value used to search for a specific value in a document.
|
|
98
127
|
* @memberof QueryBuilder
|
|
99
128
|
*/
|
|
100
|
-
raw(query: string): Equals
|
|
129
|
+
raw(query: string): Equals {
|
|
130
|
+
return buildRawEquals(this.#query, query);
|
|
131
|
+
}
|
|
132
|
+
|
|
101
133
|
/**
|
|
102
134
|
* This method returns the final query string.
|
|
103
135
|
*
|
|
@@ -110,5 +142,7 @@ export declare class Equals {
|
|
|
110
142
|
* @return {*} {string} - The final query string.
|
|
111
143
|
* @memberof Equal
|
|
112
144
|
*/
|
|
113
|
-
build(): string
|
|
145
|
+
build(): string {
|
|
146
|
+
return sanitizeQuery(this.#query);
|
|
147
|
+
}
|
|
114
148
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Equals } from './Equals';
|
|
2
|
+
|
|
3
|
+
import { buildEquals } from '../utils';
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* The `Field` class is used to build a query with a specific field.
|
|
4
7
|
* A Lucene Field is a key used to search for a specific value in a document.
|
|
@@ -6,15 +9,18 @@ import { Equals } from './Equals';
|
|
|
6
9
|
* @export
|
|
7
10
|
* @class Field
|
|
8
11
|
*/
|
|
9
|
-
export
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
+
export class Field {
|
|
13
|
+
#query = '';
|
|
14
|
+
|
|
12
15
|
/**
|
|
13
16
|
* Creates an instance of the `Field` class.
|
|
14
17
|
*
|
|
15
18
|
* @param {string} query - The initial query string.
|
|
16
19
|
*/
|
|
17
|
-
constructor(query: string)
|
|
20
|
+
constructor(private query: string) {
|
|
21
|
+
this.#query = this.query;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
/**
|
|
19
25
|
* Appends a term to the query that should be included in the search.
|
|
20
26
|
*
|
|
@@ -28,5 +34,7 @@ export declare class Field {
|
|
|
28
34
|
* @return {Equals} - An instance of `Equals`.
|
|
29
35
|
* @memberof Field
|
|
30
36
|
*/
|
|
31
|
-
equals(term: string): Equals
|
|
37
|
+
equals(term: string): Equals {
|
|
38
|
+
return buildEquals(this.#query, term);
|
|
39
|
+
}
|
|
32
40
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { Equals } from './Equals';
|
|
2
|
+
|
|
3
|
+
import { buildEquals } from '../utils';
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* 'NotOperand' Is a Typescript class that provides the ability to use the NOT operand in the lucene query string.
|
|
4
7
|
*
|
|
5
8
|
* @export
|
|
6
9
|
* @class NotOperand
|
|
7
10
|
*/
|
|
8
|
-
export
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
constructor(query: string)
|
|
11
|
+
export class NotOperand {
|
|
12
|
+
#query = '';
|
|
13
|
+
|
|
14
|
+
constructor(private query: string) {
|
|
15
|
+
this.#query = this.query;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
/**
|
|
13
19
|
* This method appends to the query a term that should be included in the search.
|
|
14
20
|
*
|
|
@@ -22,5 +28,7 @@ export declare class NotOperand {
|
|
|
22
28
|
* @return {*} {Equals} - An instance of Equals.
|
|
23
29
|
* @memberof NotOperand
|
|
24
30
|
*/
|
|
25
|
-
equals(term: string): Equals
|
|
31
|
+
equals(term: string): Equals {
|
|
32
|
+
return buildEquals(this.#query, term);
|
|
33
|
+
}
|
|
26
34
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Equals } from './Equals';
|
|
2
2
|
import { Field } from './Field';
|
|
3
|
+
|
|
4
|
+
import { buildExcludeField, buildField, buildEquals } from '../utils';
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* 'Operand' Is a Typescript class that provides the ability to use operands in the lucene query string.}
|
|
5
8
|
* An operand is a logical operator used to join two or more conditions in a query.
|
|
@@ -7,10 +10,13 @@ import { Field } from './Field';
|
|
|
7
10
|
* @export
|
|
8
11
|
* @class Operand
|
|
9
12
|
*/
|
|
10
|
-
export
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
constructor(query: string)
|
|
13
|
+
export class Operand {
|
|
14
|
+
#query = '';
|
|
15
|
+
|
|
16
|
+
constructor(private query: string) {
|
|
17
|
+
this.#query = this.query;
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
/**
|
|
15
21
|
* This method appends to the query a term that should be excluded in the search.
|
|
16
22
|
*
|
|
@@ -20,7 +26,10 @@ export declare class Operand {
|
|
|
20
26
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
21
27
|
* @memberof Operand
|
|
22
28
|
*/
|
|
23
|
-
excludeField(field: string): Field
|
|
29
|
+
excludeField(field: string): Field {
|
|
30
|
+
return buildExcludeField(this.#query, field);
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
/**
|
|
25
34
|
* This method appends to the query a field that should be included in the search.
|
|
26
35
|
*
|
|
@@ -30,7 +39,10 @@ export declare class Operand {
|
|
|
30
39
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
31
40
|
* @memberof Operand
|
|
32
41
|
*/
|
|
33
|
-
field(field: string): Field
|
|
42
|
+
field(field: string): Field {
|
|
43
|
+
return buildField(this.#query, field);
|
|
44
|
+
}
|
|
45
|
+
|
|
34
46
|
/**
|
|
35
47
|
* This method appends to the query a term that should be included in the search.
|
|
36
48
|
*
|
|
@@ -40,5 +52,7 @@ export declare class Operand {
|
|
|
40
52
|
* @return {*} {Equals} - An instance of Equals.
|
|
41
53
|
* @memberof Operand
|
|
42
54
|
*/
|
|
43
|
-
equals(term: string): Equals
|
|
55
|
+
equals(term: string): Equals {
|
|
56
|
+
return buildEquals(this.#query, term);
|
|
57
|
+
}
|
|
44
58
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { QueryBuilder } from './sdk-query-builder';
|
|
2
|
+
|
|
3
|
+
describe('QueryBuilder', () => {
|
|
4
|
+
let queryBuilder: QueryBuilder;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
queryBuilder = new QueryBuilder();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should return a query with a simple term', () => {
|
|
11
|
+
const queryForBlogs = queryBuilder.field('contentType').equals('Blog').build();
|
|
12
|
+
|
|
13
|
+
expect(queryForBlogs).toBe('+contentType:Blog');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should return a query with multiple fields with a simple term ', () => {
|
|
17
|
+
const queryForBlogsInSuperCoolSite = queryBuilder
|
|
18
|
+
.field('contentType')
|
|
19
|
+
.equals('Blog')
|
|
20
|
+
.field('conhost')
|
|
21
|
+
.equals('my-super-cool-site')
|
|
22
|
+
.build();
|
|
23
|
+
|
|
24
|
+
expect(queryForBlogsInSuperCoolSite).toBe('+contentType:Blog +conhost:my-super-cool-site');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should return a query with an 'OR' operand", () => {
|
|
28
|
+
const queryForBlogsOrArticles = queryBuilder
|
|
29
|
+
.field('contentType')
|
|
30
|
+
.equals('Blog')
|
|
31
|
+
.or()
|
|
32
|
+
.equals('Article')
|
|
33
|
+
.build();
|
|
34
|
+
|
|
35
|
+
expect(queryForBlogsOrArticles).toBe('+contentType:Blog OR Article');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("should return a query with an 'AND' operand", () => {
|
|
39
|
+
const queryForBlogsAndArticles = queryBuilder
|
|
40
|
+
.field('contentType')
|
|
41
|
+
.equals('Blog')
|
|
42
|
+
.and()
|
|
43
|
+
.equals('Article')
|
|
44
|
+
.build();
|
|
45
|
+
|
|
46
|
+
expect(queryForBlogsAndArticles).toBe('+contentType:Blog AND Article');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should return a query with a 'NOT' operand", () => {
|
|
50
|
+
const queryForSkiingTripsNotInSwissAlps = queryBuilder
|
|
51
|
+
.field('summary')
|
|
52
|
+
.equals('Skiing trip')
|
|
53
|
+
.not()
|
|
54
|
+
.equals('Swiss Alps')
|
|
55
|
+
.build();
|
|
56
|
+
|
|
57
|
+
expect(queryForSkiingTripsNotInSwissAlps).toBe('+summary:"Skiing trip" NOT "Swiss Alps"');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should return a query with an exclusion field', () => {
|
|
61
|
+
const queryForFootballBlogsWithoutMessi = queryBuilder
|
|
62
|
+
.field('contentType')
|
|
63
|
+
.equals('Blog')
|
|
64
|
+
.field('title')
|
|
65
|
+
.equals('Football')
|
|
66
|
+
.excludeField('summary')
|
|
67
|
+
.equals('Lionel Messi')
|
|
68
|
+
.build();
|
|
69
|
+
|
|
70
|
+
expect(queryForFootballBlogsWithoutMessi).toBe(
|
|
71
|
+
'+contentType:Blog +title:Football -summary:"Lionel Messi"'
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should build a raw query from the query builder', () => {
|
|
76
|
+
const queryForBlogs = queryBuilder
|
|
77
|
+
.raw('+summary:Snowboard')
|
|
78
|
+
.not()
|
|
79
|
+
.equals('Swiss Alps')
|
|
80
|
+
.field('contentType')
|
|
81
|
+
.equals('Blog')
|
|
82
|
+
.build();
|
|
83
|
+
|
|
84
|
+
expect(queryForBlogs).toBe('+summary:Snowboard NOT "Swiss Alps" +contentType:Blog');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should return a query with a raw query appended', () => {
|
|
88
|
+
const queryForBlogs = queryBuilder
|
|
89
|
+
.field('contentType')
|
|
90
|
+
.equals('Blog')
|
|
91
|
+
.raw('+summary:Snowboard')
|
|
92
|
+
.not()
|
|
93
|
+
.equals('Swiss Alps')
|
|
94
|
+
.build();
|
|
95
|
+
|
|
96
|
+
expect(queryForBlogs).toBe('+contentType:Blog +summary:Snowboard NOT "Swiss Alps"');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should return a query with a raw query created with a queryBuilder appended and a term', () => {
|
|
100
|
+
const anotherQueryBuilder = new QueryBuilder();
|
|
101
|
+
|
|
102
|
+
const snowboardInCanada = anotherQueryBuilder
|
|
103
|
+
.field('summary')
|
|
104
|
+
.equals('Snowboard')
|
|
105
|
+
.field('country')
|
|
106
|
+
.equals('Canada')
|
|
107
|
+
.build();
|
|
108
|
+
|
|
109
|
+
const queryForBlogs = queryBuilder
|
|
110
|
+
.field('contentType')
|
|
111
|
+
.equals('Blog')
|
|
112
|
+
.raw(snowboardInCanada)
|
|
113
|
+
.build();
|
|
114
|
+
|
|
115
|
+
expect(queryForBlogs).toBe('+contentType:Blog +summary:Snowboard +country:Canada');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should return a query with all possible combinations', () => {
|
|
119
|
+
const blogOrActivity = queryBuilder
|
|
120
|
+
.field('contentType')
|
|
121
|
+
.equals('Blog')
|
|
122
|
+
.or()
|
|
123
|
+
.equals('Activity');
|
|
124
|
+
|
|
125
|
+
const customIdSiteOrCoolSite = blogOrActivity
|
|
126
|
+
.field('conhost')
|
|
127
|
+
.equals('48190c8c-42c4-46af-8d1a-0cd5db894797')
|
|
128
|
+
.or()
|
|
129
|
+
.equals('cool-site');
|
|
130
|
+
|
|
131
|
+
const englishAndSpanish = customIdSiteOrCoolSite
|
|
132
|
+
.field('languageId')
|
|
133
|
+
.equals('1')
|
|
134
|
+
.and()
|
|
135
|
+
.equals('2');
|
|
136
|
+
|
|
137
|
+
const notDeleted = englishAndSpanish.field('deleted').equals('false');
|
|
138
|
+
|
|
139
|
+
const currentlyWorking = notDeleted.field('working').equals('true');
|
|
140
|
+
|
|
141
|
+
const defaultVariant = currentlyWorking.field('variant').equals('default');
|
|
142
|
+
|
|
143
|
+
const snowboardOutsideSwissAlps = defaultVariant
|
|
144
|
+
.field('title')
|
|
145
|
+
.equals('Snowboard')
|
|
146
|
+
.excludeField('summary')
|
|
147
|
+
.equals('Swiss Alps');
|
|
148
|
+
|
|
149
|
+
const writtenByJohnDoe = snowboardOutsideSwissAlps.field('authors').equals('John Doe');
|
|
150
|
+
|
|
151
|
+
const withoutJaneDoeHelp = writtenByJohnDoe.not().equals('Jane Doe');
|
|
152
|
+
|
|
153
|
+
const query = withoutJaneDoeHelp.build();
|
|
154
|
+
|
|
155
|
+
expect(query).toBe(
|
|
156
|
+
'+contentType:Blog OR Activity +conhost:48190c8c-42c4-46af-8d1a-0cd5db894797 OR cool-site +languageId:1 AND 2 +deleted:false +working:true +variant:default +title:Snowboard -summary:"Swiss Alps" +authors:"John Doe" NOT "Jane Doe"'
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Equals, Field } from './lucene-syntax/index';
|
|
2
|
+
import { buildExcludeField, buildField, buildRawEquals } from './utils';
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
5
|
* 'QueryBuilder' Is a Typescript class that provides the ability to build a query string using the Lucene syntax in a more readable way.
|
|
4
6
|
* @example
|
|
@@ -27,8 +29,9 @@ import { Equals, Field } from './lucene-syntax/index';
|
|
|
27
29
|
* @export
|
|
28
30
|
* @class QueryBuilder
|
|
29
31
|
*/
|
|
30
|
-
export
|
|
31
|
-
#
|
|
32
|
+
export class QueryBuilder {
|
|
33
|
+
#query = '';
|
|
34
|
+
|
|
32
35
|
/**
|
|
33
36
|
* This method appends to the query a field that should be included in the search.
|
|
34
37
|
*
|
|
@@ -42,7 +45,10 @@ export declare class QueryBuilder {
|
|
|
42
45
|
* @return {*} {Field} - An instance of a Lucene Field. A field is a key used to search for a specific value in a document.
|
|
43
46
|
* @memberof QueryBuilder
|
|
44
47
|
*/
|
|
45
|
-
field(field: string): Field
|
|
48
|
+
field(field: string): Field {
|
|
49
|
+
return buildField(this.#query, field);
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
/**
|
|
47
53
|
* This method appends to the query a field that should be excluded from the search.
|
|
48
54
|
*
|
|
@@ -56,7 +62,10 @@ export declare class QueryBuilder {
|
|
|
56
62
|
* @return {*} {Field} - An instance of a Lucene Exclude Field. An exclude field is a key used to exclude for a specific value in a document.
|
|
57
63
|
* @memberof QueryBuilder
|
|
58
64
|
*/
|
|
59
|
-
excludeField(field: string): Field
|
|
65
|
+
excludeField(field: string): Field {
|
|
66
|
+
return buildExcludeField(this.#query, field);
|
|
67
|
+
}
|
|
68
|
+
|
|
60
69
|
/**
|
|
61
70
|
* This method allows to pass a raw query string to the query builder.
|
|
62
71
|
* This raw query should end in Equals.
|
|
@@ -72,5 +81,7 @@ export declare class QueryBuilder {
|
|
|
72
81
|
* @return {*} {Equals} - An instance of Equals. A term is a value used to search for a specific value in a document.
|
|
73
82
|
* @memberof QueryBuilder
|
|
74
83
|
*/
|
|
75
|
-
raw(query: string): Equals
|
|
84
|
+
raw(query: string): Equals {
|
|
85
|
+
return buildRawEquals(this.#query, query);
|
|
86
|
+
}
|
|
76
87
|
}
|