@tstdl/base 0.92.167 → 0.92.168
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/application/application.d.ts +12 -18
- package/application/application.js +48 -69
- package/application/index.d.ts +1 -5
- package/application/index.js +1 -5
- package/application/providers.d.ts +10 -0
- package/application/providers.js +54 -0
- package/authentication/client/authentication.service.d.ts +1 -3
- package/authentication/client/authentication.service.js +4 -5
- package/browser/browser-context-controller.d.ts +2 -4
- package/browser/browser-context-controller.js +5 -6
- package/browser/browser-controller.d.ts +2 -4
- package/browser/browser-controller.js +3 -4
- package/browser/browser.service.d.ts +1 -3
- package/browser/browser.service.js +1 -2
- package/browser/page-controller.d.ts +2 -4
- package/browser/page-controller.js +7 -8
- package/browser/utils.js +3 -3
- package/cancellation/token.d.ts +104 -41
- package/cancellation/token.js +125 -54
- package/core.d.ts +1 -13
- package/core.js +1 -46
- package/disposable/disposable.d.ts +0 -8
- package/disposable/disposable.js +1 -3
- package/disposable/index.d.ts +0 -6
- package/disposable/index.js +0 -6
- package/disposable/using.d.ts +0 -1
- package/disposable/using.js +2 -3
- package/distributed-loop/distributed-loop.js +2 -2
- package/errors/utils.js +4 -1
- package/examples/api/authentication.js +11 -5
- package/examples/api/basic-overview.js +17 -12
- package/examples/api/custom-authentication.js +13 -7
- package/examples/api/streaming.js +15 -12
- package/examples/browser/basic.js +6 -3
- package/examples/document-management/main.js +6 -3
- package/examples/http/client.js +7 -3
- package/examples/mail/basic.js +9 -7
- package/examples/pdf/basic.js +8 -6
- package/examples/template/basic.js +7 -5
- package/http/client/http-client-request.d.ts +1 -2
- package/http/client/http-client-request.js +1 -2
- package/http/server/http-server.d.ts +1 -3
- package/http/server/http-server.js +0 -1
- package/http/server/node/node-http-server.d.ts +1 -2
- package/http/server/node/node-http-server.js +1 -2
- package/import.js +1 -1
- package/injector/injector.d.ts +1 -1
- package/injector/types.d.ts +3 -4
- package/lock/lock.d.ts +40 -21
- package/lock/lock.js +74 -1
- package/lock/postgres/drizzle/0000_busy_tattoo.sql +7 -0
- package/lock/postgres/drizzle/meta/0000_snapshot.json +65 -0
- package/lock/postgres/drizzle/meta/_journal.json +13 -0
- package/lock/postgres/drizzle.config.js +11 -0
- package/lock/postgres/index.d.ts +2 -0
- package/lock/postgres/index.js +2 -0
- package/lock/postgres/lock.d.ts +14 -0
- package/lock/postgres/lock.js +127 -0
- package/lock/postgres/models/index.d.ts +2 -0
- package/lock/postgres/models/index.js +2 -0
- package/lock/postgres/models/lock.model.d.ts +7 -0
- package/{examples/orm/user.model.js → lock/postgres/models/lock.model.js} +22 -30
- package/lock/postgres/models/schemas.d.ts +3 -0
- package/lock/postgres/models/schemas.js +4 -0
- package/lock/postgres/module.d.ts +6 -0
- package/lock/postgres/module.js +26 -0
- package/lock/postgres/provider.d.ts +6 -0
- package/lock/postgres/provider.js +29 -0
- package/lock/provider.d.ts +12 -2
- package/lock/provider.js +24 -1
- package/lock/web/web-lock.d.ts +4 -3
- package/lock/web/web-lock.js +49 -42
- package/lock/web/web-lock.provider.d.ts +0 -3
- package/lock/web/web-lock.provider.js +5 -22
- package/logger/formatter.d.ts +13 -0
- package/logger/formatter.js +3 -0
- package/logger/formatters/index.d.ts +2 -0
- package/logger/formatters/index.js +2 -0
- package/logger/formatters/json.d.ts +5 -0
- package/logger/formatters/json.js +33 -0
- package/logger/formatters/pretty-print.d.ts +5 -0
- package/logger/formatters/pretty-print.js +55 -0
- package/logger/index.d.ts +5 -2
- package/logger/index.js +5 -2
- package/logger/level.d.ts +10 -8
- package/logger/level.js +9 -9
- package/logger/logger.d.ts +21 -30
- package/logger/logger.js +98 -26
- package/logger/manager.d.ts +20 -0
- package/logger/manager.js +77 -0
- package/logger/tokens.d.ts +1 -1
- package/logger/tokens.js +1 -1
- package/logger/transport.d.ts +14 -0
- package/logger/transport.js +16 -0
- package/logger/transports/console.d.ts +14 -0
- package/logger/transports/console.js +36 -0
- package/logger/transports/index.d.ts +1 -0
- package/logger/transports/index.js +1 -0
- package/mail/clients/nodemailer.mail-client.d.ts +0 -1
- package/mail/clients/nodemailer.mail-client.js +9 -7
- package/message-bus/local/local-message-bus.js +2 -2
- package/message-bus/message-bus-base.d.ts +2 -3
- package/message-bus/message-bus-base.js +5 -6
- package/message-bus/message-bus.d.ts +1 -2
- package/message-bus/message-bus.js +1 -2
- package/module/index.d.ts +0 -2
- package/module/index.js +0 -2
- package/module/module.d.ts +17 -18
- package/module/module.js +47 -12
- package/module/modules/function.module.d.ts +6 -6
- package/module/modules/function.module.js +25 -9
- package/module/modules/web-server.module.d.ts +2 -10
- package/module/modules/web-server.module.js +3 -11
- package/openid-connect/index.d.ts +0 -2
- package/openid-connect/index.js +0 -2
- package/openid-connect/oidc-state.model.d.ts +4 -5
- package/openid-connect/oidc-state.model.js +51 -1
- package/openid-connect/oidc.service-model.d.ts +1 -1
- package/openid-connect/oidc.service.d.ts +2 -6
- package/openid-connect/oidc.service.js +24 -37
- package/orm/decorators.d.ts +10 -1
- package/orm/decorators.js +8 -0
- package/orm/server/repository.d.ts +3 -1
- package/orm/server/repository.js +32 -3
- package/package.json +17 -28
- package/pdf/pdf.service.js +9 -9
- package/pool/pool.d.ts +1 -3
- package/pool/pool.js +3 -4
- package/queue/postgres/job.model.d.ts +1 -2
- package/queue/postgres/job.model.js +1 -2
- package/queue/postgres/module.js +1 -1
- package/threading/thread-pool.d.ts +1 -3
- package/threading/thread-pool.js +7 -8
- package/utils/format-error.d.ts +7 -0
- package/utils/format-error.js +59 -17
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/object/dereference.d.ts +51 -19
- package/utils/object/dereference.js +52 -43
- package/utils/timing.js +2 -2
- package/utils/try-chain.d.ts +22 -0
- package/utils/try-chain.js +46 -0
- package/database/entity-repository.d.ts +0 -50
- package/database/entity-repository.js +0 -3
- package/database/entity.d.ts +0 -7
- package/database/entity.js +0 -1
- package/database/id.d.ts +0 -1
- package/database/id.js +0 -9
- package/database/index.d.ts +0 -11
- package/database/index.js +0 -11
- package/database/module.d.ts +0 -8
- package/database/module.js +0 -11
- package/database/mongo/classes.d.ts +0 -21
- package/database/mongo/classes.js +0 -26
- package/database/mongo/index.d.ts +0 -15
- package/database/mongo/index.js +0 -15
- package/database/mongo/model/document.d.ts +0 -29
- package/database/mongo/model/document.js +0 -63
- package/database/mongo/model/index.d.ts +0 -1
- package/database/mongo/model/index.js +0 -1
- package/database/mongo/module.d.ts +0 -8
- package/database/mongo/module.js +0 -68
- package/database/mongo/mongo-base.repository.d.ts +0 -103
- package/database/mongo/mongo-base.repository.js +0 -263
- package/database/mongo/mongo-bulk.d.ts +0 -35
- package/database/mongo/mongo-bulk.js +0 -90
- package/database/mongo/mongo-entity-repository.d.ts +0 -98
- package/database/mongo/mongo-entity-repository.js +0 -278
- package/database/mongo/operations.d.ts +0 -10
- package/database/mongo/operations.js +0 -54
- package/database/mongo/query-converter.d.ts +0 -6
- package/database/mongo/query-converter.js +0 -83
- package/database/mongo/simple-entity-repository.d.ts +0 -7
- package/database/mongo/simple-entity-repository.js +0 -6
- package/database/mongo/types.d.ts +0 -50
- package/database/mongo/types.js +0 -3
- package/database/query.d.ts +0 -121
- package/database/query.js +0 -7
- package/database/utils.d.ts +0 -2
- package/database/utils.js +0 -3
- package/disposable/async-disposer.d.ts +0 -35
- package/disposable/async-disposer.js +0 -125
- package/examples/orm/drizzle.config.js +0 -6
- package/examples/orm/schemas.d.ts +0 -3
- package/examples/orm/schemas.js +0 -4
- package/examples/orm/test.d.ts +0 -1
- package/examples/orm/test.js +0 -11
- package/examples/orm/user.model.d.ts +0 -13
- package/key-value-store/mongo/index.d.ts +0 -6
- package/key-value-store/mongo/index.js +0 -6
- package/key-value-store/mongo/module.d.ts +0 -8
- package/key-value-store/mongo/module.js +0 -18
- package/key-value-store/mongo/mongo-key-value-store.provider.d.ts +0 -8
- package/key-value-store/mongo/mongo-key-value-store.provider.js +0 -26
- package/key-value-store/mongo/mongo-key-value.model.d.ts +0 -7
- package/key-value-store/mongo/mongo-key-value.model.js +0 -1
- package/key-value-store/mongo/mongo-key-value.repository.d.ts +0 -10
- package/key-value-store/mongo/mongo-key-value.repository.js +0 -31
- package/key-value-store/mongo/mongo-key-value.store.d.ts +0 -15
- package/key-value-store/mongo/mongo-key-value.store.js +0 -82
- package/key-value-store/mongo/tokens.d.ts +0 -3
- package/key-value-store/mongo/tokens.js +0 -2
- package/lock/mongo/index.d.ts +0 -5
- package/lock/mongo/index.js +0 -5
- package/lock/mongo/lock.d.ts +0 -14
- package/lock/mongo/lock.js +0 -125
- package/lock/mongo/model.d.ts +0 -6
- package/lock/mongo/model.js +0 -1
- package/lock/mongo/module.d.ts +0 -12
- package/lock/mongo/module.js +0 -20
- package/lock/mongo/mongo-lock-repository.d.ts +0 -14
- package/lock/mongo/mongo-lock-repository.js +0 -67
- package/lock/mongo/provider.d.ts +0 -8
- package/lock/mongo/provider.js +0 -36
- package/logger/console/index.d.ts +0 -1
- package/logger/console/index.js +0 -1
- package/logger/console/logger.d.ts +0 -11
- package/logger/console/logger.js +0 -64
- package/logger/noop/index.d.ts +0 -1
- package/logger/noop/index.js +0 -1
- package/logger/noop/logger.d.ts +0 -9
- package/logger/noop/logger.js +0 -21
- package/migration/index.d.ts +0 -9
- package/migration/index.js +0 -9
- package/migration/migration-state-repository.d.ts +0 -4
- package/migration/migration-state-repository.js +0 -3
- package/migration/migration-state.d.ts +0 -6
- package/migration/migration-state.js +0 -1
- package/migration/migrator.d.ts +0 -23
- package/migration/migrator.js +0 -76
- package/migration/mongo/index.d.ts +0 -2
- package/migration/mongo/index.js +0 -2
- package/migration/mongo/migration-state-repository.d.ts +0 -11
- package/migration/mongo/migration-state-repository.js +0 -32
- package/migration/mongo/module.d.ts +0 -12
- package/migration/mongo/module.js +0 -17
- package/module/module-base.d.ts +0 -18
- package/module/module-base.js +0 -40
- package/module/module-metric-reporter.d.ts +0 -29
- package/module/module-metric-reporter.js +0 -62
- package/openid-connect/mongo-oidc-state.repository.d.ts +0 -21
- package/openid-connect/mongo-oidc-state.repository.js +0 -52
- package/openid-connect/oidc-state.repository.d.ts +0 -4
- package/openid-connect/oidc-state.repository.js +0 -3
- package/process-shutdown.d.ts +0 -9
- package/process-shutdown.js +0 -65
- package/queue/mongo/index.d.ts +0 -4
- package/queue/mongo/index.js +0 -4
- package/queue/mongo/job.d.ts +0 -12
- package/queue/mongo/job.js +0 -1
- package/queue/mongo/mongo-job.repository.d.ts +0 -13
- package/queue/mongo/mongo-job.repository.js +0 -54
- package/queue/mongo/queue.d.ts +0 -38
- package/queue/mongo/queue.js +0 -266
- package/queue/mongo/queue.provider.d.ts +0 -18
- package/queue/mongo/queue.provider.js +0 -38
- package/search-index/elastic/config.d.ts +0 -8
- package/search-index/elastic/config.js +0 -26
- package/search-index/elastic/index.d.ts +0 -8
- package/search-index/elastic/index.js +0 -8
- package/search-index/elastic/keyword-rewriter.d.ts +0 -8
- package/search-index/elastic/keyword-rewriter.js +0 -18
- package/search-index/elastic/model/elastic-query.d.ts +0 -16
- package/search-index/elastic/model/elastic-query.js +0 -1
- package/search-index/elastic/model/index-mapping.d.ts +0 -26
- package/search-index/elastic/model/index-mapping.js +0 -4
- package/search-index/elastic/model/index.d.ts +0 -3
- package/search-index/elastic/model/index.js +0 -3
- package/search-index/elastic/model/sort.d.ts +0 -8
- package/search-index/elastic/model/sort.js +0 -1
- package/search-index/elastic/module.d.ts +0 -10
- package/search-index/elastic/module.js +0 -49
- package/search-index/elastic/query-builder/boolean-query-builder.d.ts +0 -11
- package/search-index/elastic/query-builder/boolean-query-builder.js +0 -52
- package/search-index/elastic/query-builder/index.d.ts +0 -1
- package/search-index/elastic/query-builder/index.js +0 -1
- package/search-index/elastic/query-converter.d.ts +0 -9
- package/search-index/elastic/query-converter.js +0 -183
- package/search-index/elastic/search-index.d.ts +0 -30
- package/search-index/elastic/search-index.js +0 -144
- package/search-index/elastic/sort-converter.d.ts +0 -4
- package/search-index/elastic/sort-converter.js +0 -14
- package/search-index/elastic/types.d.ts +0 -5
- package/search-index/elastic/types.js +0 -1
- package/search-index/error.d.ts +0 -10
- package/search-index/error.js +0 -14
- package/search-index/index.d.ts +0 -3
- package/search-index/index.js +0 -3
- package/search-index/memory/index.d.ts +0 -1
- package/search-index/memory/index.js +0 -1
- package/search-index/memory/memory-search-index.d.ts +0 -19
- package/search-index/memory/memory-search-index.js +0 -144
- package/search-index/search-index.d.ts +0 -46
- package/search-index/search-index.js +0 -31
- package/search-index/search-result.d.ts +0 -12
- package/search-index/search-result.js +0 -1
- package/theme/adapters/css-adapter.d.ts +0 -5
- package/theme/adapters/css-adapter.js +0 -29
- package/theme/adapters/index.d.ts +0 -2
- package/theme/adapters/index.js +0 -2
- package/theme/adapters/tailwind-adapter.d.ts +0 -18
- package/theme/adapters/tailwind-adapter.js +0 -32
- package/theme/index.d.ts +0 -1
- package/theme/index.js +0 -1
- package/theme/theme-service.d.ts +0 -43
- package/theme/theme-service.js +0 -128
- /package/{examples/orm → lock/postgres}/drizzle.config.d.ts +0 -0
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
|
-
import { hasOwnProperty, objectEntries, objectValues } from '../../utils/object/object.js';
|
|
3
|
-
import { assertDefinedPass, isPrimitive, isRegExp, isString } from '../../utils/type-guards.js';
|
|
4
|
-
import { BoolQueryBuilder } from './query-builder/index.js';
|
|
5
|
-
// eslint-disable-next-line max-lines-per-function, max-statements, complexity
|
|
6
|
-
export function convertQuery(query) {
|
|
7
|
-
const defaultBoolQueryBuilder = new BoolQueryBuilder();
|
|
8
|
-
const queryEntries = objectEntries(query);
|
|
9
|
-
// eslint-disable-next-line no-unreachable-loop
|
|
10
|
-
for (const [rawProperty, value] of queryEntries) {
|
|
11
|
-
const property = getPropertyName(rawProperty);
|
|
12
|
-
const isPrimitiveValue = isPrimitive(value);
|
|
13
|
-
const range = {};
|
|
14
|
-
let canHandleProperty = false;
|
|
15
|
-
if (rawProperty == '$and') {
|
|
16
|
-
if (queryEntries.length > 1) {
|
|
17
|
-
throw new Error('only one logical operator per level allowed');
|
|
18
|
-
}
|
|
19
|
-
return convertLogicalAndQuery(value);
|
|
20
|
-
}
|
|
21
|
-
if (rawProperty == '$or') {
|
|
22
|
-
if (queryEntries.length > 1) {
|
|
23
|
-
throw new Error('only one logical operator per level allowed');
|
|
24
|
-
}
|
|
25
|
-
return convertLogicalOrQuery(value);
|
|
26
|
-
}
|
|
27
|
-
if (rawProperty == '$nor') {
|
|
28
|
-
if (queryEntries.length > 1) {
|
|
29
|
-
throw new Error('only one logical operator per level allowed');
|
|
30
|
-
}
|
|
31
|
-
return convertLogicalNorQuery(value);
|
|
32
|
-
}
|
|
33
|
-
if (rawProperty == '$textSpan') {
|
|
34
|
-
const { fields, text, mode, operator } = value;
|
|
35
|
-
const type = convertTextSpanQueryMode(mode);
|
|
36
|
-
const matchQuery = { multi_match: { fields, query: text, type, operator } };
|
|
37
|
-
defaultBoolQueryBuilder.must(matchQuery);
|
|
38
|
-
canHandleProperty = true;
|
|
39
|
-
}
|
|
40
|
-
if (isPrimitiveValue || hasOwnProperty(value, '$eq')) {
|
|
41
|
-
const termQuery = {
|
|
42
|
-
term: { [property]: isPrimitiveValue ? value : value.$eq }
|
|
43
|
-
};
|
|
44
|
-
defaultBoolQueryBuilder.must(termQuery);
|
|
45
|
-
canHandleProperty = true;
|
|
46
|
-
}
|
|
47
|
-
if (hasOwnProperty(value, '$neq')) {
|
|
48
|
-
const termQuery = {
|
|
49
|
-
term: { [property]: value.$neq }
|
|
50
|
-
};
|
|
51
|
-
defaultBoolQueryBuilder.mustNot(termQuery);
|
|
52
|
-
canHandleProperty = true;
|
|
53
|
-
}
|
|
54
|
-
if (hasOwnProperty(value, '$exists')) {
|
|
55
|
-
const existsQuery = { exists: { field: property } };
|
|
56
|
-
if (value.$exists) {
|
|
57
|
-
defaultBoolQueryBuilder.must(existsQuery);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
defaultBoolQueryBuilder.mustNot(existsQuery);
|
|
61
|
-
}
|
|
62
|
-
canHandleProperty = true;
|
|
63
|
-
}
|
|
64
|
-
if (hasOwnProperty(value, '$in')) {
|
|
65
|
-
const termQuery = {
|
|
66
|
-
terms: { [property]: value.$in }
|
|
67
|
-
};
|
|
68
|
-
defaultBoolQueryBuilder.must(termQuery);
|
|
69
|
-
canHandleProperty = true;
|
|
70
|
-
}
|
|
71
|
-
if (hasOwnProperty(value, '$nin')) {
|
|
72
|
-
const termQuery = {
|
|
73
|
-
terms: { [property]: value.$nin }
|
|
74
|
-
};
|
|
75
|
-
defaultBoolQueryBuilder.mustNot(termQuery);
|
|
76
|
-
canHandleProperty = true;
|
|
77
|
-
}
|
|
78
|
-
if (hasOwnProperty(value, '$lt')) {
|
|
79
|
-
range.lt = value.$lt;
|
|
80
|
-
canHandleProperty = true;
|
|
81
|
-
}
|
|
82
|
-
if (hasOwnProperty(value, '$lte')) {
|
|
83
|
-
range.lte = value.$lte;
|
|
84
|
-
canHandleProperty = true;
|
|
85
|
-
}
|
|
86
|
-
if (hasOwnProperty(value, '$gt')) {
|
|
87
|
-
range.gt = value.$gt;
|
|
88
|
-
canHandleProperty = true;
|
|
89
|
-
}
|
|
90
|
-
if (hasOwnProperty(value, '$gte')) {
|
|
91
|
-
range.gte = value.$gte;
|
|
92
|
-
canHandleProperty = true;
|
|
93
|
-
}
|
|
94
|
-
if (objectValues(range).length > 0) {
|
|
95
|
-
const rangeQuery = { range: { [property]: range } };
|
|
96
|
-
defaultBoolQueryBuilder.must(rangeQuery);
|
|
97
|
-
}
|
|
98
|
-
if (hasOwnProperty(value, '$regex')) {
|
|
99
|
-
const regex = value.$regex;
|
|
100
|
-
const regexp = isString(regex)
|
|
101
|
-
? regex
|
|
102
|
-
: isRegExp(regex)
|
|
103
|
-
? { flags: regex.flags, value: regex.source }
|
|
104
|
-
: { flags: regex.flags, value: regex.pattern };
|
|
105
|
-
const termQuery = {
|
|
106
|
-
regexp: { property: regexp }
|
|
107
|
-
};
|
|
108
|
-
defaultBoolQueryBuilder.must(termQuery);
|
|
109
|
-
canHandleProperty = true;
|
|
110
|
-
}
|
|
111
|
-
if (hasOwnProperty(value, '$text')) {
|
|
112
|
-
let matchQuery;
|
|
113
|
-
const textQueryValue = value.$text;
|
|
114
|
-
if (typeof textQueryValue == 'string') {
|
|
115
|
-
matchQuery = { match: { [property]: { query: textQueryValue } } };
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
matchQuery = { match: { [property]: { query: textQueryValue.text, operator: textQueryValue.operator } } };
|
|
119
|
-
}
|
|
120
|
-
defaultBoolQueryBuilder.must(matchQuery);
|
|
121
|
-
canHandleProperty = true;
|
|
122
|
-
}
|
|
123
|
-
if (hasOwnProperty(value, '$geoShape')) {
|
|
124
|
-
const geoShapeQuery = {
|
|
125
|
-
geo_shape: {
|
|
126
|
-
[property]: {
|
|
127
|
-
shape: value.$geoShape.geometry,
|
|
128
|
-
relation: value.$geoShape.relation
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
defaultBoolQueryBuilder.must(geoShapeQuery);
|
|
133
|
-
canHandleProperty = true;
|
|
134
|
-
}
|
|
135
|
-
if (hasOwnProperty(value, '$geoDistance')) {
|
|
136
|
-
const distance = assertDefinedPass(value.$geoDistance.maxDistance, 'maxDistance required');
|
|
137
|
-
const geoShapeQuery = {
|
|
138
|
-
geo_distance: {
|
|
139
|
-
distance: `${distance}m`,
|
|
140
|
-
[property]: [
|
|
141
|
-
value.$geoDistance.longitude,
|
|
142
|
-
value.$geoDistance.latitude
|
|
143
|
-
]
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
defaultBoolQueryBuilder.must(geoShapeQuery);
|
|
147
|
-
canHandleProperty = true;
|
|
148
|
-
}
|
|
149
|
-
if (!canHandleProperty) {
|
|
150
|
-
throw new Error(`unsupported query type "${rawProperty}"`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
if (defaultBoolQueryBuilder.totalQueries == 0) {
|
|
154
|
-
return { match_all: {} };
|
|
155
|
-
}
|
|
156
|
-
return defaultBoolQueryBuilder.build();
|
|
157
|
-
}
|
|
158
|
-
function getPropertyName(property) {
|
|
159
|
-
return property == 'id' ? '_id' : property;
|
|
160
|
-
}
|
|
161
|
-
export function convertLogicalAndQuery(andQuery) {
|
|
162
|
-
return new BoolQueryBuilder().must(...andQuery.map(convertQuery)).build();
|
|
163
|
-
}
|
|
164
|
-
export function convertLogicalOrQuery(orQuery) {
|
|
165
|
-
return new BoolQueryBuilder().should(...orQuery.map(convertQuery)).build();
|
|
166
|
-
}
|
|
167
|
-
export function convertLogicalNorQuery(norQuery) {
|
|
168
|
-
return new BoolQueryBuilder().mustNot(...norQuery.map(convertQuery)).build();
|
|
169
|
-
}
|
|
170
|
-
export function convertTextSpanQueryMode(mode) {
|
|
171
|
-
switch (mode) {
|
|
172
|
-
case undefined:
|
|
173
|
-
return undefined;
|
|
174
|
-
case 'best':
|
|
175
|
-
return 'best_fields';
|
|
176
|
-
case 'most':
|
|
177
|
-
return 'most_fields';
|
|
178
|
-
case 'cross':
|
|
179
|
-
return 'cross_fields';
|
|
180
|
-
default:
|
|
181
|
-
throw new Error('unknown ComplexTextSpanQueryMode');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { Client, estypes } from '@elastic/elasticsearch';
|
|
2
|
-
import type { Entity, Query, QueryOptions } from '../../database/index.js';
|
|
3
|
-
import type { AfterResolve } from '../../injector/interfaces.js';
|
|
4
|
-
import { afterResolve } from '../../injector/interfaces.js';
|
|
5
|
-
import type { Logger } from '../../logger/index.js';
|
|
6
|
-
import type { SearchResult } from '../../search-index/index.js';
|
|
7
|
-
import { SearchIndex } from '../../search-index/index.js';
|
|
8
|
-
import type { ElasticSearchIndexConfig } from './config.js';
|
|
9
|
-
import { KeywordRewriter } from './keyword-rewriter.js';
|
|
10
|
-
import type { ElasticIndexMapping } from './model/index.js';
|
|
11
|
-
export declare class ElasticSearchIndex<T extends Entity> extends SearchIndex<T> implements AfterResolve {
|
|
12
|
-
private readonly logger;
|
|
13
|
-
readonly client: Client;
|
|
14
|
-
readonly indexName: string;
|
|
15
|
-
readonly indexSettings: estypes.IndicesIndexSettings;
|
|
16
|
-
readonly indexMapping: ElasticIndexMapping<T>;
|
|
17
|
-
readonly keywordRewriter: KeywordRewriter;
|
|
18
|
-
constructor(client: Client, config: ElasticSearchIndexConfig<T>, indexSettings: estypes.IndicesIndexSettings, indexMapping: ElasticIndexMapping<T>, keywordRewrites: Iterable<string>, logger: Logger);
|
|
19
|
-
[afterResolve](): Promise<void>;
|
|
20
|
-
initialize(): Promise<void>;
|
|
21
|
-
refresh(): Promise<void>;
|
|
22
|
-
updateSettings(): Promise<void>;
|
|
23
|
-
index(entities: T[]): Promise<void>;
|
|
24
|
-
delete(id: string): Promise<void>;
|
|
25
|
-
deleteByQuery(query: Query<T>): Promise<void>;
|
|
26
|
-
search(searchQueryOrCursor: Query<T> | string, options?: QueryOptions<T>): Promise<SearchResult<T>>;
|
|
27
|
-
count(query?: Query<T>, options?: QueryOptions<T>): Promise<number>;
|
|
28
|
-
drop(): Promise<void>;
|
|
29
|
-
exists(): Promise<boolean>;
|
|
30
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { BadRequestError } from '../../errors/bad-request.error.js';
|
|
2
|
-
import { MultiError } from '../../errors/multi.error.js';
|
|
3
|
-
import { afterResolve } from '../../injector/interfaces.js';
|
|
4
|
-
import { SearchIndex, SearchIndexError } from '../../search-index/index.js';
|
|
5
|
-
import { decodeBase64, encodeBase64 } from '../../utils/base64.js';
|
|
6
|
-
import { decodeText, encodeUtf8 } from '../../utils/encoding.js';
|
|
7
|
-
import { filterObject } from '../../utils/object/object.js';
|
|
8
|
-
import { isDefined, isNumber, isString } from '../../utils/type-guards.js';
|
|
9
|
-
import { KeywordRewriter } from './keyword-rewriter.js';
|
|
10
|
-
import { convertQuery } from './query-converter.js';
|
|
11
|
-
import { convertSort } from './sort-converter.js';
|
|
12
|
-
export class ElasticSearchIndex extends SearchIndex {
|
|
13
|
-
logger;
|
|
14
|
-
client;
|
|
15
|
-
indexName;
|
|
16
|
-
indexSettings;
|
|
17
|
-
indexMapping;
|
|
18
|
-
keywordRewriter;
|
|
19
|
-
constructor(client, config, indexSettings, indexMapping, keywordRewrites, logger) {
|
|
20
|
-
super();
|
|
21
|
-
this.client = client;
|
|
22
|
-
this.indexName = config.indexName;
|
|
23
|
-
this.indexSettings = indexSettings;
|
|
24
|
-
this.indexMapping = indexMapping;
|
|
25
|
-
this.logger = logger;
|
|
26
|
-
this.keywordRewriter = new KeywordRewriter(keywordRewrites);
|
|
27
|
-
}
|
|
28
|
-
async [afterResolve]() {
|
|
29
|
-
await this.initialize();
|
|
30
|
-
}
|
|
31
|
-
async initialize() {
|
|
32
|
-
const exists = await this.exists();
|
|
33
|
-
if (!exists) {
|
|
34
|
-
await this.client.indices.create({ index: this.indexName, mappings: this.indexMapping, settings: this.indexSettings });
|
|
35
|
-
this.logger.info(`created index ${this.indexName}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async refresh() {
|
|
39
|
-
await this.client.indices.refresh({ index: this.indexName });
|
|
40
|
-
}
|
|
41
|
-
async updateSettings() {
|
|
42
|
-
this.logger.info(`closing index ${this.indexName} for updates`);
|
|
43
|
-
await this.client.indices.close({ index: this.indexName });
|
|
44
|
-
this.logger.info(`closed index ${this.indexName} for updates`);
|
|
45
|
-
this.logger.info(`updating settings for index ${this.indexName}`);
|
|
46
|
-
await this.client.indices.putSettings({ index: this.indexName, settings: this.indexSettings });
|
|
47
|
-
this.logger.info(`updated settings for index ${this.indexName}`);
|
|
48
|
-
this.logger.info(`updating mapping for index ${this.indexName}`);
|
|
49
|
-
await this.client.indices.putMapping({ index: this.indexName, ...this.indexMapping });
|
|
50
|
-
this.logger.info(`updated mapping for index ${this.indexName}`);
|
|
51
|
-
this.logger.info(`reopening index ${this.indexName}`);
|
|
52
|
-
await this.client.indices.open({ index: this.indexName });
|
|
53
|
-
this.logger.info(`reopened index ${this.indexName}`);
|
|
54
|
-
this.logger.info(`refreshing index ${this.indexName}`);
|
|
55
|
-
await this.client.indices.refresh({ index: this.indexName });
|
|
56
|
-
this.logger.info(`refreshed index ${this.indexName}`);
|
|
57
|
-
}
|
|
58
|
-
async index(entities) {
|
|
59
|
-
const request = {
|
|
60
|
-
index: this.indexName,
|
|
61
|
-
refresh: false,
|
|
62
|
-
operations: entities.flatMap((entity) => {
|
|
63
|
-
const { id: _, ...entityWithoutId } = entity;
|
|
64
|
-
return [{ index: { _id: entity.id } }, entityWithoutId];
|
|
65
|
-
}),
|
|
66
|
-
};
|
|
67
|
-
const result = await this.client.bulk(request);
|
|
68
|
-
if (result.errors) {
|
|
69
|
-
const errorItems = result.items
|
|
70
|
-
.filter((item) => isDefined(item.index.error))
|
|
71
|
-
.map((item) => item.index);
|
|
72
|
-
const errors = errorItems.map((item) => convertError(item.error, item));
|
|
73
|
-
if (errors.length == 1) {
|
|
74
|
-
throw errors[0];
|
|
75
|
-
}
|
|
76
|
-
const multiError = new MultiError(errors);
|
|
77
|
-
throw new SearchIndexError('index error', 'multiple errors', { cause: multiError });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async delete(id) {
|
|
81
|
-
await this.client.delete({ index: this.indexName, id });
|
|
82
|
-
}
|
|
83
|
-
async deleteByQuery(query) {
|
|
84
|
-
const queryBody = convertQuery(query);
|
|
85
|
-
await this.client.deleteByQuery({ index: this.indexName, query: queryBody });
|
|
86
|
-
}
|
|
87
|
-
async search(searchQueryOrCursor, options) {
|
|
88
|
-
const cursorData = isString(searchQueryOrCursor) ? deserializeCursor(searchQueryOrCursor) : undefined;
|
|
89
|
-
const queryBody = isDefined(cursorData) ? cursorData.query : convertQuery(searchQueryOrCursor);
|
|
90
|
-
const search = { index: this.indexName, query: queryBody };
|
|
91
|
-
const windowLimit = this.indexSettings.max_result_window ?? 10000;
|
|
92
|
-
if ((options?.skip ?? 0) + (options?.limit ?? 0) > windowLimit) {
|
|
93
|
-
throw new BadRequestError(`Result window is too large, skip + limit must be less than or equal to ${windowLimit}. Use cursor for more results`);
|
|
94
|
-
}
|
|
95
|
-
if (isDefined(cursorData) && isDefined(options?.skip)) {
|
|
96
|
-
throw new Error('cursor and skip cannot be used at the same time');
|
|
97
|
-
}
|
|
98
|
-
const sort = cursorData?.sort ?? (options?.sort ?? []).map((sortItem) => convertSort(sortItem, this.keywordRewriter));
|
|
99
|
-
search.sort = sort;
|
|
100
|
-
search.from = options?.skip;
|
|
101
|
-
search.size = options?.limit ?? cursorData?.options?.limit;
|
|
102
|
-
search.search_after = cursorData?.searchAfter;
|
|
103
|
-
const response = await this.client.search(search);
|
|
104
|
-
const hits = response.hits.hits;
|
|
105
|
-
const resultItems = hits.map(({ _id, _score, _source }) => ({ score: _score ?? 1, entity: { id: _id, ..._source } }));
|
|
106
|
-
const total = isNumber(response.hits.total) ? response.hits.total : response.hits.total?.value;
|
|
107
|
-
const totalIsLowerBound = isNumber(response.hits.total) ? false : (response.hits.total?.relation == 'gte');
|
|
108
|
-
const cursor = (hits.length > 0) && (isDefined(hits[hits.length - 1].sort)) ? serializeCursor(queryBody, sort, { limit: search.size }, hits[hits.length - 1].sort) : undefined;
|
|
109
|
-
const result = { total, milliseconds: response.took, totalIsLowerBound, cursor, items: resultItems };
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
112
|
-
async count(query, options) {
|
|
113
|
-
if (isDefined(options?.skip) || isDefined(options?.limit)) {
|
|
114
|
-
throw new Error('Options skip and limit for count are not support in ElasticSearchIndex.');
|
|
115
|
-
}
|
|
116
|
-
const result = await this.client.count({
|
|
117
|
-
index: this.indexName,
|
|
118
|
-
query: convertQuery(query ?? {}),
|
|
119
|
-
});
|
|
120
|
-
return result.count;
|
|
121
|
-
}
|
|
122
|
-
async drop() {
|
|
123
|
-
const exists = await this.exists();
|
|
124
|
-
if (!exists) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
await this.client.indices.delete({ index: this.indexName });
|
|
128
|
-
}
|
|
129
|
-
async exists() {
|
|
130
|
-
return await this.client.indices.exists({ index: this.indexName });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function serializeCursor(query, sort, options, searchAfter) {
|
|
134
|
-
const filteredOptions = isDefined(options) ? filterObject(options, isDefined) : undefined;
|
|
135
|
-
const data = { query, sort, options: filteredOptions, searchAfter };
|
|
136
|
-
return encodeBase64(encodeUtf8(JSON.stringify(data)));
|
|
137
|
-
}
|
|
138
|
-
function deserializeCursor(cursor) {
|
|
139
|
-
return JSON.parse(decodeText(decodeBase64(cursor)));
|
|
140
|
-
}
|
|
141
|
-
function convertError(error, raw) {
|
|
142
|
-
const cause = (isDefined(error.caused_by)) ? convertError(error.caused_by) : undefined;
|
|
143
|
-
return new SearchIndexError(error.type, error.reason ?? 'No error message provided.', { raw, cause });
|
|
144
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { Entity, Sort } from '../../database/index.js';
|
|
2
|
-
import type { KeywordRewriter } from './keyword-rewriter.js';
|
|
3
|
-
import type { SortCombinations } from './model/index.js';
|
|
4
|
-
export declare function convertSort<T extends Entity>(sort: Sort<T>, keywordRewriter: KeywordRewriter): SortCombinations<T>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const renameMap = new Map([
|
|
2
|
-
['id', '_id'],
|
|
3
|
-
['$score', '_score']
|
|
4
|
-
]);
|
|
5
|
-
// eslint-disable-next-line max-lines-per-function, max-statements, complexity
|
|
6
|
-
export function convertSort(sort, keywordRewriter) {
|
|
7
|
-
const name = renameMap.get(sort.field) ?? sort.field;
|
|
8
|
-
const field = keywordRewriter.rewriteIfRequired(name);
|
|
9
|
-
const order = sort.order ?? 'asc';
|
|
10
|
-
if (((field != '_score') && (order == 'asc')) || ((field == '_score') && (order == 'desc'))) {
|
|
11
|
-
return field;
|
|
12
|
-
}
|
|
13
|
-
return { [field]: order };
|
|
14
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { estypes } from '@elastic/elasticsearch';
|
|
2
|
-
export type AnalysisAnalyzer = estypes.AnalysisAnalyzer;
|
|
3
|
-
export type AnalysisTokenFilter = estypes.AnalysisTokenFilter;
|
|
4
|
-
export type AnalysisTokenizer = estypes.AnalysisTokenizer;
|
|
5
|
-
export type IndicesIndexSettings = estypes.IndicesIndexSettings;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/search-index/error.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { CustomError } from '../errors/custom.error.js';
|
|
2
|
-
export declare class SearchIndexError extends CustomError {
|
|
3
|
-
static readonly errorName = "SearchIndexError";
|
|
4
|
-
readonly type: string;
|
|
5
|
-
readonly raw: unknown;
|
|
6
|
-
constructor(type: string, message: string, { raw, cause }?: {
|
|
7
|
-
raw?: unknown;
|
|
8
|
-
cause?: Error;
|
|
9
|
-
});
|
|
10
|
-
}
|
package/search-index/error.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { CustomError } from '../errors/custom.error.js';
|
|
2
|
-
import { isDefined } from '../utils/type-guards.js';
|
|
3
|
-
export class SearchIndexError extends CustomError {
|
|
4
|
-
static errorName = 'SearchIndexError';
|
|
5
|
-
type;
|
|
6
|
-
raw;
|
|
7
|
-
constructor(type, message, { raw, cause } = {}) {
|
|
8
|
-
super({ message, cause });
|
|
9
|
-
this.type = type;
|
|
10
|
-
if (isDefined(raw)) {
|
|
11
|
-
this.raw = raw;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
package/search-index/index.d.ts
DELETED
package/search-index/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './memory-search-index.js';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './memory-search-index.js';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Entity, Query, QueryOptions } from '../../database/index.js';
|
|
2
|
-
import { SearchIndex } from '../search-index.js';
|
|
3
|
-
import type { SearchResult } from '../search-result.js';
|
|
4
|
-
export declare class MemorySearchIndex<T extends Entity> extends SearchIndex<T> {
|
|
5
|
-
private readonly indexedFields;
|
|
6
|
-
private readonly allSet;
|
|
7
|
-
private readonly idMap;
|
|
8
|
-
private readonly indexMap;
|
|
9
|
-
constructor(indexedFields: (keyof T)[]);
|
|
10
|
-
index(entities: T[]): Promise<void>;
|
|
11
|
-
delete(id: string): Promise<void>;
|
|
12
|
-
deleteByQuery(query: Query<T>): Promise<void>;
|
|
13
|
-
search(queryOrCursor: string | Query<T>, options?: QueryOptions<T>): Promise<SearchResult<T>>;
|
|
14
|
-
count(query?: Query<T>, options?: QueryOptions<T>): Promise<number>;
|
|
15
|
-
drop(): Promise<void>;
|
|
16
|
-
private _delete;
|
|
17
|
-
private indexEntity;
|
|
18
|
-
private deleteEntity;
|
|
19
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { compareByValueSelectionOrdered } from '../../utils/comparison.js';
|
|
2
|
-
import { FactoryMap } from '../../utils/factory-map.js';
|
|
3
|
-
import { objectEntries } from '../../utils/object/object.js';
|
|
4
|
-
import { intersectSets, unionSets } from '../../utils/set.js';
|
|
5
|
-
import { normalizeText } from '../../utils/string/index.js';
|
|
6
|
-
import { Timer } from '../../utils/timer.js';
|
|
7
|
-
import { isDefined, isNullOrUndefined, isString } from '../../utils/type-guards.js';
|
|
8
|
-
import { SearchIndex } from '../search-index.js';
|
|
9
|
-
export class MemorySearchIndex extends SearchIndex {
|
|
10
|
-
indexedFields;
|
|
11
|
-
allSet;
|
|
12
|
-
idMap;
|
|
13
|
-
indexMap;
|
|
14
|
-
constructor(indexedFields) {
|
|
15
|
-
super();
|
|
16
|
-
this.indexedFields = indexedFields;
|
|
17
|
-
this.allSet = new Set();
|
|
18
|
-
this.idMap = new Map();
|
|
19
|
-
this.indexMap = new FactoryMap(() => new FactoryMap(() => new Set()));
|
|
20
|
-
}
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
22
|
-
async index(entities) {
|
|
23
|
-
for (const entity of entities) {
|
|
24
|
-
this._delete(entity.id);
|
|
25
|
-
this.indexEntity(entity);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
29
|
-
async delete(id) {
|
|
30
|
-
this._delete(id);
|
|
31
|
-
}
|
|
32
|
-
async deleteByQuery(query) {
|
|
33
|
-
const searchResult = await this.search(query);
|
|
34
|
-
for (const item of searchResult.items) {
|
|
35
|
-
this.deleteEntity(item.entity);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/require-await, max-statements, max-lines-per-function
|
|
39
|
-
async search(queryOrCursor, options = {}) {
|
|
40
|
-
if (isString(queryOrCursor)) {
|
|
41
|
-
throw new Error('cursor not supported');
|
|
42
|
-
}
|
|
43
|
-
const timer = new Timer(true);
|
|
44
|
-
const entries = objectEntries(queryOrCursor);
|
|
45
|
-
let items;
|
|
46
|
-
if (entries.length == 0) {
|
|
47
|
-
items = [...this.allSet];
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
const sets = [];
|
|
51
|
-
for (const [field, query] of entries) {
|
|
52
|
-
const textQuery = query.$text;
|
|
53
|
-
const queryIsString = isString(textQuery);
|
|
54
|
-
const text = queryIsString ? textQuery : textQuery.text;
|
|
55
|
-
const and = queryIsString ? true : textQuery.operator != 'or';
|
|
56
|
-
const innerSets = [];
|
|
57
|
-
if (isString(text)) {
|
|
58
|
-
const tokens = normalizeText(text).split(' ').filter((token) => token.length > 0);
|
|
59
|
-
if (tokens.length == 0) {
|
|
60
|
-
innerSets.push(this.allSet);
|
|
61
|
-
}
|
|
62
|
-
for (const token of tokens) {
|
|
63
|
-
innerSets.push(this.indexMap.get(field).get(token));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const innerEntries = and ? intersectSets(...innerSets) : unionSets(...innerSets);
|
|
67
|
-
sets.push(new Set(innerEntries));
|
|
68
|
-
}
|
|
69
|
-
items = intersectSets(...sets);
|
|
70
|
-
}
|
|
71
|
-
if (isDefined(options.sort)) {
|
|
72
|
-
items.sort(compareByValueSelectionOrdered(...options.sort.map((sort) => [(item) => item[sort.field], sort.order == 'desc' ? -1 : 1])));
|
|
73
|
-
}
|
|
74
|
-
if (isDefined(options.skip) || isDefined(options.limit)) {
|
|
75
|
-
const start = options.skip ?? 0;
|
|
76
|
-
const end = isDefined(options.limit) ? (start + options.limit) : undefined;
|
|
77
|
-
items = items.slice(start, end);
|
|
78
|
-
}
|
|
79
|
-
const resultItems = items.map((item) => ({ entity: item, score: 1 }));
|
|
80
|
-
const result = {
|
|
81
|
-
total: resultItems.length,
|
|
82
|
-
totalIsLowerBound: false,
|
|
83
|
-
milliseconds: timer.milliseconds,
|
|
84
|
-
items: resultItems,
|
|
85
|
-
};
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
async count(query, options) {
|
|
89
|
-
const items = await this.searchAll(query ?? {}, options);
|
|
90
|
-
return items.length;
|
|
91
|
-
}
|
|
92
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
93
|
-
async drop() {
|
|
94
|
-
this.allSet.clear();
|
|
95
|
-
this.idMap.clear();
|
|
96
|
-
this.indexMap.clear();
|
|
97
|
-
}
|
|
98
|
-
_delete(id) {
|
|
99
|
-
const entity = this.idMap.get(id);
|
|
100
|
-
if (isDefined(entity)) {
|
|
101
|
-
this.deleteEntity(entity);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
indexEntity(entity) {
|
|
105
|
-
this.allSet.add(entity);
|
|
106
|
-
this.idMap.set(entity.id, entity);
|
|
107
|
-
for (const field of this.indexedFields) {
|
|
108
|
-
const value = entity[field];
|
|
109
|
-
const tokens = getTokens(value);
|
|
110
|
-
for (const token of tokens) {
|
|
111
|
-
this.indexMap.get(field).get(token).add(entity);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
deleteEntity(entity) {
|
|
116
|
-
for (const field of this.indexedFields) {
|
|
117
|
-
const value = entity[field];
|
|
118
|
-
const tokens = getTokens(value);
|
|
119
|
-
for (const token of tokens) {
|
|
120
|
-
this.indexMap.get(field).get(token).delete(entity);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
this.allSet.delete(entity);
|
|
124
|
-
this.idMap.delete(entity.id);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
function getTokens(value) {
|
|
128
|
-
if (isNullOrUndefined(value)) {
|
|
129
|
-
return [value];
|
|
130
|
-
}
|
|
131
|
-
if (!isString(value)) {
|
|
132
|
-
throw new Error('value is neither string nor null or undefined');
|
|
133
|
-
}
|
|
134
|
-
const normalizedParts = normalizeText(value).split(' ');
|
|
135
|
-
const tokens = new Set();
|
|
136
|
-
for (const part of normalizedParts) {
|
|
137
|
-
for (let i = 0; i < part.length; i++) {
|
|
138
|
-
for (let j = i; j < part.length; j++) {
|
|
139
|
-
tokens.add(part.slice(i, j + 1));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return [...tokens];
|
|
144
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import type { Entity } from '../database/entity.js';
|
|
2
|
-
import type { Query, QueryOptions } from '../database/query.js';
|
|
3
|
-
import type { SearchResult, SearchResultItem } from './search-result.js';
|
|
4
|
-
export type SearchCursorOptions<T extends Entity> = QueryOptions<T> & {
|
|
5
|
-
batchSize?: number;
|
|
6
|
-
};
|
|
7
|
-
declare const type: unique symbol;
|
|
8
|
-
export declare abstract class SearchIndex<T extends Entity> {
|
|
9
|
-
[type]: T;
|
|
10
|
-
/**
|
|
11
|
-
* search all entities using an automatic cursor
|
|
12
|
-
* @param query search query
|
|
13
|
-
* @param options search options
|
|
14
|
-
*/
|
|
15
|
-
searchCursor(query: Query<T>, options?: SearchCursorOptions<T>): AsyncIterable<SearchResultItem<T>>;
|
|
16
|
-
/**
|
|
17
|
-
* search all entities instead of just a chunk
|
|
18
|
-
* @param query search query
|
|
19
|
-
* @param options search option
|
|
20
|
-
*/
|
|
21
|
-
searchAll(query: Query<T>, options?: QueryOptions<T>): Promise<SearchResultItem<T>[]>;
|
|
22
|
-
/**
|
|
23
|
-
* index entities for search
|
|
24
|
-
* @param entities entities to index
|
|
25
|
-
*/
|
|
26
|
-
abstract index(entities: T[]): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* delete entity from index
|
|
29
|
-
* @param id entity id to delete
|
|
30
|
-
*/
|
|
31
|
-
abstract delete(id: string): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* delete matching entities from index
|
|
34
|
-
* @param query query to search for matching entities
|
|
35
|
-
*/
|
|
36
|
-
abstract deleteByQuery(query: Query<T>): Promise<void>;
|
|
37
|
-
abstract search(query: Query<T>, options?: QueryOptions<T>): Promise<SearchResult<T>>;
|
|
38
|
-
abstract search(cursor: string, options?: QueryOptions<T>): Promise<SearchResult<T>>;
|
|
39
|
-
abstract search(queryOrCursor: Query<T> | string, options?: QueryOptions<T>): Promise<SearchResult<T>>;
|
|
40
|
-
abstract count(query?: Query<T>, options?: QueryOptions<T>): Promise<number>;
|
|
41
|
-
/**
|
|
42
|
-
* drop index. If you only want to delete all items from the index, use {@link deleteByQuery} with an empty query.
|
|
43
|
-
*/
|
|
44
|
-
abstract drop(): Promise<void>;
|
|
45
|
-
}
|
|
46
|
-
export {};
|