@lossless.org/client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/.smartconfig.json +37 -0
  2. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  3. package/dist_ts/00_commitinfo_data.js +9 -0
  4. package/dist_ts/classes.losslessorgclient.d.ts +32 -0
  5. package/dist_ts/classes.losslessorgclient.js +103 -0
  6. package/dist_ts/core/classes.error.d.ts +16 -0
  7. package/dist_ts/core/classes.error.js +29 -0
  8. package/dist_ts/core/classes.operation.d.ts +17 -0
  9. package/dist_ts/core/classes.operation.js +70 -0
  10. package/dist_ts/core/interfaces.d.ts +18 -0
  11. package/dist_ts/core/interfaces.js +2 -0
  12. package/dist_ts/index.d.ts +4 -0
  13. package/dist_ts/index.js +3 -0
  14. package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
  15. package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
  16. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
  17. package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
  18. package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
  19. package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
  20. package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
  21. package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
  22. package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
  23. package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
  24. package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
  25. package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
  26. package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
  27. package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
  28. package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
  29. package/dist_ts/nosqldb/classes.cached-document.js +112 -0
  30. package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
  31. package/dist_ts/nosqldb/classes.collection.js +1568 -0
  32. package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
  33. package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
  34. package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
  35. package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
  36. package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
  37. package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
  38. package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
  39. package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
  40. package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
  41. package/dist_ts/nosqldb/classes.connection.js +23 -0
  42. package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
  43. package/dist_ts/nosqldb/classes.convenience.js +5 -0
  44. package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
  45. package/dist_ts/nosqldb/classes.cursor.js +82 -0
  46. package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
  47. package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
  48. package/dist_ts/nosqldb/classes.db.d.ts +98 -0
  49. package/dist_ts/nosqldb/classes.db.js +434 -0
  50. package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
  51. package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
  52. package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
  53. package/dist_ts/nosqldb/classes.doc.js +2976 -0
  54. package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
  55. package/dist_ts/nosqldb/classes.easystore.js +199 -0
  56. package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
  57. package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
  58. package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
  59. package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
  60. package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
  61. package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
  62. package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
  63. package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
  64. package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
  65. package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
  66. package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
  67. package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
  68. package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
  69. package/dist_ts/nosqldb/classes.persistence.js +34 -0
  70. package/dist_ts/nosqldb/classes.session.d.ts +28 -0
  71. package/dist_ts/nosqldb/classes.session.js +246 -0
  72. package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
  73. package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
  74. package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
  75. package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
  76. package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
  77. package/dist_ts/nosqldb/classes.watcher.js +98 -0
  78. package/dist_ts/nosqldb/index.d.ts +27 -0
  79. package/dist_ts/nosqldb/index.js +18 -0
  80. package/dist_ts/nosqldb/logging.d.ts +2 -0
  81. package/dist_ts/nosqldb/logging.js +3 -0
  82. package/dist_ts/nosqldb/plugins.d.ts +17 -0
  83. package/dist_ts/nosqldb/plugins.js +20 -0
  84. package/dist_ts/nosqldb/shim.d.ts +1 -0
  85. package/dist_ts/nosqldb/shim.js +8 -0
  86. package/dist_ts/nosqldb/testsupport.d.ts +3 -0
  87. package/dist_ts/nosqldb/testsupport.js +3 -0
  88. package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
  89. package/dist_ts/objectstorage/classes.bucket.js +939 -0
  90. package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
  91. package/dist_ts/objectstorage/classes.connection.js +27 -0
  92. package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
  93. package/dist_ts/objectstorage/classes.directory.js +335 -0
  94. package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
  95. package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
  96. package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
  97. package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
  98. package/dist_ts/objectstorage/classes.file.d.ts +91 -0
  99. package/dist_ts/objectstorage/classes.file.js +255 -0
  100. package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
  101. package/dist_ts/objectstorage/classes.listcursor.js +67 -0
  102. package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
  103. package/dist_ts/objectstorage/classes.metadata.js +113 -0
  104. package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
  105. package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
  106. package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
  107. package/dist_ts/objectstorage/classes.trash.js +22 -0
  108. package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
  109. package/dist_ts/objectstorage/classes.watcher.js +249 -0
  110. package/dist_ts/objectstorage/helpers.d.ts +25 -0
  111. package/dist_ts/objectstorage/helpers.js +215 -0
  112. package/dist_ts/objectstorage/index.d.ts +13 -0
  113. package/dist_ts/objectstorage/index.js +13 -0
  114. package/dist_ts/objectstorage/interfaces.d.ts +276 -0
  115. package/dist_ts/objectstorage/interfaces.js +2 -0
  116. package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
  117. package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
  118. package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
  119. package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
  120. package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
  121. package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
  122. package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
  123. package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
  124. package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
  125. package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
  126. package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
  127. package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
  128. package/dist_ts/objectstorage/plugins.d.ts +17 -0
  129. package/dist_ts/objectstorage/plugins.js +23 -0
  130. package/dist_ts/plugins.d.ts +4 -0
  131. package/dist_ts/plugins.js +5 -0
  132. package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
  133. package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
  134. package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
  135. package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
  136. package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
  137. package/dist_ts/sqldb/classes.sqltable.js +70 -0
  138. package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
  139. package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
  140. package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
  141. package/dist_ts/sqldb/clickhouse/index.js +13 -0
  142. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
  143. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
  144. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
  145. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
  146. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
  147. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
  148. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
  149. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
  150. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
  151. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
  152. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
  153. package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
  154. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
  155. package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
  156. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
  157. package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
  158. package/dist_ts/sqldb/index.d.ts +6 -0
  159. package/dist_ts/sqldb/index.js +6 -0
  160. package/dist_ts/sqldb/interfaces.d.ts +53 -0
  161. package/dist_ts/sqldb/interfaces.js +19 -0
  162. package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
  163. package/dist_ts/sqldb/internal.sqlpool.js +214 -0
  164. package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
  165. package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
  166. package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
  167. package/dist_ts/sqldb/plugins.mariadb.js +5 -0
  168. package/docs/source/smartbucket/license.md +19 -0
  169. package/docs/source/smartclickhouse/license.md +19 -0
  170. package/license.md +21 -0
  171. package/package.json +101 -0
  172. package/readme.md +157 -0
  173. package/ts/00_commitinfo_data.ts +8 -0
  174. package/ts/classes.losslessorgclient.ts +104 -0
  175. package/ts/core/classes.error.ts +31 -0
  176. package/ts/core/classes.operation.ts +60 -0
  177. package/ts/core/interfaces.ts +24 -0
  178. package/ts/index.ts +4 -0
  179. package/ts/nosqldb/classes.atomicdelete.ts +81 -0
  180. package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
  181. package/ts/nosqldb/classes.atomicupdate.ts +99 -0
  182. package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
  183. package/ts/nosqldb/classes.bsonassertion.ts +25 -0
  184. package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
  185. package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
  186. package/ts/nosqldb/classes.cached-document.ts +67 -0
  187. package/ts/nosqldb/classes.collection.ts +2399 -0
  188. package/ts/nosqldb/classes.collectionfactory.ts +87 -0
  189. package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
  190. package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
  191. package/ts/nosqldb/classes.collectiontopology.ts +645 -0
  192. package/ts/nosqldb/classes.connection.ts +31 -0
  193. package/ts/nosqldb/classes.convenience.ts +5 -0
  194. package/ts/nosqldb/classes.cursor.ts +88 -0
  195. package/ts/nosqldb/classes.cursoroperation.ts +38 -0
  196. package/ts/nosqldb/classes.db.ts +637 -0
  197. package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
  198. package/ts/nosqldb/classes.doc.ts +4928 -0
  199. package/ts/nosqldb/classes.easystore.ts +154 -0
  200. package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
  201. package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
  202. package/ts/nosqldb/classes.mongoadministration.ts +867 -0
  203. package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
  204. package/ts/nosqldb/classes.operationbudget.ts +75 -0
  205. package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
  206. package/ts/nosqldb/classes.persistence.ts +62 -0
  207. package/ts/nosqldb/classes.session.ts +389 -0
  208. package/ts/nosqldb/classes.storedinspection.ts +151 -0
  209. package/ts/nosqldb/classes.testdatabase.ts +272 -0
  210. package/ts/nosqldb/classes.watcher.ts +96 -0
  211. package/ts/nosqldb/index.ts +51 -0
  212. package/ts/nosqldb/logging.ts +3 -0
  213. package/ts/nosqldb/plugins.ts +37 -0
  214. package/ts/nosqldb/shim.ts +6 -0
  215. package/ts/nosqldb/testsupport.ts +13 -0
  216. package/ts/objectstorage/classes.bucket.ts +1114 -0
  217. package/ts/objectstorage/classes.connection.ts +36 -0
  218. package/ts/objectstorage/classes.directory.ts +425 -0
  219. package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
  220. package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
  221. package/ts/objectstorage/classes.file.ts +303 -0
  222. package/ts/objectstorage/classes.listcursor.ts +89 -0
  223. package/ts/objectstorage/classes.metadata.ts +134 -0
  224. package/ts/objectstorage/classes.smartbucket.ts +445 -0
  225. package/ts/objectstorage/classes.trash.ts +30 -0
  226. package/ts/objectstorage/classes.watcher.ts +289 -0
  227. package/ts/objectstorage/helpers.ts +254 -0
  228. package/ts/objectstorage/index.ts +13 -0
  229. package/ts/objectstorage/interfaces.ts +389 -0
  230. package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
  231. package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
  232. package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
  233. package/ts/objectstorage/internal.multipart.planner.ts +90 -0
  234. package/ts/objectstorage/internal.multipart.stream.ts +606 -0
  235. package/ts/objectstorage/internal.multipart.types.ts +106 -0
  236. package/ts/objectstorage/plugins.ts +35 -0
  237. package/ts/plugins.ts +4 -0
  238. package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
  239. package/ts/sqldb/classes.sqlconnection.ts +350 -0
  240. package/ts/sqldb/classes.sqltable.ts +70 -0
  241. package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
  242. package/ts/sqldb/clickhouse/index.ts +16 -0
  243. package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
  244. package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
  245. package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
  246. package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
  247. package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
  248. package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
  249. package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
  250. package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
  251. package/ts/sqldb/index.ts +6 -0
  252. package/ts/sqldb/interfaces.ts +61 -0
  253. package/ts/sqldb/internal.sqlpool.ts +179 -0
  254. package/ts/sqldb/plugins.clickhouse.ts +4 -0
  255. package/ts/sqldb/plugins.mariadb.ts +4 -0
@@ -0,0 +1,623 @@
1
+ /**
2
+ * Lucene to MongoDB query adapter for SmartData
3
+ */
4
+ import * as plugins from './plugins.js';
5
+ import { logger } from './logging.js';
6
+ /**
7
+ * Lucene query parser
8
+ */
9
+ export class LuceneParser {
10
+ pos = 0;
11
+ input = '';
12
+ tokens = [];
13
+ constructor() { }
14
+ /**
15
+ * Parse a Lucene query string into an AST
16
+ */
17
+ parse(query) {
18
+ this.input = query.trim();
19
+ this.pos = 0;
20
+ this.tokens = this.tokenize(this.input);
21
+ return this.parseQuery();
22
+ }
23
+ /**
24
+ * Tokenize the input string into tokens
25
+ */
26
+ tokenize(input) {
27
+ const specialChars = /[()\[\]{}"~^:]/;
28
+ const operators = /AND|OR|NOT|TO/;
29
+ let tokens = [];
30
+ let current = '';
31
+ let inQuote = false;
32
+ for (let i = 0; i < input.length; i++) {
33
+ const char = input[i];
34
+ // Handle quoted strings
35
+ if (char === '"') {
36
+ if (inQuote) {
37
+ tokens.push(current + char);
38
+ current = '';
39
+ inQuote = false;
40
+ }
41
+ else {
42
+ if (current)
43
+ tokens.push(current);
44
+ current = char;
45
+ inQuote = true;
46
+ }
47
+ continue;
48
+ }
49
+ if (inQuote) {
50
+ current += char;
51
+ continue;
52
+ }
53
+ // Handle whitespace
54
+ if (char === ' ' || char === '\t' || char === '\n') {
55
+ if (current) {
56
+ tokens.push(current);
57
+ current = '';
58
+ }
59
+ continue;
60
+ }
61
+ // Handle special characters
62
+ if (specialChars.test(char)) {
63
+ if (current) {
64
+ tokens.push(current);
65
+ current = '';
66
+ }
67
+ tokens.push(char);
68
+ continue;
69
+ }
70
+ current += char;
71
+ // Check if current is an operator
72
+ if (operators.test(current) && (i + 1 === input.length || /\s/.test(input[i + 1]))) {
73
+ tokens.push(current);
74
+ current = '';
75
+ }
76
+ }
77
+ if (current)
78
+ tokens.push(current);
79
+ return tokens;
80
+ }
81
+ /**
82
+ * Parse the main query expression
83
+ */
84
+ parseQuery() {
85
+ const left = this.parseBooleanOperand();
86
+ if (this.pos < this.tokens.length) {
87
+ const token = this.tokens[this.pos];
88
+ if (token === 'AND' || token === 'OR') {
89
+ this.pos++;
90
+ const right = this.parseQuery();
91
+ return {
92
+ type: token,
93
+ left,
94
+ right,
95
+ };
96
+ }
97
+ else if (token === 'NOT' || token === '-') {
98
+ this.pos++;
99
+ const right = this.parseQuery();
100
+ return {
101
+ type: 'NOT',
102
+ left,
103
+ right,
104
+ };
105
+ }
106
+ }
107
+ return left;
108
+ }
109
+ /**
110
+ * Parse boolean operands (terms, phrases, fields, groups)
111
+ */
112
+ parseBooleanOperand() {
113
+ if (this.pos >= this.tokens.length) {
114
+ throw new Error('Unexpected end of input');
115
+ }
116
+ const token = this.tokens[this.pos];
117
+ // Handle grouping with parentheses
118
+ if (token === '(') {
119
+ this.pos++;
120
+ const group = this.parseQuery();
121
+ if (this.pos < this.tokens.length && this.tokens[this.pos] === ')') {
122
+ this.pos++;
123
+ return { type: 'GROUP', value: group };
124
+ }
125
+ else {
126
+ throw new Error('Unclosed group');
127
+ }
128
+ }
129
+ // Handle fields (field:value)
130
+ if (this.pos + 1 < this.tokens.length && this.tokens[this.pos + 1] === ':') {
131
+ const field = token;
132
+ this.pos += 2; // Skip field and colon
133
+ if (this.pos < this.tokens.length) {
134
+ const value = this.parseBooleanOperand();
135
+ return { type: 'FIELD', field, value };
136
+ }
137
+ else {
138
+ throw new Error('Expected value after field');
139
+ }
140
+ }
141
+ // Handle range queries
142
+ if (token === '[' || token === '{') {
143
+ return this.parseRange();
144
+ }
145
+ // Handle phrases ("term term")
146
+ if (token.startsWith('"') && token.endsWith('"')) {
147
+ const phrase = token.slice(1, -1);
148
+ this.pos++;
149
+ // Check for proximity operator
150
+ let proximity;
151
+ if (this.pos < this.tokens.length && this.tokens[this.pos] === '~') {
152
+ this.pos++;
153
+ if (this.pos < this.tokens.length && /^\d+$/.test(this.tokens[this.pos])) {
154
+ proximity = parseInt(this.tokens[this.pos], 10);
155
+ this.pos++;
156
+ }
157
+ else {
158
+ throw new Error('Expected number after proximity operator');
159
+ }
160
+ }
161
+ return { type: 'PHRASE', value: phrase, proximity };
162
+ }
163
+ // Handle wildcards
164
+ if (token.includes('*') || token.includes('?')) {
165
+ this.pos++;
166
+ return { type: 'WILDCARD', value: token };
167
+ }
168
+ // Handle fuzzy searches
169
+ if (this.pos + 1 < this.tokens.length && this.tokens[this.pos + 1] === '~') {
170
+ const term = token;
171
+ this.pos += 2; // Skip term and tilde
172
+ let maxEdits = 2; // Default
173
+ if (this.pos < this.tokens.length && /^\d+$/.test(this.tokens[this.pos])) {
174
+ maxEdits = parseInt(this.tokens[this.pos], 10);
175
+ this.pos++;
176
+ }
177
+ return { type: 'FUZZY', value: term, maxEdits };
178
+ }
179
+ // Simple term
180
+ this.pos++;
181
+ return { type: 'TERM', value: token };
182
+ }
183
+ /**
184
+ * Parse range queries
185
+ */
186
+ parseRange() {
187
+ const includeLower = this.tokens[this.pos] === '[';
188
+ const includeUpper = this.tokens[this.pos + 4] === ']';
189
+ // Ensure tokens for lower, TO, upper, and closing bracket exist
190
+ if (this.pos + 4 >= this.tokens.length) {
191
+ throw new Error('Invalid range query syntax');
192
+ }
193
+ this.pos++; // Skip open bracket
194
+ const lower = this.tokens[this.pos];
195
+ this.pos++;
196
+ if (this.tokens[this.pos] !== 'TO') {
197
+ throw new Error('Expected TO in range query');
198
+ }
199
+ this.pos++;
200
+ const upper = this.tokens[this.pos];
201
+ this.pos++;
202
+ if (this.tokens[this.pos] !== (includeLower ? ']' : '}')) {
203
+ throw new Error('Invalid range query closing bracket');
204
+ }
205
+ this.pos++;
206
+ // For simplicity, assuming the field is handled separately
207
+ return {
208
+ type: 'RANGE',
209
+ field: '', // This will be filled by the field node
210
+ lower,
211
+ upper,
212
+ includeLower,
213
+ includeUpper,
214
+ };
215
+ }
216
+ }
217
+ /**
218
+ * Transformer for Lucene AST to MongoDB query
219
+ * FIXED VERSION - proper MongoDB query structure
220
+ */
221
+ export class LuceneToMongoTransformer {
222
+ defaultFields;
223
+ constructor(defaultFields = []) {
224
+ this.defaultFields = defaultFields;
225
+ }
226
+ /**
227
+ * Escape special characters for use in RegExp patterns
228
+ */
229
+ escapeRegex(input) {
230
+ return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
231
+ }
232
+ /**
233
+ * Transform a Lucene AST node to a MongoDB query
234
+ */
235
+ transform(node, searchFields) {
236
+ switch (node.type) {
237
+ case 'TERM':
238
+ return this.transformTerm(node, searchFields);
239
+ case 'PHRASE':
240
+ return this.transformPhrase(node, searchFields);
241
+ case 'FIELD':
242
+ return this.transformField(node);
243
+ case 'AND':
244
+ return this.transformAnd(node);
245
+ case 'OR':
246
+ return this.transformOr(node);
247
+ case 'NOT':
248
+ return this.transformNot(node);
249
+ case 'RANGE':
250
+ return this.transformRange(node);
251
+ case 'WILDCARD':
252
+ return this.transformWildcard(node, searchFields);
253
+ case 'FUZZY':
254
+ return this.transformFuzzy(node, searchFields);
255
+ case 'GROUP':
256
+ return this.transform(node.value, searchFields);
257
+ default:
258
+ throw new Error(`Unsupported node type: ${node.type}`);
259
+ }
260
+ }
261
+ /**
262
+ * Transform a term to MongoDB query
263
+ * FIXED: properly structured $or query for multiple fields
264
+ */
265
+ transformTerm(node, searchFields) {
266
+ // Build regex pattern, support wildcard (*) and fuzzy (?) if present
267
+ const term = node.value;
268
+ // Determine regex pattern: wildcard conversion or exact escape
269
+ let pattern;
270
+ if (term.includes('*') || term.includes('?')) {
271
+ pattern = this.luceneWildcardToRegex(term);
272
+ }
273
+ else {
274
+ pattern = this.escapeRegex(term);
275
+ }
276
+ // Search across provided fields or default fields
277
+ const fields = searchFields && searchFields.length > 0 ? searchFields : this.defaultFields;
278
+ const orConditions = fields.map((field) => ({
279
+ [field]: { $regex: pattern, $options: 'i' },
280
+ }));
281
+ return { $or: orConditions };
282
+ }
283
+ /**
284
+ * Transform a phrase to MongoDB query
285
+ * FIXED: properly structured $or query for multiple fields
286
+ */
287
+ transformPhrase(node, searchFields) {
288
+ // Use regex across provided fields or default fields, respecting word boundaries
289
+ const parts = node.value.split(/\s+/).map((t) => this.escapeRegex(t));
290
+ const pattern = parts.join('\\s+');
291
+ const fields = searchFields && searchFields.length > 0 ? searchFields : this.defaultFields;
292
+ const orConditions = fields.map((field) => ({
293
+ [field]: { $regex: pattern, $options: 'i' },
294
+ }));
295
+ return { $or: orConditions };
296
+ }
297
+ /**
298
+ * Transform a field query to MongoDB query
299
+ */
300
+ transformField(node) {
301
+ // Handle special case for range queries on fields
302
+ if (node.value.type === 'RANGE') {
303
+ const rangeNode = node.value;
304
+ rangeNode.field = node.field;
305
+ return this.transformRange(rangeNode);
306
+ }
307
+ // Handle special case for wildcards on fields
308
+ if (node.value.type === 'WILDCARD') {
309
+ return {
310
+ [node.field]: {
311
+ $regex: this.luceneWildcardToRegex(node.value.value),
312
+ $options: 'i',
313
+ },
314
+ };
315
+ }
316
+ // Handle special case for fuzzy searches on fields
317
+ if (node.value.type === 'FUZZY') {
318
+ return {
319
+ [node.field]: {
320
+ $regex: this.createFuzzyRegex(node.value.value),
321
+ $options: 'i',
322
+ },
323
+ };
324
+ }
325
+ // Special case for exact term matches on fields (supporting wildcard characters)
326
+ if (node.value.type === 'TERM') {
327
+ const val = node.value.value;
328
+ if (val.includes('*') || val.includes('?')) {
329
+ const regex = this.luceneWildcardToRegex(val);
330
+ return { [node.field]: { $regex: regex, $options: 'i' } };
331
+ }
332
+ return { [node.field]: { $regex: val, $options: 'i' } };
333
+ }
334
+ // Special case for phrase matches on fields
335
+ if (node.value.type === 'PHRASE') {
336
+ return {
337
+ [node.field]: {
338
+ $regex: `${node.value.value.replace(/\s+/g, '\\s+')}`,
339
+ $options: 'i',
340
+ },
341
+ };
342
+ }
343
+ // For other cases, we'll transform the value and apply it to the field
344
+ const transformedValue = this.transform(node.value);
345
+ // If the transformed value uses $text, we need to adapt it for the field
346
+ if (transformedValue.$text) {
347
+ return { [node.field]: { $regex: transformedValue.$text.$search, $options: 'i' } };
348
+ }
349
+ // Handle $or and $and cases
350
+ if (transformedValue.$or || transformedValue.$and) {
351
+ // This is a bit complex - we need to restructure the query to apply the field
352
+ // For now, simplify by just using a regex on the field
353
+ const term = this.extractTermFromBooleanQuery(transformedValue);
354
+ if (term) {
355
+ return { [node.field]: { $regex: term, $options: 'i' } };
356
+ }
357
+ }
358
+ return { [node.field]: transformedValue };
359
+ }
360
+ /**
361
+ * Extract a term from a boolean query (simplification)
362
+ */
363
+ extractTermFromBooleanQuery(query) {
364
+ if (query.$or && Array.isArray(query.$or) && query.$or.length > 0) {
365
+ const firstClause = query.$or[0];
366
+ for (const field in firstClause) {
367
+ if (firstClause[field].$regex) {
368
+ return firstClause[field].$regex;
369
+ }
370
+ }
371
+ }
372
+ if (query.$and && Array.isArray(query.$and) && query.$and.length > 0) {
373
+ const firstClause = query.$and[0];
374
+ for (const field in firstClause) {
375
+ if (firstClause[field].$regex) {
376
+ return firstClause[field].$regex;
377
+ }
378
+ }
379
+ }
380
+ return null;
381
+ }
382
+ /**
383
+ * Transform AND operator to MongoDB query
384
+ * FIXED: $and must be an array
385
+ */
386
+ transformAnd(node) {
387
+ return { $and: [this.transform(node.left), this.transform(node.right)] };
388
+ }
389
+ /**
390
+ * Transform OR operator to MongoDB query
391
+ * FIXED: $or must be an array
392
+ */
393
+ transformOr(node) {
394
+ return { $or: [this.transform(node.left), this.transform(node.right)] };
395
+ }
396
+ /**
397
+ * Transform NOT operator to MongoDB query
398
+ * FIXED: $and must be an array and $not usage
399
+ */
400
+ transformNot(node) {
401
+ const leftQuery = this.transform(node.left);
402
+ const rightQuery = this.transform(node.right);
403
+ // Create a query that includes left but excludes right
404
+ if (rightQuery.$text) {
405
+ // For text searches, we need a different approach
406
+ // We'll use a negated regex instead
407
+ const searchTerm = rightQuery.$text.$search.replace(/"/g, '');
408
+ // Determine the fields to apply the negation to
409
+ const notConditions = [];
410
+ for (const field in leftQuery) {
411
+ if (field !== '$or' && field !== '$and') {
412
+ notConditions.push({
413
+ [field]: { $not: { $regex: searchTerm, $options: 'i' } },
414
+ });
415
+ }
416
+ }
417
+ // If left query has $or or $and, we need to handle it differently
418
+ if (leftQuery.$or) {
419
+ return {
420
+ $and: [leftQuery, { $nor: [{ $or: notConditions }] }],
421
+ };
422
+ }
423
+ else {
424
+ // Simple case - just add $not to each field
425
+ return {
426
+ $and: [leftQuery, { $and: notConditions }],
427
+ };
428
+ }
429
+ }
430
+ else {
431
+ // For other queries, we can use $not directly
432
+ // We need to handle different structures based on the rightQuery
433
+ let notQuery = {};
434
+ if (rightQuery.$or) {
435
+ notQuery = { $nor: rightQuery.$or };
436
+ }
437
+ else if (rightQuery.$and) {
438
+ // Convert $and to $nor
439
+ notQuery = { $nor: rightQuery.$and };
440
+ }
441
+ else {
442
+ // Simple field condition
443
+ for (const field in rightQuery) {
444
+ notQuery[field] = { $not: rightQuery[field] };
445
+ }
446
+ }
447
+ return { $and: [leftQuery, notQuery] };
448
+ }
449
+ }
450
+ /**
451
+ * Transform range query to MongoDB query
452
+ */
453
+ transformRange(node) {
454
+ const range = {};
455
+ if (node.lower !== '*') {
456
+ range[node.includeLower ? '$gte' : '$gt'] = this.parseValue(node.lower);
457
+ }
458
+ if (node.upper !== '*') {
459
+ range[node.includeUpper ? '$lte' : '$lt'] = this.parseValue(node.upper);
460
+ }
461
+ return { [node.field]: range };
462
+ }
463
+ /**
464
+ * Transform wildcard query to MongoDB query
465
+ * FIXED: properly structured for multiple fields
466
+ */
467
+ transformWildcard(node, searchFields) {
468
+ // Convert Lucene wildcards to MongoDB regex
469
+ const regex = this.luceneWildcardToRegex(node.value);
470
+ // If specific fields are provided, search wildcard across those fields
471
+ if (searchFields && searchFields.length > 0) {
472
+ const orConditions = searchFields.map((field) => ({
473
+ [field]: { $regex: regex, $options: 'i' },
474
+ }));
475
+ return { $or: orConditions };
476
+ }
477
+ // By default, apply to the default field
478
+ return { $regex: regex, $options: 'i' };
479
+ }
480
+ /**
481
+ * Transform fuzzy query to MongoDB query
482
+ * FIXED: properly structured for multiple fields
483
+ */
484
+ transformFuzzy(node, searchFields) {
485
+ // MongoDB doesn't have built-in fuzzy search
486
+ // This is a very basic approach using regex
487
+ const regex = this.createFuzzyRegex(node.value);
488
+ // If specific fields are provided, search fuzzy term across those fields
489
+ if (searchFields && searchFields.length > 0) {
490
+ const orConditions = searchFields.map((field) => ({
491
+ [field]: { $regex: regex, $options: 'i' },
492
+ }));
493
+ return { $or: orConditions };
494
+ }
495
+ // By default, apply to the default field
496
+ return { $regex: regex, $options: 'i' };
497
+ }
498
+ /**
499
+ * Convert Lucene wildcards to MongoDB regex patterns
500
+ */
501
+ luceneWildcardToRegex(wildcardPattern) {
502
+ // Replace Lucene wildcards with regex equivalents
503
+ // * => .*
504
+ // ? => .
505
+ // Also escape regex special chars
506
+ return wildcardPattern
507
+ .replace(/([.+^${}()|\\])/g, '\\$1') // Escape regex special chars
508
+ .replace(/\*/g, '.*')
509
+ .replace(/\?/g, '.');
510
+ }
511
+ /**
512
+ * Create a simplified fuzzy search regex
513
+ */
514
+ createFuzzyRegex(term) {
515
+ // For a very simple approach, we allow some characters to be optional
516
+ let regex = '';
517
+ for (let i = 0; i < term.length; i++) {
518
+ // Make every other character optional (simplified fuzzy)
519
+ if (i % 2 === 1) {
520
+ regex += term[i] + '?';
521
+ }
522
+ else {
523
+ regex += term[i];
524
+ }
525
+ }
526
+ return regex;
527
+ }
528
+ /**
529
+ * Parse string values to appropriate types (numbers, dates, etc.)
530
+ */
531
+ parseValue(value) {
532
+ // Try to parse as number
533
+ if (/^-?\d+$/.test(value)) {
534
+ return parseInt(value, 10);
535
+ }
536
+ if (/^-?\d+\.\d+$/.test(value)) {
537
+ return parseFloat(value);
538
+ }
539
+ // Try to parse as date (simplified)
540
+ const date = new Date(value);
541
+ if (!isNaN(date.getTime())) {
542
+ return date;
543
+ }
544
+ // Default to string
545
+ return value;
546
+ }
547
+ }
548
+ /**
549
+ * Main adapter class
550
+ */
551
+ export class SmartdataLuceneAdapter {
552
+ parser;
553
+ transformer;
554
+ defaultSearchFields = [];
555
+ /**
556
+ * @param defaultSearchFields - Optional array of field names to search across when no field is specified
557
+ */
558
+ constructor(defaultSearchFields) {
559
+ this.parser = new LuceneParser();
560
+ // Pass default searchable fields into transformer
561
+ this.transformer = new LuceneToMongoTransformer(defaultSearchFields || []);
562
+ if (defaultSearchFields) {
563
+ this.defaultSearchFields = defaultSearchFields;
564
+ }
565
+ }
566
+ /**
567
+ * Convert a Lucene query string to a MongoDB query object
568
+ * @param luceneQuery - The Lucene query string to convert
569
+ * @param searchFields - Optional array of field names to search across (overrides defaultSearchFields)
570
+ */
571
+ convert(luceneQuery, searchFields) {
572
+ try {
573
+ // For simple single-term queries (no field:, boolean, grouping), use simpler regex
574
+ if (!luceneQuery.includes(':') &&
575
+ !luceneQuery.includes(' AND ') &&
576
+ !luceneQuery.includes(' OR ') &&
577
+ !luceneQuery.includes(' NOT ') &&
578
+ !luceneQuery.includes('(') &&
579
+ !luceneQuery.includes('[')) {
580
+ const fieldsToSearch = searchFields || this.defaultSearchFields;
581
+ if (fieldsToSearch && fieldsToSearch.length > 0) {
582
+ // Handle wildcard characters in query
583
+ let pattern = luceneQuery;
584
+ if (luceneQuery.includes('*') || luceneQuery.includes('?')) {
585
+ // Use transformer to convert wildcard pattern
586
+ pattern = this.transformer.luceneWildcardToRegex(luceneQuery);
587
+ }
588
+ return {
589
+ $or: fieldsToSearch.map((field) => ({
590
+ [field]: { $regex: pattern, $options: 'i' },
591
+ })),
592
+ };
593
+ }
594
+ }
595
+ // For more complex queries, use the full parser
596
+ // Parse the Lucene query into an AST
597
+ const ast = this.parser.parse(luceneQuery);
598
+ // Use provided searchFields, fall back to defaultSearchFields
599
+ const fieldsToSearch = searchFields || this.defaultSearchFields;
600
+ // Transform the AST to a MongoDB query
601
+ return this.transformWithFields(ast, fieldsToSearch);
602
+ }
603
+ catch (error) {
604
+ logger.log('error', `Failed to convert Lucene query "${luceneQuery}":`, error);
605
+ throw new Error(`Failed to convert Lucene query: ${error}`);
606
+ }
607
+ }
608
+ /**
609
+ * Helper method to transform the AST with field information
610
+ */
611
+ transformWithFields(node, searchFields) {
612
+ // Special case for term nodes without a specific field
613
+ if (node.type === 'TERM' ||
614
+ node.type === 'PHRASE' ||
615
+ node.type === 'WILDCARD' ||
616
+ node.type === 'FUZZY') {
617
+ return this.transformer.transform(node, searchFields);
618
+ }
619
+ // For other node types, use the standard transformation
620
+ return this.transformer.transform(node);
621
+ }
622
+ }
623
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5sdWNlbmUuYWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL25vc3FsZGIvY2xhc3Nlcy5sdWNlbmUuYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUE4RXRDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFDZixHQUFHLEdBQVcsQ0FBQyxDQUFDO0lBQ2hCLEtBQUssR0FBVyxFQUFFLENBQUM7SUFDbkIsTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUU5QixnQkFBZSxDQUFDO0lBRWhCOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEtBQWE7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDYixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXhDLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNLLFFBQVEsQ0FBQyxLQUFhO1FBQzVCLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDO1FBQ3RDLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQztRQUVsQyxJQUFJLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFDMUIsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztRQUVwQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxD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