@mcp-z/mcp-outlook 1.0.12 → 1.0.13
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/dist/cjs/email/querying/query-builder.d.cts +1 -0
- package/dist/cjs/email/querying/query-builder.d.ts +1 -0
- package/dist/cjs/email/querying/query-builder.js +137 -165
- package/dist/cjs/email/querying/query-builder.js.map +1 -1
- package/dist/cjs/email/querying/search-execution.js +204 -82
- package/dist/cjs/email/querying/search-execution.js.map +1 -1
- package/dist/cjs/mcp/tools/message-search.js +3 -0
- package/dist/cjs/mcp/tools/message-search.js.map +1 -1
- package/dist/esm/email/querying/query-builder.d.ts +1 -0
- package/dist/esm/email/querying/query-builder.js +120 -136
- package/dist/esm/email/querying/query-builder.js.map +1 -1
- package/dist/esm/email/querying/search-execution.js +144 -70
- package/dist/esm/email/querying/search-execution.js.map +1 -1
- package/dist/esm/mcp/tools/message-search.js +1 -0
- package/dist/esm/mcp/tools/message-search.js.map +1 -1
- package/package.json +1 -1
|
@@ -23,6 +23,7 @@ export interface ODataFilterResult {
|
|
|
23
23
|
hasFullText: boolean;
|
|
24
24
|
}
|
|
25
25
|
export declare function toGraphFilter(query: QueryNode): ODataFilterResult;
|
|
26
|
+
export declare function buildQueryFilter(query: QueryNode): string;
|
|
26
27
|
export declare function toOutlookFilter(parsed: QueryNode, _options?: {
|
|
27
28
|
includeBodyContent?: boolean;
|
|
28
29
|
useCaseInsensitiveWrap?: boolean;
|
|
@@ -23,6 +23,7 @@ export interface ODataFilterResult {
|
|
|
23
23
|
hasFullText: boolean;
|
|
24
24
|
}
|
|
25
25
|
export declare function toGraphFilter(query: QueryNode): ODataFilterResult;
|
|
26
|
+
export declare function buildQueryFilter(query: QueryNode): string;
|
|
26
27
|
export declare function toOutlookFilter(parsed: QueryNode, _options?: {
|
|
27
28
|
includeBodyContent?: boolean;
|
|
28
29
|
useCaseInsensitiveWrap?: boolean;
|
|
@@ -12,6 +12,9 @@ _export(exports, {
|
|
|
12
12
|
get OUTLOOK_CATEGORIES () {
|
|
13
13
|
return OUTLOOK_CATEGORIES;
|
|
14
14
|
},
|
|
15
|
+
get buildQueryFilter () {
|
|
16
|
+
return buildQueryFilter;
|
|
17
|
+
},
|
|
15
18
|
get extractOutlookFilters () {
|
|
16
19
|
return extractOutlookFilters;
|
|
17
20
|
},
|
|
@@ -90,7 +93,7 @@ function toGraphFilter(query) {
|
|
|
90
93
|
}
|
|
91
94
|
if (hasFullTextIntent(query)) {
|
|
92
95
|
var searchCollect = collectSearchTerms(query);
|
|
93
|
-
var search = searchCollect.terms.length ? searchCollect.terms.join('
|
|
96
|
+
var search = searchCollect.terms.length ? searchCollect.terms.join(' OR ') : null;
|
|
94
97
|
return {
|
|
95
98
|
search: search,
|
|
96
99
|
filter: null,
|
|
@@ -98,16 +101,144 @@ function toGraphFilter(query) {
|
|
|
98
101
|
hasFullText: true
|
|
99
102
|
};
|
|
100
103
|
}
|
|
104
|
+
var filterStr = buildQueryFilter(query);
|
|
105
|
+
var cleanedFilter = filterStr && typeof filterStr === 'string' && filterStr.trim().length ? filterStr.trim() : null;
|
|
106
|
+
return {
|
|
107
|
+
search: null,
|
|
108
|
+
filter: cleanedFilter,
|
|
109
|
+
requireBodyClientFilter: false,
|
|
110
|
+
hasFullText: false
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function collectSearchTerms(query) {
|
|
114
|
+
var state = {
|
|
115
|
+
terms: [],
|
|
116
|
+
usesText: false,
|
|
117
|
+
usesBody: false,
|
|
118
|
+
usesExact: false
|
|
119
|
+
};
|
|
120
|
+
walkNode(query);
|
|
121
|
+
return state;
|
|
122
|
+
function walkNode(node) {
|
|
123
|
+
if (!node || (typeof node === "undefined" ? "undefined" : _type_of(node)) !== 'object') return;
|
|
124
|
+
if (node.$and) {
|
|
125
|
+
node.$and.forEach(function(child) {
|
|
126
|
+
return walkNode(child);
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (node.$or) {
|
|
131
|
+
node.$or.forEach(function(child) {
|
|
132
|
+
return walkNode(child);
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (node.$not) {
|
|
137
|
+
walkNode(node.$not);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if ('exactPhrase' in node && node.exactPhrase) {
|
|
141
|
+
state.usesExact = true;
|
|
142
|
+
pushExactPhrase(node.exactPhrase);
|
|
143
|
+
}
|
|
144
|
+
pushOperatorTerms(node.subject);
|
|
145
|
+
if ('text' in node && node.text) {
|
|
146
|
+
state.usesText = true;
|
|
147
|
+
pushOperatorTerms(node.text);
|
|
148
|
+
}
|
|
149
|
+
if ('body' in node && node.body) {
|
|
150
|
+
state.usesBody = true;
|
|
151
|
+
pushOperatorTerms(node.body);
|
|
152
|
+
}
|
|
153
|
+
// Other fields (hasAttachment, importance, date) are handled via OData filters (emit())
|
|
154
|
+
// and should not create search terms with colon prefixes that break Graph $search.
|
|
155
|
+
}
|
|
156
|
+
function pushExactPhrase(value) {
|
|
157
|
+
var phrase = String(value);
|
|
158
|
+
if (!phrase.trim()) return;
|
|
159
|
+
pushAnyTerms([
|
|
160
|
+
'"'.concat(phrase, '"')
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
function pushOperatorTerms(value) {
|
|
164
|
+
if (!value) return;
|
|
165
|
+
if (typeof value === 'string') {
|
|
166
|
+
var clause = buildClause(null, value);
|
|
167
|
+
if (clause) state.terms.push(clause);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(value.$any) && value.$any.length > 0) {
|
|
171
|
+
pushAnyTerms(value.$any);
|
|
172
|
+
}
|
|
173
|
+
if (Array.isArray(value.$all) && value.$all.length > 0) {
|
|
174
|
+
pushAllTerms(value.$all);
|
|
175
|
+
}
|
|
176
|
+
if (Array.isArray(value.$none) && value.$none.length > 0) {
|
|
177
|
+
var clauses = value.$none.map(function(term) {
|
|
178
|
+
return buildClause(null, String(term !== null && term !== void 0 ? term : ''));
|
|
179
|
+
}).filter(Boolean);
|
|
180
|
+
if (clauses.length === 1) {
|
|
181
|
+
state.terms.push("NOT ".concat(clauses[0]));
|
|
182
|
+
} else if (clauses.length > 1) {
|
|
183
|
+
state.terms.push("NOT (".concat(clauses.join(' OR '), ")"));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function pushAnyTerms(values) {
|
|
188
|
+
var clauses = values.map(function(val) {
|
|
189
|
+
return buildClause(null, val);
|
|
190
|
+
}).filter(Boolean);
|
|
191
|
+
if (!clauses.length) return;
|
|
192
|
+
state.terms.push(clauses.length === 1 ? clauses[0] : "(".concat(clauses.join(' OR '), ")"));
|
|
193
|
+
}
|
|
194
|
+
function pushAllTerms(values) {
|
|
195
|
+
var clauses = values.map(function(val) {
|
|
196
|
+
return buildClause(null, val);
|
|
197
|
+
}).filter(Boolean);
|
|
198
|
+
if (!clauses.length) return;
|
|
199
|
+
state.terms.push(clauses.length === 1 ? clauses[0] : "(".concat(clauses.join(' AND '), ")"));
|
|
200
|
+
}
|
|
201
|
+
function escapeKQL(value) {
|
|
202
|
+
return value.replace(/\\/g, '\\\\').replace(/:/g, '\\:').replace(/\(/g, '\\(').replace(/\)/g, '\\)').replace(/\{/g, '\\{').replace(/\}/g, '\\}').replace(/\[/g, '\\[').replace(/\]/g, '\\]').replace(/"/g, '\\"').replace(/\*/g, '\\*').replace(/\?/g, '\\?').replace(/</g, '\\<').replace(/>/g, '\\>').replace(/_/g, '\\_');
|
|
203
|
+
}
|
|
204
|
+
function buildClause(_prefix, value) {
|
|
205
|
+
var trimmed = value.trim();
|
|
206
|
+
if (!trimmed) return '';
|
|
207
|
+
var escaped = escapeKQL(trimmed);
|
|
208
|
+
var shouldQuote = /[^a-zA-Z\s]/.test(trimmed) || /\s/.test(trimmed);
|
|
209
|
+
return shouldQuote ? '"'.concat(escaped, '"') : escaped;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function hasFullTextIntent(node) {
|
|
213
|
+
if (!node || (typeof node === "undefined" ? "undefined" : _type_of(node)) !== 'object') return false;
|
|
214
|
+
if (node.kqlQuery) return true;
|
|
215
|
+
if (node.exactPhrase) return true;
|
|
216
|
+
if ('subject' in node && node.subject) return true;
|
|
217
|
+
if ('text' in node && node.text) return true;
|
|
218
|
+
if ('body' in node && node.body) return true;
|
|
219
|
+
if ('$and' in node && node.$and) {
|
|
220
|
+
return node.$and.some(function(child) {
|
|
221
|
+
return hasFullTextIntent(child);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
if ('$or' in node && node.$or) {
|
|
225
|
+
return node.$or.some(function(child) {
|
|
226
|
+
return hasFullTextIntent(child);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
if ('$not' in node && node.$not) {
|
|
230
|
+
return hasFullTextIntent(node.$not);
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
function buildQueryFilter(query) {
|
|
101
235
|
function L(s) {
|
|
102
|
-
// Microsoft Graph does NOT support toLower() function in OData filters
|
|
103
|
-
// Case-insensitive matching must be done client-side or via $search
|
|
104
236
|
return s;
|
|
105
237
|
}
|
|
106
238
|
function p(s) {
|
|
107
239
|
return "(".concat(s, ")");
|
|
108
240
|
}
|
|
109
241
|
function recip(coll, V) {
|
|
110
|
-
// Graph may reject functions on nested properties; use equality on nested address/name fields.
|
|
111
242
|
var left = "r/emailAddress/address eq ".concat(V);
|
|
112
243
|
var right = "r/emailAddress/name eq ".concat(V);
|
|
113
244
|
return "".concat(coll, "/any(r: ").concat(left, " or ").concat(right, ")");
|
|
@@ -115,15 +246,12 @@ function toGraphFilter(query) {
|
|
|
115
246
|
function fv(field, raw) {
|
|
116
247
|
if (raw == null) return '';
|
|
117
248
|
var rawStr = String(raw);
|
|
118
|
-
// For text and body fields, skip OData filtering entirely (uses KQL search instead)
|
|
119
|
-
// Do this BEFORE validation so we don't throw on valid text/body queries
|
|
120
249
|
if (field === 'text' || field === 'body') {
|
|
121
250
|
if (rawStr.trim() === '') {
|
|
122
251
|
throw new Error("Invalid ".concat(field, " value: empty string"));
|
|
123
252
|
}
|
|
124
253
|
return '';
|
|
125
254
|
}
|
|
126
|
-
// For all other fields, validate non-empty AFTER checking for null
|
|
127
255
|
if (rawStr.trim() === '') {
|
|
128
256
|
throw new Error("Invalid ".concat(field, " value: empty string"));
|
|
129
257
|
}
|
|
@@ -131,14 +259,11 @@ function toGraphFilter(query) {
|
|
|
131
259
|
switch(field){
|
|
132
260
|
case 'from':
|
|
133
261
|
{
|
|
134
|
-
// For email addresses emit equality checks on nested address/name;
|
|
135
|
-
// for name-only tokens, skip server-side filter (handled client-side or via $search).
|
|
136
262
|
if (rawStr.includes('@')) {
|
|
137
263
|
var addrEq = "".concat(L('from/emailAddress/address'), " eq ").concat(V);
|
|
138
264
|
var nameEq = "".concat(L('from/emailAddress/name'), " eq ").concat(V);
|
|
139
265
|
return p("".concat(addrEq, " or ").concat(nameEq));
|
|
140
266
|
}
|
|
141
|
-
// Don't emit a server-side filter for name-only 'from' tokens.
|
|
142
267
|
return '';
|
|
143
268
|
}
|
|
144
269
|
case 'to':
|
|
@@ -148,25 +273,16 @@ function toGraphFilter(query) {
|
|
|
148
273
|
case 'bcc':
|
|
149
274
|
return recip('bccRecipients', V);
|
|
150
275
|
case 'subject':
|
|
151
|
-
// Microsoft Graph does NOT support contains() function in OData filters
|
|
152
|
-
// Use startswith as a partial alternative or rely on $search
|
|
153
276
|
if (rawStr.includes('-') || rawStr.length < 3) return '';
|
|
154
277
|
return "startswith(subject, ".concat(V, ")");
|
|
155
278
|
case 'categories':
|
|
156
279
|
{
|
|
157
|
-
// mapOutlookCategory will throw on invalid input (fail fast)
|
|
158
280
|
var systemCategory = mapOutlookCategory(rawStr);
|
|
159
|
-
// Use the categories OData property with exact case-sensitive match
|
|
160
281
|
return "categories/any(c: c eq '".concat(systemCategory, "')");
|
|
161
282
|
}
|
|
162
283
|
case 'label':
|
|
163
|
-
|
|
164
|
-
// Direct passthrough to categories for Outlook (case-sensitive)
|
|
165
|
-
return "categories/any(c: c eq '".concat(rawStr.replace(/'/g, "''"), "')");
|
|
166
|
-
}
|
|
284
|
+
return "categories/any(c: c eq '".concat(rawStr.replace(/'/g, "''"), "')");
|
|
167
285
|
default:
|
|
168
|
-
// Microsoft Graph does NOT support contains() function
|
|
169
|
-
// For unknown fields, skip server-side filtering
|
|
170
286
|
return '';
|
|
171
287
|
}
|
|
172
288
|
}
|
|
@@ -190,7 +306,6 @@ function toGraphFilter(query) {
|
|
|
190
306
|
var results = op.$any.map(function(v) {
|
|
191
307
|
return fv(field, String(v !== null && v !== void 0 ? v : ''));
|
|
192
308
|
});
|
|
193
|
-
// Filter out empty strings (from fields like text/body that don't generate OData filters)
|
|
194
309
|
var validResults = results.filter(function(s) {
|
|
195
310
|
return s && s.trim();
|
|
196
311
|
});
|
|
@@ -201,7 +316,6 @@ function toGraphFilter(query) {
|
|
|
201
316
|
var results1 = op.$all.map(function(v) {
|
|
202
317
|
return fv(field, String(v !== null && v !== void 0 ? v : ''));
|
|
203
318
|
});
|
|
204
|
-
// Filter out empty strings (from fields like text/body that don't generate OData filters)
|
|
205
319
|
var validResults1 = results1.filter(function(s) {
|
|
206
320
|
return s && s.trim();
|
|
207
321
|
});
|
|
@@ -212,7 +326,6 @@ function toGraphFilter(query) {
|
|
|
212
326
|
var results2 = op.$none.map(function(v) {
|
|
213
327
|
return fv(field, String(v !== null && v !== void 0 ? v : ''));
|
|
214
328
|
});
|
|
215
|
-
// Filter out empty strings (from fields like text/body that don't generate OData filters)
|
|
216
329
|
var validResults2 = results2.filter(function(s) {
|
|
217
330
|
return s && s.trim();
|
|
218
331
|
});
|
|
@@ -279,148 +392,7 @@ function toGraphFilter(query) {
|
|
|
279
392
|
}
|
|
280
393
|
return '';
|
|
281
394
|
}
|
|
282
|
-
|
|
283
|
-
var cleanedFilter = filterStr && typeof filterStr === 'string' && filterStr.trim().length ? filterStr.trim() : null;
|
|
284
|
-
return {
|
|
285
|
-
search: null,
|
|
286
|
-
filter: cleanedFilter,
|
|
287
|
-
requireBodyClientFilter: false,
|
|
288
|
-
hasFullText: false
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
function collectSearchTerms(query) {
|
|
292
|
-
var state = {
|
|
293
|
-
terms: [],
|
|
294
|
-
usesText: false,
|
|
295
|
-
usesBody: false,
|
|
296
|
-
usesExact: false
|
|
297
|
-
};
|
|
298
|
-
walkNode(query);
|
|
299
|
-
return state;
|
|
300
|
-
function walkNode(node) {
|
|
301
|
-
if (!node || (typeof node === "undefined" ? "undefined" : _type_of(node)) !== 'object') return;
|
|
302
|
-
if (node.$and) {
|
|
303
|
-
node.$and.forEach(function(child) {
|
|
304
|
-
return walkNode(child);
|
|
305
|
-
});
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
if (node.$or) {
|
|
309
|
-
node.$or.forEach(function(child) {
|
|
310
|
-
return walkNode(child);
|
|
311
|
-
});
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
if (node.$not) {
|
|
315
|
-
walkNode(node.$not);
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
if ('exactPhrase' in node && node.exactPhrase) {
|
|
319
|
-
state.usesExact = true;
|
|
320
|
-
pushExactPhrase(node.exactPhrase);
|
|
321
|
-
}
|
|
322
|
-
pushOperatorTerms(node.subject);
|
|
323
|
-
if ('text' in node && node.text) {
|
|
324
|
-
state.usesText = true;
|
|
325
|
-
pushOperatorTerms(node.text);
|
|
326
|
-
}
|
|
327
|
-
if ('body' in node && node.body) {
|
|
328
|
-
state.usesBody = true;
|
|
329
|
-
pushOperatorTerms(node.body);
|
|
330
|
-
}
|
|
331
|
-
// Other fields (hasAttachment, importance, date) are handled via OData filters (emit())
|
|
332
|
-
// and should not create search terms with colon prefixes that break Graph $search.
|
|
333
|
-
}
|
|
334
|
-
function pushExactPhrase(value) {
|
|
335
|
-
var phrase = String(value);
|
|
336
|
-
if (!phrase.trim()) return;
|
|
337
|
-
pushAnyTerms([
|
|
338
|
-
'"'.concat(phrase, '"')
|
|
339
|
-
]);
|
|
340
|
-
}
|
|
341
|
-
function pushOperatorTerms(value) {
|
|
342
|
-
if (!value) return;
|
|
343
|
-
if (typeof value === 'string') {
|
|
344
|
-
var clause = buildClause(null, value);
|
|
345
|
-
if (clause) state.terms.push(clause);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
if (Array.isArray(value.$any) && value.$any.length > 0) {
|
|
349
|
-
pushAnyTerms(value.$any);
|
|
350
|
-
}
|
|
351
|
-
if (Array.isArray(value.$all) && value.$all.length > 0) {
|
|
352
|
-
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
353
|
-
try {
|
|
354
|
-
for(var _iterator = value.$all[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
355
|
-
var term = _step.value;
|
|
356
|
-
var clause1 = buildClause(null, String(term !== null && term !== void 0 ? term : ''));
|
|
357
|
-
if (clause1) state.terms.push(clause1);
|
|
358
|
-
}
|
|
359
|
-
} catch (err) {
|
|
360
|
-
_didIteratorError = true;
|
|
361
|
-
_iteratorError = err;
|
|
362
|
-
} finally{
|
|
363
|
-
try {
|
|
364
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
365
|
-
_iterator.return();
|
|
366
|
-
}
|
|
367
|
-
} finally{
|
|
368
|
-
if (_didIteratorError) {
|
|
369
|
-
throw _iteratorError;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
if (Array.isArray(value.$none) && value.$none.length > 0) {
|
|
375
|
-
var clauses = value.$none.map(function(term) {
|
|
376
|
-
return buildClause(null, String(term !== null && term !== void 0 ? term : ''));
|
|
377
|
-
}).filter(Boolean);
|
|
378
|
-
if (clauses.length === 1) {
|
|
379
|
-
state.terms.push("NOT ".concat(clauses[0]));
|
|
380
|
-
} else if (clauses.length > 1) {
|
|
381
|
-
state.terms.push("NOT (".concat(clauses.join(' OR '), ")"));
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
function pushAnyTerms(values) {
|
|
386
|
-
var clauses = values.map(function(val) {
|
|
387
|
-
return buildClause(null, val);
|
|
388
|
-
}).filter(Boolean);
|
|
389
|
-
if (!clauses.length) return;
|
|
390
|
-
state.terms.push(clauses.length === 1 ? clauses[0] : "(".concat(clauses.join(' OR '), ")"));
|
|
391
|
-
}
|
|
392
|
-
function escapeKQL(value) {
|
|
393
|
-
return value.replace(/\\/g, '\\\\').replace(/:/g, '\\:').replace(/\(/g, '\\(').replace(/\)/g, '\\)').replace(/\{/g, '\\{').replace(/\}/g, '\\}').replace(/\[/g, '\\[').replace(/\]/g, '\\]').replace(/"/g, '\\"').replace(/\*/g, '\\*').replace(/\?/g, '\\?').replace(/</g, '\\<').replace(/>/g, '\\>').replace(/_/g, '\\_');
|
|
394
|
-
}
|
|
395
|
-
function buildClause(_prefix, value) {
|
|
396
|
-
var trimmed = value.trim();
|
|
397
|
-
if (!trimmed) return '';
|
|
398
|
-
var escaped = escapeKQL(trimmed);
|
|
399
|
-
var shouldQuote = /[^a-zA-Z\s]/.test(trimmed) || /\s/.test(trimmed);
|
|
400
|
-
return shouldQuote ? '"'.concat(escaped, '"') : escaped;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
function hasFullTextIntent(node) {
|
|
404
|
-
if (!node || (typeof node === "undefined" ? "undefined" : _type_of(node)) !== 'object') return false;
|
|
405
|
-
if (node.kqlQuery) return true;
|
|
406
|
-
if (node.exactPhrase) return true;
|
|
407
|
-
if ('subject' in node && node.subject) return true;
|
|
408
|
-
if ('text' in node && node.text) return true;
|
|
409
|
-
if ('body' in node && node.body) return true;
|
|
410
|
-
if ('$and' in node && node.$and) {
|
|
411
|
-
return node.$and.some(function(child) {
|
|
412
|
-
return hasFullTextIntent(child);
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
if ('$or' in node && node.$or) {
|
|
416
|
-
return node.$or.some(function(child) {
|
|
417
|
-
return hasFullTextIntent(child);
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
if ('$not' in node && node.$not) {
|
|
421
|
-
return hasFullTextIntent(node.$not);
|
|
422
|
-
}
|
|
423
|
-
return false;
|
|
395
|
+
return emit(query);
|
|
424
396
|
}
|
|
425
397
|
function toOutlookFilter(parsed, _options) {
|
|
426
398
|
var graphResult = toGraphFilter(parsed);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nexport const OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nexport function mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n hasFullText: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n if (query.kqlQuery) {\n return {\n search: query.kqlQuery,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: true,\n };\n }\n\n if (hasFullTextIntent(query)) {\n const searchCollect = collectSearchTerms(query);\n const search = searchCollect.terms.length ? searchCollect.terms.join(' AND ') : null;\n return {\n search,\n filter: null,\n requireBodyClientFilter: searchCollect.usesBody || searchCollect.usesText,\n hasFullText: true,\n };\n }\n\n function L(s: string) {\n // Microsoft Graph does NOT support toLower() function in OData filters\n // Case-insensitive matching must be done client-side or via $search\n return s;\n }\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n // Graph may reject functions on nested properties; use equality on nested address/name fields.\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n // For text and body fields, skip OData filtering entirely (uses KQL search instead)\n // Do this BEFORE validation so we don't throw on valid text/body queries\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n return '';\n }\n\n // For all other fields, validate non-empty AFTER checking for null\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n // For email addresses emit equality checks on nested address/name;\n // for name-only tokens, skip server-side filter (handled client-side or via $search).\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n // Don't emit a server-side filter for name-only 'from' tokens.\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n // Microsoft Graph does NOT support contains() function in OData filters\n // Use startswith as a partial alternative or rely on $search\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n // mapOutlookCategory will throw on invalid input (fail fast)\n const systemCategory = mapOutlookCategory(rawStr);\n // Use the categories OData property with exact case-sensitive match\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label': {\n // Direct passthrough to categories for Outlook (case-sensitive)\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n }\n default:\n // Microsoft Graph does NOT support contains() function\n // For unknown fields, skip server-side filtering\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n // Filter out empty strings (from fields like text/body that don't generate OData filters)\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n const filterStr = emit(query);\n const cleanedFilter = filterStr && typeof filterStr === 'string' && filterStr.trim().length ? filterStr.trim() : null;\n return {\n search: null,\n filter: cleanedFilter,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n}\n\nfunction collectSearchTerms(query: QueryNode): { terms: string[]; usesText: boolean; usesBody: boolean; usesExact: boolean } {\n const state = {\n terms: [] as string[],\n usesText: false,\n usesBody: false,\n usesExact: false,\n };\n\n walkNode(query);\n return state;\n\n function walkNode(node: QueryNode | undefined) {\n if (!node || typeof node !== 'object') return;\n\n if (node.$and) {\n node.$and.forEach((child) => walkNode(child));\n return;\n }\n if (node.$or) {\n node.$or.forEach((child) => walkNode(child));\n return;\n }\n if (node.$not) {\n walkNode(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n state.usesExact = true;\n pushExactPhrase(node.exactPhrase);\n }\n\n pushOperatorTerms(node.subject);\n\n if ('text' in node && node.text) {\n state.usesText = true;\n pushOperatorTerms(node.text);\n }\n if ('body' in node && node.body) {\n state.usesBody = true;\n pushOperatorTerms(node.body);\n }\n\n // Other fields (hasAttachment, importance, date) are handled via OData filters (emit())\n // and should not create search terms with colon prefixes that break Graph $search.\n }\n\n function pushExactPhrase(value: string) {\n const phrase = String(value);\n if (!phrase.trim()) return;\n pushAnyTerms([`\"${phrase}\"`]);\n }\n\n function pushOperatorTerms(value: FieldOperator | string | undefined) {\n if (!value) return;\n if (typeof value === 'string') {\n const clause = buildClause(null, value);\n if (clause) state.terms.push(clause);\n return;\n }\n\n if (Array.isArray(value.$any) && value.$any.length > 0) {\n pushAnyTerms(value.$any);\n }\n if (Array.isArray(value.$all) && value.$all.length > 0) {\n for (const term of value.$all) {\n const clause = buildClause(null, String(term ?? ''));\n if (clause) state.terms.push(clause);\n }\n }\n if (Array.isArray(value.$none) && value.$none.length > 0) {\n const clauses = value.$none.map((term) => buildClause(null, String(term ?? ''))).filter(Boolean);\n if (clauses.length === 1) {\n state.terms.push(`NOT ${clauses[0]}`);\n } else if (clauses.length > 1) {\n state.terms.push(`NOT (${clauses.join(' OR ')})`);\n }\n }\n }\n\n function pushAnyTerms(values: string[]) {\n const clauses = values.map((val) => buildClause(null, val)).filter(Boolean);\n if (!clauses.length) return;\n state.terms.push(clauses.length === 1 ? clauses[0] : `(${clauses.join(' OR ')})`);\n }\n\n function escapeKQL(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/_/g, '\\\\_');\n }\n\n function buildClause(_prefix: string | null, value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return '';\n const escaped = escapeKQL(trimmed);\n const shouldQuote = /[^a-zA-Z\\s]/.test(trimmed) || /\\s/.test(trimmed);\n return shouldQuote ? `\"${escaped}\"` : escaped;\n }\n}\n\nfunction hasFullTextIntent(node: QueryNode | undefined | null): boolean {\n if (!node || typeof node !== 'object') return false;\n\n if (node.kqlQuery) return true;\n if (node.exactPhrase) return true;\n if ('subject' in node && node.subject) return true;\n if ('text' in node && node.text) return true;\n if ('body' in node && node.body) return true;\n\n if ('$and' in node && node.$and) {\n return node.$and.some((child) => hasFullTextIntent(child));\n }\n if ('$or' in node && node.$or) {\n return node.$or.some((child) => hasFullTextIntent(child));\n }\n if ('$not' in node && node.$not) {\n return hasFullTextIntent(node.$not);\n }\n\n return false;\n}\n\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["OUTLOOK_CATEGORIES","extractOutlookFilters","mapOutlookCategory","toGraphFilter","toOutlookFilter","personal","work","family","travel","important","urgent","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","query","kqlQuery","search","filter","requireBodyClientFilter","hasFullText","hasFullTextIntent","searchCollect","collectSearchTerms","terms","length","usesBody","usesText","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","String","replace","includes","addrEq","nameEq","chain","op","arr","first","joined","fieldExpr","Array","isArray","$any","results","map","v","validResults","$all","$none","JSON","stringify","dateExpr","d","parts","$gte","push","$lt","emit","n","$and","andParts","part","Boolean","firstPart","$or","orParts","$not","notExpr","hasAttachment","date","k0","fieldValue","filterStr","cleanedFilter","state","usesExact","walkNode","node","forEach","child","exactPhrase","pushExactPhrase","pushOperatorTerms","subject","text","body","value","phrase","pushAnyTerms","clause","buildClause","term","clauses","values","val","escapeKQL","_prefix","escaped","shouldQuote","test","some","parsed","_options","graphResult","filters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","walk","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":";;;;;;;;;;;QA6BaA;eAAAA;;QA2YGC;eAAAA;;QA9XAC;eAAAA;;QA6BAC;eAAAA;;QAuUAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAjXT,IAAMJ,qBAAqB;IAChCK,UAAU;IACVC,MAAM;IACNC,QAAQ;IACRC,QAAQ;IACRC,WAAW;IACXC,QAAQ;AACV;AAMO,SAASR,mBAAmBS,QAAgB;IACjD,gDAAgD;IAChD,IAAI,CAACA,YAAY,OAAOA,aAAa,UAAU;QAC7C,MAAM,IAAIC,MAAM,AAAC,oDAAmE,OAAhB,OAAOD,yCAAP,SAAOA;IAC7E;IAEA,IAAME,UAAUF,SAASG,IAAI;IAC7B,IAAID,YAAY,IAAI;QAClB,MAAM,IAAID,MAAM;IAClB;IAEA,kCAAkC;IAClC,IAAMG,qBAAqBF,QAAQG,WAAW;IAC9C,IAAMC,iBAAiBjB,kBAAkB,CAACe,mBAAsD;IAEhG,IAAI,CAACE,gBAAgB;QACnB,MAAM,IAAIL,MAAM,AAAC,8BAA6DM,OAAhCP,UAAS,yBAAkE,OAA3CO,OAAOC,IAAI,CAACnB,oBAAoBoB,IAAI,CAAC;IACrH;IAEA,OAAOH;AACT;AASO,SAASd,cAAckB,KAAgB;IAC5C,IAAIA,MAAMC,QAAQ,EAAE;QAClB,OAAO;YACLC,QAAQF,MAAMC,QAAQ;YACtBE,QAAQ;YACRC,yBAAyB;YACzBC,aAAa;QACf;IACF;IAEA,IAAIC,kBAAkBN,QAAQ;QAC5B,IAAMO,gBAAgBC,mBAAmBR;QACzC,IAAME,SAASK,cAAcE,KAAK,CAACC,MAAM,GAAGH,cAAcE,KAAK,CAACV,IAAI,CAAC,WAAW;QAChF,OAAO;YACLG,QAAAA;YACAC,QAAQ;YACRC,yBAAyBG,cAAcI,QAAQ,IAAIJ,cAAcK,QAAQ;YACzEP,aAAa;QACf;IACF;IAEA,SAASQ,EAAEC,CAAS;QAClB,uEAAuE;QACvE,oEAAoE;QACpE,OAAOA;IACT;IACA,SAASC,EAAED,CAAS;QAClB,OAAO,AAAC,IAAK,OAAFA,GAAE;IACf;IAEA,SAASE,MAAMC,IAAY,EAAEC,CAAS;QACpC,+FAA+F;QAC/F,IAAMC,OAAO,AAAC,6BAA8B,OAAFD;QAC1C,IAAME,QAAQ,AAAC,0BAA2B,OAAFF;QACxC,OAAO,AAAC,GAAiBC,OAAfF,MAAK,YAAqBG,OAAXD,MAAK,QAAY,OAANC,OAAM;IAC5C;IAEA,SAASC,GAAGC,KAAa,EAAEC,GAAiD;QAC1E,IAAIA,OAAO,MAAM,OAAO;QACxB,IAAMC,SAASC,OAAOF;QAEtB,oFAAoF;QACpF,yEAAyE;QACzE,IAAID,UAAU,UAAUA,UAAU,QAAQ;YACxC,IAAIE,OAAO/B,IAAI,OAAO,IAAI;gBACxB,MAAM,IAAIF,MAAM,AAAC,WAAgB,OAAN+B,OAAM;YACnC;YACA,OAAO;QACT;QAEA,mEAAmE;QACnE,IAAIE,OAAO/B,IAAI,OAAO,IAAI;YACxB,MAAM,IAAIF,MAAM,AAAC,WAAgB,OAAN+B,OAAM;QACnC;QAEA,IAAMJ,IAAI,AAAC,IAA4C,OAAzCM,OAAO7B,WAAW,GAAG+B,OAAO,CAAC,MAAM,OAAM;QACvD,OAAQJ;YACN,KAAK;gBAAQ;oBACX,mEAAmE;oBACnE,sFAAsF;oBACtF,IAAIE,OAAOG,QAAQ,CAAC,MAAM;wBACxB,IAAMC,SAAS,AAAC,GAAuCV,OAArCL,EAAE,8BAA6B,QAAQ,OAAFK;wBACvD,IAAMW,SAAS,AAAC,GAAoCX,OAAlCL,EAAE,2BAA0B,QAAQ,OAAFK;wBACpD,OAAOH,EAAE,AAAC,GAAec,OAAbD,QAAO,QAAa,OAAPC;oBAC3B;oBACA,+DAA+D;oBAC/D,OAAO;gBACT;YACA,KAAK;gBACH,OAAOb,MAAM,gBAAgBE;YAC/B,KAAK;gBACH,OAAOF,MAAM,gBAAgBE;YAC/B,KAAK;gBACH,OAAOF,MAAM,iBAAiBE;YAChC,KAAK;gBACH,wEAAwE;gBACxE,6DAA6D;gBAC7D,IAAIM,OAAOG,QAAQ,CAAC,QAAQH,OAAOd,MAAM,GAAG,GAAG,OAAO;gBACtD,OAAO,AAAC,uBAAwB,OAAFQ,GAAE;YAClC,KAAK;gBAAc;oBACjB,6DAA6D;oBAC7D,IAAMtB,iBAAiBf,mBAAmB2C;oBAC1C,oEAAoE;oBACpE,OAAO,AAAC,2BAAyC,OAAf5B,gBAAe;gBACnD;YACA,KAAK;gBAAS;oBACZ,gEAAgE;oBAChE,OAAO,AAAC,2BAAqD,OAA3B4B,OAAOE,OAAO,CAAC,MAAM,OAAM;gBAC/D;YACA;gBACE,uDAAuD;gBACvD,iDAAiD;gBACjD,OAAO;QACX;IACF;IAEA,SAASI,MAAMC,EAAgB,EAAEC,GAA8B;QAC7D,IAAI,CAACA,OAAOA,IAAItB,MAAM,KAAK,GAAG;YAC5B,MAAM,IAAInB,MAAM,AAAC,0BAA4B,OAAHwC,IAAG;QAC/C;QACA,IAAIC,IAAItB,MAAM,KAAK,GAAG;gBACNsB;YAAd,IAAMC,SAAQD,QAAAA,GAAG,CAAC,EAAE,cAANA,mBAAAA,QAAU;YACxB,OAAOP,OAAOQ;QAChB;QACA,IAAMC,SAASF,IAAIjC,IAAI,CAAC,AAAC,IAAM,OAAHgC,IAAG;QAC/B,OAAOhB,EAAEmB;IACX;IACA,SAASC,UAAUb,KAAa,EAAES,EAA0B;QAC1D,IAAI,OAAOA,OAAO,UAAU;YAC1B,OAAOV,GAAGC,OAAOS;QACnB;QAEA,IAAIK,MAAMC,OAAO,CAACN,GAAGO,IAAI,GAAG;YAC1B,IAAMC,UAAUR,GAAGO,IAAI,CAACE,GAAG,CAAC,SAACC;uBAAMpB,GAAGC,OAAOG,OAAOgB,cAAAA,eAAAA,IAAK;;YACzD,0FAA0F;YAC1F,IAAMC,eAAeH,QAAQpC,MAAM,CAAC,SAACW;uBAAMA,KAAKA,EAAErB,IAAI;;YACtD,IAAIiD,aAAahC,MAAM,KAAK,GAAG,OAAO;YACtC,OAAOoB,MAAM,MAAMY;QACrB;QACA,IAAIN,MAAMC,OAAO,CAACN,GAAGY,IAAI,GAAG;YAC1B,IAAMJ,WAAUR,GAAGY,IAAI,CAACH,GAAG,CAAC,SAACC;uBAAMpB,GAAGC,OAAOG,OAAOgB,cAAAA,eAAAA,IAAK;;YACzD,0FAA0F;YAC1F,IAAMC,gBAAeH,SAAQpC,MAAM,CAAC,SAACW;uBAAMA,KAAKA,EAAErB,IAAI;;YACtD,IAAIiD,cAAahC,MAAM,KAAK,GAAG,OAAO;YACtC,OAAOoB,MAAM,OAAOY;QACtB;QACA,IAAIN,MAAMC,OAAO,CAACN,GAAGa,KAAK,GAAG;YAC3B,IAAML,WAAUR,GAAGa,KAAK,CAACJ,GAAG,CAAC,SAACC;uBAAMpB,GAAGC,OAAOG,OAAOgB,cAAAA,eAAAA,IAAK;;YAC1D,0FAA0F;YAC1F,IAAMC,gBAAeH,SAAQpC,MAAM,CAAC,SAACW;uBAAMA,KAAKA,EAAErB,IAAI;;YACtD,IAAIiD,cAAahC,MAAM,KAAK,GAAG,OAAO;YACtC,OAAO,AAAC,OAAmC,OAA7BK,EAAEe,MAAM,MAAMY;QAC9B;QACA,MAAM,IAAInD,MAAM,AAAC,0BAA4C,OAAnBsD,KAAKC,SAAS,CAACf;IAC3D;IAEA,SAASgB,SAASC,CAAe;YAIqBC;QAHpD,IAAMA,QAAkB,EAAE;QAC1B,IAAID,EAAEE,IAAI,EAAED,MAAME,IAAI,CAAC,AAAC,uBAA6B,OAAPH,EAAEE,IAAI,EAAC;QACrD,IAAIF,EAAEI,GAAG,EAAEH,MAAME,IAAI,CAAC,AAAC,uBAA4B,OAANH,EAAEI,GAAG,EAAC;QACnD,OAAOH,MAAMvC,MAAM,GAAG,IAAIK,EAAEkC,MAAMlD,IAAI,CAAC,aAAakD,UAAAA,KAAK,CAAC,EAAE,cAARA,qBAAAA,UAAY;IAClE;IAEA,SAASI,KAAKC,CAAY;QACxB,IAAI,CAACA,KAAK,CAAA,OAAOA,kCAAP,SAAOA,EAAAA,MAAM,UAAU,OAAO;QAExC,IAAI,UAAUA,KAAKA,EAAEC,IAAI,EAAE;YACzB,IAAMC,WAAWF,EAAEC,IAAI,CAACf,GAAG,CAACa,MAAMlD,MAAM,CAAC,SAACsD;uBAAiCC,QAAQD;;YACnF,IAAID,SAAS9C,MAAM,KAAK,GAAG,OAAO;YAClC,IAAI8C,SAAS9C,MAAM,KAAK,GAAG;gBACzB,IAAMiD,YAAYH,QAAQ,CAAC,EAAE;gBAC7B,OAAOG,sBAAAA,uBAAAA,YAAa;YACtB;YACA,OAAO5C,EAAEyC,SAASzD,IAAI,CAAC;QACzB;QACA,IAAI,SAASuD,KAAKA,EAAEM,GAAG,EAAE;YACvB,IAAMC,UAAUP,EAAEM,GAAG,CAACpB,GAAG,CAACa,MAAMlD,MAAM,CAAC,SAACsD;uBAAiCC,QAAQD;;YACjF,IAAII,QAAQnD,MAAM,KAAK,GAAG,OAAO;YACjC,IAAImD,QAAQnD,MAAM,KAAK,GAAG;gBACxB,IAAMiD,aAAYE,OAAO,CAAC,EAAE;gBAC5B,OAAOF,uBAAAA,wBAAAA,aAAa;YACtB;YACA,OAAO5C,EAAE8C,QAAQ9D,IAAI,CAAC;QACxB;QACA,IAAI,UAAUuD,KAAKA,EAAEQ,IAAI,EAAE;YACzB,IAAMC,UAAUV,KAAKC,EAAEQ,IAAI;YAC3B,OAAOC,UAAU,AAAC,QAAe,OAARA,SAAQ,OAAK;QACxC;QACA,IAAI,mBAAmBT,KAAKA,EAAEU,aAAa,EAAE,OAAO;QACpD,IAAI,UAAUV,KAAKA,EAAEW,IAAI,EAAE,OAAOlB,SAASO,EAAEW,IAAI;QAEjD,IAAMnE,OAAOD,OAAOC,IAAI,CAACwD;QACzB,IAAIxD,KAAKY,MAAM,KAAK,GAAG;gBACHZ;YAAlB,IAAMoE,KAAKzC,QAAO3B,SAAAA,IAAI,CAAC,EAAE,cAAPA,oBAAAA,SAAW;YAC7B,IAAIoE,MAAM;gBAAC;gBAAQ;gBAAM;gBAAM;gBAAO;gBAAW;gBAAQ;gBAAQ;gBAAc;aAAQ,CAACvC,QAAQ,CAACuC,KAAK;gBACpG,IAAMC,aAAa,AAACb,CAAgB,CAACY,GAAuB;gBAC5D,IAAIC,YAAY,OAAOhC,UAAU+B,IAAIC;YACvC;QACF;QACA,OAAO;IACT;IAEA,IAAMC,YAAYf,KAAKrD;IACvB,IAAMqE,gBAAgBD,aAAa,OAAOA,cAAc,YAAYA,UAAU3E,IAAI,GAAGiB,MAAM,GAAG0D,UAAU3E,IAAI,KAAK;IACjH,OAAO;QACLS,QAAQ;QACRC,QAAQkE;QACRjE,yBAAyB;QACzBC,aAAa;IACf;AACF;AAEA,SAASG,mBAAmBR,KAAgB;IAC1C,IAAMsE,QAAQ;QACZ7D,OAAO,EAAE;QACTG,UAAU;QACVD,UAAU;QACV4D,WAAW;IACb;IAEAC,SAASxE;IACT,OAAOsE;IAEP,SAASE,SAASC,IAA2B;QAC3C,IAAI,CAACA,QAAQ,CAAA,OAAOA,qCAAP,SAAOA,KAAG,MAAM,UAAU;QAEvC,IAAIA,KAAKlB,IAAI,EAAE;YACbkB,KAAKlB,IAAI,CAACmB,OAAO,CAAC,SAACC;uBAAUH,SAASG;;YACtC;QACF;QACA,IAAIF,KAAKb,GAAG,EAAE;YACZa,KAAKb,GAAG,CAACc,OAAO,CAAC,SAACC;uBAAUH,SAASG;;YACrC;QACF;QACA,IAAIF,KAAKX,IAAI,EAAE;YACbU,SAASC,KAAKX,IAAI;YAClB;QACF;QAEA,IAAI,iBAAiBW,QAAQA,KAAKG,WAAW,EAAE;YAC7CN,MAAMC,SAAS,GAAG;YAClBM,gBAAgBJ,KAAKG,WAAW;QAClC;QAEAE,kBAAkBL,KAAKM,OAAO;QAE9B,IAAI,UAAUN,QAAQA,KAAKO,IAAI,EAAE;YAC/BV,MAAM1D,QAAQ,GAAG;YACjBkE,kBAAkBL,KAAKO,IAAI;QAC7B;QACA,IAAI,UAAUP,QAAQA,KAAKQ,IAAI,EAAE;YAC/BX,MAAM3D,QAAQ,GAAG;YACjBmE,kBAAkBL,KAAKQ,IAAI;QAC7B;IAEA,wFAAwF;IACxF,mFAAmF;IACrF;IAEA,SAASJ,gBAAgBK,KAAa;QACpC,IAAMC,SAAS1D,OAAOyD;QACtB,IAAI,CAACC,OAAO1F,IAAI,IAAI;QACpB2F,aAAa;YAAE,IAAU,OAAPD,QAAO;SAAG;IAC9B;IAEA,SAASL,kBAAkBI,KAAyC;QAClE,IAAI,CAACA,OAAO;QACZ,IAAI,OAAOA,UAAU,UAAU;YAC7B,IAAMG,SAASC,YAAY,MAAMJ;YACjC,IAAIG,QAAQf,MAAM7D,KAAK,CAAC0C,IAAI,CAACkC;YAC7B;QACF;QAEA,IAAIjD,MAAMC,OAAO,CAAC6C,MAAM5C,IAAI,KAAK4C,MAAM5C,IAAI,CAAC5B,MAAM,GAAG,GAAG;YACtD0E,aAAaF,MAAM5C,IAAI;QACzB;QACA,IAAIF,MAAMC,OAAO,CAAC6C,MAAMvC,IAAI,KAAKuC,MAAMvC,IAAI,CAACjC,MAAM,GAAG,GAAG;gBACjD,kCAAA,2BAAA;;gBAAL,QAAK,YAAcwE,MAAMvC,IAAI,qBAAxB,SAAA,6BAAA,QAAA,yBAAA,iCAA0B;oBAA1B,IAAM4C,OAAN;oBACH,IAAMF,UAASC,YAAY,MAAM7D,OAAO8D,iBAAAA,kBAAAA,OAAQ;oBAChD,IAAIF,SAAQf,MAAM7D,KAAK,CAAC0C,IAAI,CAACkC;gBAC/B;;gBAHK;gBAAA;;;yBAAA,6BAAA;wBAAA;;;wBAAA;8BAAA;;;;QAIP;QACA,IAAIjD,MAAMC,OAAO,CAAC6C,MAAMtC,KAAK,KAAKsC,MAAMtC,KAAK,CAAClC,MAAM,GAAG,GAAG;YACxD,IAAM8E,UAAUN,MAAMtC,KAAK,CAACJ,GAAG,CAAC,SAAC+C;uBAASD,YAAY,MAAM7D,OAAO8D,iBAAAA,kBAAAA,OAAQ;eAAMpF,MAAM,CAACuD;YACxF,IAAI8B,QAAQ9E,MAAM,KAAK,GAAG;gBACxB4D,MAAM7D,KAAK,CAAC0C,IAAI,CAAC,AAAC,OAAiB,OAAXqC,OAAO,CAAC,EAAE;YACpC,OAAO,IAAIA,QAAQ9E,MAAM,GAAG,GAAG;gBAC7B4D,MAAM7D,KAAK,CAAC0C,IAAI,CAAC,AAAC,QAA4B,OAArBqC,QAAQzF,IAAI,CAAC,SAAQ;YAChD;QACF;IACF;IAEA,SAASqF,aAAaK,MAAgB;QACpC,IAAMD,UAAUC,OAAOjD,GAAG,CAAC,SAACkD;mBAAQJ,YAAY,MAAMI;WAAMvF,MAAM,CAACuD;QACnE,IAAI,CAAC8B,QAAQ9E,MAAM,EAAE;QACrB4D,MAAM7D,KAAK,CAAC0C,IAAI,CAACqC,QAAQ9E,MAAM,KAAK,IAAI8E,OAAO,CAAC,EAAE,GAAG,AAAC,IAAwB,OAArBA,QAAQzF,IAAI,CAAC,SAAQ;IAChF;IAEA,SAAS4F,UAAUT,KAAa;QAC9B,OAAOA,MACJxD,OAAO,CAAC,OAAO,QACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,OAAO,OACfA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,MAAM,OACdA,OAAO,CAAC,MAAM;IACnB;IAEA,SAAS4D,YAAYM,OAAsB,EAAEV,KAAa;QACxD,IAAM1F,UAAU0F,MAAMzF,IAAI;QAC1B,IAAI,CAACD,SAAS,OAAO;QACrB,IAAMqG,UAAUF,UAAUnG;QAC1B,IAAMsG,cAAc,cAAcC,IAAI,CAACvG,YAAY,KAAKuG,IAAI,CAACvG;QAC7D,OAAOsG,cAAc,AAAC,IAAW,OAARD,SAAQ,OAAKA;IACxC;AACF;AAEA,SAASvF,kBAAkBmE,IAAkC;IAC3D,IAAI,CAACA,QAAQ,CAAA,OAAOA,qCAAP,SAAOA,KAAG,MAAM,UAAU,OAAO;IAE9C,IAAIA,KAAKxE,QAAQ,EAAE,OAAO;IAC1B,IAAIwE,KAAKG,WAAW,EAAE,OAAO;IAC7B,IAAI,aAAaH,QAAQA,KAAKM,OAAO,EAAE,OAAO;IAC9C,IAAI,UAAUN,QAAQA,KAAKO,IAAI,EAAE,OAAO;IACxC,IAAI,UAAUP,QAAQA,KAAKQ,IAAI,EAAE,OAAO;IAExC,IAAI,UAAUR,QAAQA,KAAKlB,IAAI,EAAE;QAC/B,OAAOkB,KAAKlB,IAAI,CAACyC,IAAI,CAAC,SAACrB;mBAAUrE,kBAAkBqE;;IACrD;IACA,IAAI,SAASF,QAAQA,KAAKb,GAAG,EAAE;QAC7B,OAAOa,KAAKb,GAAG,CAACoC,IAAI,CAAC,SAACrB;mBAAUrE,kBAAkBqE;;IACpD;IACA,IAAI,UAAUF,QAAQA,KAAKX,IAAI,EAAE;QAC/B,OAAOxD,kBAAkBmE,KAAKX,IAAI;IACpC;IAEA,OAAO;AACT;AAEO,SAAS/E,gBAAgBkH,MAAiB,EAAEC,QAA6E;IAC9H,IAAMC,cAAcrH,cAAcmH;IAClC,IAAMG,UAAUxH,sBAAsBqH;IACtC,OAAO;QACL9F,QAAQgG,YAAYhG,MAAM;QAC1BD,QAAQiG,YAAYjG,MAAM;QAC1BE,yBAAyB+F,YAAY/F,uBAAuB;QAC5DgG,SAAAA;IACF;AACF;AAiBO,SAASxH,sBAAsBqH,MAAiB;IACrD,IAAMG,UAA4B;QAChCC,iBAAiB,EAAE;QACnBC,cAAc,EAAE;QAChBC,cAAc,EAAE;QAChBC,cAAc,EAAE;QAChBC,YAAY,EAAE;QACdC,YAAY,EAAE;QACdC,aAAa,EAAE;QACfC,oBAAoB,EAAE;QACtBC,eAAe,EAAE;IACnB;IACA,SAASC,KAAKrC,IAAe;QAC3B,IAAI,CAACA,QAAQ,CAAA,OAAOA,qCAAP,SAAOA,KAAG,MAAM,UAAU;QAEvC,IAAI,UAAUA,QAAQA,KAAKlB,IAAI,EAAE;YAC/BkB,KAAKlB,IAAI,CAACmB,OAAO,CAACoC;YAClB;QACF;QACA,IAAI,SAASrC,QAAQA,KAAKb,GAAG,EAAE;YAC7Ba,KAAKb,GAAG,CAACc,OAAO,CAACoC;YACjB;QACF;QACA,IAAI,UAAUrC,QAAQA,KAAKX,IAAI,EAAE;YAC/BgD,KAAKrC,KAAKX,IAAI;YACd;QACF;QAEA,IAAI,mBAAmBW,QAAQA,KAAKT,aAAa,KAAK+C,WAAW;YAC/DX,QAAQpC,aAAa,GAAGS,KAAKT,aAAa,KAAK;YAC/C;QACF;QACA,IAAI,UAAUS,QAAQA,KAAKR,IAAI,EAAE;YAC/B,IAAIQ,KAAKR,IAAI,CAACf,IAAI,EAAEkD,QAAQY,KAAK,GAAGvC,KAAKR,IAAI,CAACf,IAAI;YAClD,IAAIuB,KAAKR,IAAI,CAACb,GAAG,EAAEgD,QAAQa,MAAM,GAAGxC,KAAKR,IAAI,CAACb,GAAG;YACjD;QACF;QAEA,IAAI,aAAaqB,QAAQA,KAAKM,OAAO,EAAE;YACrC,IAAI,OAAON,KAAKM,OAAO,KAAK,UAAU;gBACpCqB,QAAQC,eAAe,CAAClD,IAAI,CAACsB,KAAKM,OAAO;YAC3C,OAAO;oBACkBqB,0BACAA;gBADvB,IAAI3B,KAAKM,OAAO,CAACzC,IAAI,EAAE8D,CAAAA,2BAAAA,QAAQC,eAAe,EAAClD,IAAI,OAA5BiD,0BAA6B,qBAAG3B,KAAKM,OAAO,CAACzC,IAAI;gBACxE,IAAImC,KAAKM,OAAO,CAACpC,IAAI,EAAEyD,CAAAA,4BAAAA,QAAQC,eAAe,EAAClD,IAAI,OAA5BiD,2BAA6B,qBAAG3B,KAAKM,OAAO,CAACpC,IAAI;YAC1E;QACF;QACA,IAAI,UAAU8B,QAAQA,KAAKQ,IAAI,EAAE;YAC/B,IAAI,OAAOR,KAAKQ,IAAI,KAAK,UAAU;gBACjCmB,QAAQE,YAAY,CAACnD,IAAI,CAACsB,KAAKQ,IAAI;YACrC,OAAO;oBACemB,uBACAA;gBADpB,IAAI3B,KAAKQ,IAAI,CAAC3C,IAAI,EAAE8D,CAAAA,wBAAAA,QAAQE,YAAY,EAACnD,IAAI,OAAzBiD,uBAA0B,qBAAG3B,KAAKQ,IAAI,CAAC3C,IAAI;gBAC/D,IAAImC,KAAKQ,IAAI,CAACtC,IAAI,EAAEyD,CAAAA,yBAAAA,QAAQE,YAAY,EAACnD,IAAI,OAAzBiD,wBAA0B,qBAAG3B,KAAKQ,IAAI,CAACtC,IAAI;YACjE;QACF;QACA,IAAI,UAAU8B,QAAQA,KAAKO,IAAI,EAAE;YAC/B,IAAI,OAAOP,KAAKO,IAAI,KAAK,UAAU;gBACjCoB,QAAQG,YAAY,CAACpD,IAAI,CAACsB,KAAKO,IAAI;gBACnCoB,QAAQE,YAAY,CAACnD,IAAI,CAACsB,KAAKO,IAAI;YACrC,OAAO;gBACL,IAAIP,KAAKO,IAAI,CAAC1C,IAAI,EAAE;wBAClB8D,uBACAA;oBADAA,CAAAA,wBAAAA,QAAQG,YAAY,EAACpD,IAAI,OAAzBiD,uBAA0B,qBAAG3B,KAAKO,IAAI,CAAC1C,IAAI;oBAC3C8D,CAAAA,yBAAAA,QAAQE,YAAY,EAACnD,IAAI,OAAzBiD,wBAA0B,qBAAG3B,KAAKO,IAAI,CAAC1C,IAAI;gBAC7C;gBACA,IAAImC,KAAKO,IAAI,CAACrC,IAAI,EAAE;wBAClByD,wBACAA;oBADAA,CAAAA,yBAAAA,QAAQG,YAAY,EAACpD,IAAI,OAAzBiD,wBAA0B,qBAAG3B,KAAKO,IAAI,CAACrC,IAAI;oBAC3CyD,CAAAA,yBAAAA,QAAQE,YAAY,EAACnD,IAAI,OAAzBiD,wBAA0B,qBAAG3B,KAAKO,IAAI,CAACrC,IAAI;gBAC7C;YACF;QACF;QACA,IAAI,UAAU8B,QAAQA,KAAKyC,IAAI,EAAE;YAC/B,IAAI,OAAOzC,KAAKyC,IAAI,KAAK,UAAU;gBACjCd,QAAQI,YAAY,CAACrD,IAAI,CAACsB,KAAKyC,IAAI;YACrC,OAAO;oBACed,uBACAA;gBADpB,IAAI3B,KAAKyC,IAAI,CAAC5E,IAAI,EAAE8D,CAAAA,wBAAAA,QAAQI,YAAY,EAACrD,IAAI,OAAzBiD,uBAA0B,qBAAG3B,KAAKyC,IAAI,CAAC5E,IAAI;gBAC/D,IAAImC,KAAKyC,IAAI,CAACvE,IAAI,EAAEyD,CAAAA,yBAAAA,QAAQI,YAAY,EAACrD,IAAI,OAAzBiD,wBAA0B,qBAAG3B,KAAKyC,IAAI,CAACvE,IAAI;YACjE;QACF;QACA,IAAI,QAAQ8B,QAAQA,KAAK0C,EAAE,EAAE;YAC3B,IAAI,OAAO1C,KAAK0C,EAAE,KAAK,UAAU;gBAC/Bf,QAAQK,UAAU,CAACtD,IAAI,CAACsB,KAAK0C,EAAE;YACjC,OAAO;oBACaf,qBACAA;gBADlB,IAAI3B,KAAK0C,EAAE,CAAC7E,IAAI,EAAE8D,CAAAA,sBAAAA,QAAQK,UAAU,EAACtD,IAAI,OAAvBiD,qBAAwB,qBAAG3B,KAAK0C,EAAE,CAAC7E,IAAI;gBACzD,IAAImC,KAAK0C,EAAE,CAACxE,IAAI,EAAEyD,CAAAA,uBAAAA,QAAQK,UAAU,EAACtD,IAAI,OAAvBiD,sBAAwB,qBAAG3B,KAAK0C,EAAE,CAACxE,IAAI;YAC3D;QACF;QACA,IAAI,QAAQ8B,QAAQA,KAAK2C,EAAE,EAAE;YAC3B,IAAI,OAAO3C,KAAK2C,EAAE,KAAK,UAAU;gBAC/BhB,QAAQM,UAAU,CAACvD,IAAI,CAACsB,KAAK2C,EAAE;YACjC,OAAO;oBACahB,qBACAA;gBADlB,IAAI3B,KAAK2C,EAAE,CAAC9E,IAAI,EAAE8D,CAAAA,sBAAAA,QAAQM,UAAU,EAACvD,IAAI,OAAvBiD,qBAAwB,qBAAG3B,KAAK2C,EAAE,CAAC9E,IAAI;gBACzD,IAAImC,KAAK2C,EAAE,CAACzE,IAAI,EAAEyD,CAAAA,uBAAAA,QAAQM,UAAU,EAACvD,IAAI,OAAvBiD,sBAAwB,qBAAG3B,KAAK2C,EAAE,CAACzE,IAAI;YAC3D;QACF;QACA,IAAI,SAAS8B,QAAQA,KAAK4C,GAAG,EAAE;YAC7B,IAAI,OAAO5C,KAAK4C,GAAG,KAAK,UAAU;gBAChCjB,QAAQO,WAAW,CAACxD,IAAI,CAACsB,KAAK4C,GAAG;YACnC,OAAO;oBACcjB,sBACAA;gBADnB,IAAI3B,KAAK4C,GAAG,CAAC/E,IAAI,EAAE8D,CAAAA,uBAAAA,QAAQO,WAAW,EAACxD,IAAI,OAAxBiD,sBAAyB,qBAAG3B,KAAK4C,GAAG,CAAC/E,IAAI;gBAC5D,IAAImC,KAAK4C,GAAG,CAAC1E,IAAI,EAAEyD,CAAAA,wBAAAA,QAAQO,WAAW,EAACxD,IAAI,OAAxBiD,uBAAyB,qBAAG3B,KAAK4C,GAAG,CAAC1E,IAAI;YAC9D;QACF;QACA,IAAI,gBAAgB8B,QAAQA,KAAK6C,UAAU,EAAE;YAC3C,IAAI,OAAO7C,KAAK6C,UAAU,KAAK,UAAU;gBACvC,IAAIzI,mBAAmB4F,KAAK6C,UAAU,MAAM,MAAM;oBAChDlB,QAAQQ,kBAAkB,CAACzD,IAAI,CAACsB,KAAK6C,UAAU;gBACjD;YACF,OAAO;gBACL,iFAAiF;gBACjF,IAAI7C,KAAK6C,UAAU,CAAChF,IAAI,EAAE;wBAEQ8D;oBADhC,IAAMmB,kBAAkB9C,KAAK6C,UAAU,CAAChF,IAAI,CAACnC,MAAM,CAAC,SAACqH;+BAAgB3I,mBAAmB2I,SAAS;;oBACjG,IAAID,gBAAgB7G,MAAM,GAAG,GAAG0F,CAAAA,8BAAAA,QAAQQ,kBAAkB,EAACzD,IAAI,OAA/BiD,6BAAgC,qBAAGmB;gBACrE;gBACA,IAAI9C,KAAK6C,UAAU,CAAC3E,IAAI,EAAE;wBAEQyD;oBADhC,IAAMmB,mBAAkB9C,KAAK6C,UAAU,CAAC3E,IAAI,CAACxC,MAAM,CAAC,SAACqH;+BAAgB3I,mBAAmB2I,SAAS;;oBACjG,IAAID,iBAAgB7G,MAAM,GAAG,GAAG0F,CAAAA,+BAAAA,QAAQQ,kBAAkB,EAACzD,IAAI,OAA/BiD,8BAAgC,qBAAGmB;gBACrE;gBACA,IAAI9C,KAAK6C,UAAU,CAAC1E,KAAK,EAAE;wBAEOwD;oBADhC,IAAMmB,mBAAkB9C,KAAK6C,UAAU,CAAC1E,KAAK,CAACzC,MAAM,CAAC,SAACqH;+BAAgB3I,mBAAmB2I,SAAS;;oBAClG,IAAID,iBAAgB7G,MAAM,GAAG,GAAG0F,CAAAA,+BAAAA,QAAQQ,kBAAkB,EAACzD,IAAI,OAA/BiD,8BAAgC,qBAAGmB;gBACrE;YACF;QACF;QACA,IAAI,WAAW9C,QAAQA,KAAKgD,KAAK,EAAE;YACjC,IAAI,OAAOhD,KAAKgD,KAAK,KAAK,UAAU;gBAClCrB,QAAQS,aAAa,CAAC1D,IAAI,CAACsB,KAAKgD,KAAK;YACvC,OAAO;oBACgBrB,wBACAA,yBACCA;gBAFtB,IAAI3B,KAAKgD,KAAK,CAACnF,IAAI,EAAE8D,CAAAA,yBAAAA,QAAQS,aAAa,EAAC1D,IAAI,OAA1BiD,wBAA2B,qBAAG3B,KAAKgD,KAAK,CAACnF,IAAI;gBAClE,IAAImC,KAAKgD,KAAK,CAAC9E,IAAI,EAAEyD,CAAAA,0BAAAA,QAAQS,aAAa,EAAC1D,IAAI,OAA1BiD,yBAA2B,qBAAG3B,KAAKgD,KAAK,CAAC9E,IAAI;gBAClE,IAAI8B,KAAKgD,KAAK,CAAC7E,KAAK,EAAEwD,CAAAA,0BAAAA,QAAQS,aAAa,EAAC1D,IAAI,OAA1BiD,yBAA2B,qBAAG3B,KAAKgD,KAAK,CAAC7E,KAAK;YACtE;QACF;IACF;IACAkE,KAAKb;IACL,OAAOG;AACT"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/mcp-z/mcp-outlook/src/email/querying/query-builder.ts"],"sourcesContent":["import type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\n\ntype FieldOperator = {\n $any?: string[];\n $all?: string[];\n $none?: string[];\n};\n\ntype DateOperator = {\n $gte?: string;\n $lt?: string;\n};\n\ntype FieldQuery = {\n from?: FieldOperator | string;\n to?: FieldOperator | string;\n cc?: FieldOperator | string;\n bcc?: FieldOperator | string;\n subject?: FieldOperator | string;\n text?: FieldOperator | string;\n body?: FieldOperator | string;\n categories?: FieldOperator | string;\n label?: FieldOperator | string;\n};\n\n/**\n * Outlook category mappings - case insensitive input to exact system categories\n * Note: These are user-defined categories in Outlook, not system categories like Gmail\n */\nexport const OUTLOOK_CATEGORIES = {\n personal: 'Personal',\n work: 'Work',\n family: 'Family',\n travel: 'Travel',\n important: 'Important',\n urgent: 'Urgent',\n} as const;\n\n/**\n * Validate and map category name to Outlook system category\n * Throws error for invalid categories (fail fast principle)\n */\nexport function mapOutlookCategory(category: string): string {\n // Input validation - fail fast on invalid input\n if (!category || typeof category !== 'string') {\n throw new Error(`Invalid category: expected non-empty string, got ${typeof category}`);\n }\n\n const trimmed = category.trim();\n if (trimmed === '') {\n throw new Error('Invalid category: empty string after trimming');\n }\n\n // Fail fast on unknown categories\n const normalizedCategory = trimmed.toLowerCase();\n const systemCategory = OUTLOOK_CATEGORIES[normalizedCategory as keyof typeof OUTLOOK_CATEGORIES];\n\n if (!systemCategory) {\n throw new Error(`Invalid Outlook category: \"${category}\". Valid categories: ${Object.keys(OUTLOOK_CATEGORIES).join(', ')}`);\n }\n\n return systemCategory;\n}\n\nexport interface ODataFilterResult {\n search: string | null;\n filter: string | null;\n requireBodyClientFilter: boolean;\n hasFullText: boolean;\n}\n\nexport function toGraphFilter(query: QueryNode): ODataFilterResult {\n if (query.kqlQuery) {\n return {\n search: query.kqlQuery,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: true,\n };\n }\n\n if (hasFullTextIntent(query)) {\n const searchCollect = collectSearchTerms(query);\n const search = searchCollect.terms.length ? searchCollect.terms.join(' OR ') : null;\n return {\n search,\n filter: null,\n requireBodyClientFilter: searchCollect.usesBody || searchCollect.usesText,\n hasFullText: true,\n };\n }\n\n const filterStr = buildQueryFilter(query);\n const cleanedFilter = filterStr && typeof filterStr === 'string' && filterStr.trim().length ? filterStr.trim() : null;\n return {\n search: null,\n filter: cleanedFilter,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n}\n\nfunction collectSearchTerms(query: QueryNode): { terms: string[]; usesText: boolean; usesBody: boolean; usesExact: boolean } {\n const state = {\n terms: [] as string[],\n usesText: false,\n usesBody: false,\n usesExact: false,\n };\n\n walkNode(query);\n return state;\n\n function walkNode(node: QueryNode | undefined) {\n if (!node || typeof node !== 'object') return;\n\n if (node.$and) {\n node.$and.forEach((child) => walkNode(child));\n return;\n }\n if (node.$or) {\n node.$or.forEach((child) => walkNode(child));\n return;\n }\n if (node.$not) {\n walkNode(node.$not);\n return;\n }\n\n if ('exactPhrase' in node && node.exactPhrase) {\n state.usesExact = true;\n pushExactPhrase(node.exactPhrase);\n }\n\n pushOperatorTerms(node.subject);\n\n if ('text' in node && node.text) {\n state.usesText = true;\n pushOperatorTerms(node.text);\n }\n if ('body' in node && node.body) {\n state.usesBody = true;\n pushOperatorTerms(node.body);\n }\n\n // Other fields (hasAttachment, importance, date) are handled via OData filters (emit())\n // and should not create search terms with colon prefixes that break Graph $search.\n }\n\n function pushExactPhrase(value: string) {\n const phrase = String(value);\n if (!phrase.trim()) return;\n pushAnyTerms([`\"${phrase}\"`]);\n }\n\n function pushOperatorTerms(value: FieldOperator | string | undefined) {\n if (!value) return;\n if (typeof value === 'string') {\n const clause = buildClause(null, value);\n if (clause) state.terms.push(clause);\n return;\n }\n\n if (Array.isArray(value.$any) && value.$any.length > 0) {\n pushAnyTerms(value.$any);\n }\n if (Array.isArray(value.$all) && value.$all.length > 0) {\n pushAllTerms(value.$all);\n }\n if (Array.isArray(value.$none) && value.$none.length > 0) {\n const clauses = value.$none.map((term) => buildClause(null, String(term ?? ''))).filter(Boolean);\n if (clauses.length === 1) {\n state.terms.push(`NOT ${clauses[0]}`);\n } else if (clauses.length > 1) {\n state.terms.push(`NOT (${clauses.join(' OR ')})`);\n }\n }\n }\n\n function pushAnyTerms(values: string[]) {\n const clauses = values.map((val) => buildClause(null, val)).filter(Boolean);\n if (!clauses.length) return;\n state.terms.push(clauses.length === 1 ? clauses[0] : `(${clauses.join(' OR ')})`);\n }\n\n function pushAllTerms(values: string[]) {\n const clauses = values.map((val) => buildClause(null, val)).filter(Boolean);\n if (!clauses.length) return;\n state.terms.push(clauses.length === 1 ? clauses[0] : `(${clauses.join(' AND ')})`);\n }\n\n function escapeKQL(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/:/g, '\\\\:')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\[/g, '\\\\[')\n .replace(/\\]/g, '\\\\]')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\*/g, '\\\\*')\n .replace(/\\?/g, '\\\\?')\n .replace(/</g, '\\\\<')\n .replace(/>/g, '\\\\>')\n .replace(/_/g, '\\\\_');\n }\n\n function buildClause(_prefix: string | null, value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return '';\n const escaped = escapeKQL(trimmed);\n const shouldQuote = /[^a-zA-Z\\s]/.test(trimmed) || /\\s/.test(trimmed);\n return shouldQuote ? `\"${escaped}\"` : escaped;\n }\n}\n\nfunction hasFullTextIntent(node: QueryNode | undefined | null): boolean {\n if (!node || typeof node !== 'object') return false;\n\n if (node.kqlQuery) return true;\n if (node.exactPhrase) return true;\n if ('subject' in node && node.subject) return true;\n if ('text' in node && node.text) return true;\n if ('body' in node && node.body) return true;\n\n if ('$and' in node && node.$and) {\n return node.$and.some((child) => hasFullTextIntent(child));\n }\n if ('$or' in node && node.$or) {\n return node.$or.some((child) => hasFullTextIntent(child));\n }\n if ('$not' in node && node.$not) {\n return hasFullTextIntent(node.$not);\n }\n\n return false;\n}\n\nexport function buildQueryFilter(query: QueryNode): string {\n function L(s: string) {\n return s;\n }\n\n function p(s: string) {\n return `(${s})`;\n }\n\n function recip(coll: string, V: string) {\n const left = `r/emailAddress/address eq ${V}`;\n const right = `r/emailAddress/name eq ${V}`;\n return `${coll}/any(r: ${left} or ${right})`;\n }\n\n function fv(field: string, raw: string | number | boolean | null | undefined): string {\n if (raw == null) return '';\n const rawStr = String(raw);\n\n if (field === 'text' || field === 'body') {\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n return '';\n }\n\n if (rawStr.trim() === '') {\n throw new Error(`Invalid ${field} value: empty string`);\n }\n\n const V = `'${rawStr.toLowerCase().replace(/'/g, \"''\")}'`;\n switch (field) {\n case 'from': {\n if (rawStr.includes('@')) {\n const addrEq = `${L('from/emailAddress/address')} eq ${V}`;\n const nameEq = `${L('from/emailAddress/name')} eq ${V}`;\n return p(`${addrEq} or ${nameEq}`);\n }\n return '';\n }\n case 'to':\n return recip('toRecipients', V);\n case 'cc':\n return recip('ccRecipients', V);\n case 'bcc':\n return recip('bccRecipients', V);\n case 'subject':\n if (rawStr.includes('-') || rawStr.length < 3) return '';\n return `startswith(subject, ${V})`;\n case 'categories': {\n const systemCategory = mapOutlookCategory(rawStr);\n return `categories/any(c: c eq '${systemCategory}')`;\n }\n case 'label':\n return `categories/any(c: c eq '${rawStr.replace(/'/g, \"''\")}')`;\n default:\n return '';\n }\n }\n\n function chain(op: 'and' | 'or', arr: Array<string | undefined>) {\n if (!arr || arr.length === 0) {\n throw new Error(`chain: empty array for ${op} operation`);\n }\n if (arr.length === 1) {\n const first = arr[0] ?? '';\n return String(first);\n }\n const joined = arr.join(` ${op} `);\n return p(joined);\n }\n\n function fieldExpr(field: string, op: FieldOperator | string): string {\n if (typeof op === 'string') {\n return fv(field, op);\n }\n\n if (Array.isArray(op.$any)) {\n const results = op.$any.map((v) => fv(field, String(v ?? '')));\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('or', validResults);\n }\n if (Array.isArray(op.$all)) {\n const results = op.$all.map((v) => fv(field, String(v ?? '')));\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return chain('and', validResults);\n }\n if (Array.isArray(op.$none)) {\n const results = op.$none.map((v) => fv(field, String(v ?? '')));\n const validResults = results.filter((s) => s && s.trim());\n if (validResults.length === 0) return '';\n return `not ${p(chain('or', validResults))}`;\n }\n throw new Error(`Unknown field operator ${JSON.stringify(op)}`);\n }\n\n function dateExpr(d: DateOperator): string {\n const parts: string[] = [];\n if (d.$gte) parts.push(`receivedDateTime ge ${d.$gte}T00:00:00Z`);\n if (d.$lt) parts.push(`receivedDateTime lt ${d.$lt}T00:00:00Z`);\n return parts.length > 1 ? p(parts.join(' and ')) : (parts[0] ?? '');\n }\n\n function emit(n: QueryNode): string {\n if (!n || typeof n !== 'object') return '';\n\n if ('$and' in n && n.$and) {\n const andParts = n.$and.map(emit).filter((part: string): part is string => Boolean(part));\n if (andParts.length === 0) return '';\n if (andParts.length === 1) {\n const firstPart = andParts[0];\n return firstPart ?? '';\n }\n return p(andParts.join(' and '));\n }\n if ('$or' in n && n.$or) {\n const orParts = n.$or.map(emit).filter((part: string): part is string => Boolean(part));\n if (orParts.length === 0) return '';\n if (orParts.length === 1) {\n const firstPart = orParts[0];\n return firstPart ?? '';\n }\n return p(orParts.join(' or '));\n }\n if ('$not' in n && n.$not) {\n const notExpr = emit(n.$not);\n return notExpr ? `not (${notExpr})` : '';\n }\n if ('hasAttachment' in n && n.hasAttachment) return 'hasAttachments eq true';\n if ('date' in n && n.date) return dateExpr(n.date);\n\n const keys = Object.keys(n);\n if (keys.length === 1) {\n const k0 = String(keys[0] ?? '');\n if (k0 && ['from', 'to', 'cc', 'bcc', 'subject', 'text', 'body', 'categories', 'label'].includes(k0)) {\n const fieldValue = (n as FieldQuery)[k0 as keyof FieldQuery];\n if (fieldValue) return fieldExpr(k0, fieldValue);\n }\n }\n return '';\n }\n\n return emit(query);\n}\nexport function toOutlookFilter(parsed: QueryNode, _options?: { includeBodyContent?: boolean; useCaseInsensitiveWrap?: boolean }) {\n const graphResult = toGraphFilter(parsed);\n const filters = extractOutlookFilters(parsed);\n return {\n filter: graphResult.filter,\n search: graphResult.search,\n requireBodyClientFilter: graphResult.requireBodyClientFilter,\n filters,\n };\n}\n\ninterface ExtractedFilters {\n subjectIncludes: string[];\n bodyIncludes: string[];\n textIncludes: string[];\n fromIncludes: string[];\n toIncludes: string[];\n ccIncludes: string[];\n bccIncludes: string[];\n categoriesIncludes: string[];\n labelIncludes: string[];\n hasAttachment?: boolean;\n since?: string;\n before?: string;\n}\n\nexport function extractOutlookFilters(parsed: QueryNode): ExtractedFilters {\n const filters: ExtractedFilters = {\n subjectIncludes: [],\n bodyIncludes: [],\n textIncludes: [],\n fromIncludes: [],\n toIncludes: [],\n ccIncludes: [],\n bccIncludes: [],\n categoriesIncludes: [],\n labelIncludes: [],\n };\n function walk(node: QueryNode): void {\n if (!node || typeof node !== 'object') return;\n\n if ('$and' in node && node.$and) {\n node.$and.forEach(walk);\n return;\n }\n if ('$or' in node && node.$or) {\n node.$or.forEach(walk);\n return;\n }\n if ('$not' in node && node.$not) {\n walk(node.$not);\n return;\n }\n\n if ('hasAttachment' in node && node.hasAttachment !== undefined) {\n filters.hasAttachment = node.hasAttachment === true;\n return;\n }\n if ('date' in node && node.date) {\n if (node.date.$gte) filters.since = node.date.$gte;\n if (node.date.$lt) filters.before = node.date.$lt;\n return;\n }\n\n if ('subject' in node && node.subject) {\n if (typeof node.subject === 'string') {\n filters.subjectIncludes.push(node.subject);\n } else {\n if (node.subject.$any) filters.subjectIncludes.push(...node.subject.$any);\n if (node.subject.$all) filters.subjectIncludes.push(...node.subject.$all);\n }\n }\n if ('body' in node && node.body) {\n if (typeof node.body === 'string') {\n filters.bodyIncludes.push(node.body);\n } else {\n if (node.body.$any) filters.bodyIncludes.push(...node.body.$any);\n if (node.body.$all) filters.bodyIncludes.push(...node.body.$all);\n }\n }\n if ('text' in node && node.text) {\n if (typeof node.text === 'string') {\n filters.textIncludes.push(node.text);\n filters.bodyIncludes.push(node.text);\n } else {\n if (node.text.$any) {\n filters.textIncludes.push(...node.text.$any);\n filters.bodyIncludes.push(...node.text.$any);\n }\n if (node.text.$all) {\n filters.textIncludes.push(...node.text.$all);\n filters.bodyIncludes.push(...node.text.$all);\n }\n }\n }\n if ('from' in node && node.from) {\n if (typeof node.from === 'string') {\n filters.fromIncludes.push(node.from);\n } else {\n if (node.from.$any) filters.fromIncludes.push(...node.from.$any);\n if (node.from.$all) filters.fromIncludes.push(...node.from.$all);\n }\n }\n if ('to' in node && node.to) {\n if (typeof node.to === 'string') {\n filters.toIncludes.push(node.to);\n } else {\n if (node.to.$any) filters.toIncludes.push(...node.to.$any);\n if (node.to.$all) filters.toIncludes.push(...node.to.$all);\n }\n }\n if ('cc' in node && node.cc) {\n if (typeof node.cc === 'string') {\n filters.ccIncludes.push(node.cc);\n } else {\n if (node.cc.$any) filters.ccIncludes.push(...node.cc.$any);\n if (node.cc.$all) filters.ccIncludes.push(...node.cc.$all);\n }\n }\n if ('bcc' in node && node.bcc) {\n if (typeof node.bcc === 'string') {\n filters.bccIncludes.push(node.bcc);\n } else {\n if (node.bcc.$any) filters.bccIncludes.push(...node.bcc.$any);\n if (node.bcc.$all) filters.bccIncludes.push(...node.bcc.$all);\n }\n }\n if ('categories' in node && node.categories) {\n if (typeof node.categories === 'string') {\n if (mapOutlookCategory(node.categories) !== null) {\n filters.categoriesIncludes.push(node.categories);\n }\n } else {\n // Filter out invalid categories to prevent memory leaks and maintain clean state\n if (node.categories.$any) {\n const validCategories = node.categories.$any.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$all) {\n const validCategories = node.categories.$all.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n if (node.categories.$none) {\n const validCategories = node.categories.$none.filter((cat: string) => mapOutlookCategory(cat) !== null);\n if (validCategories.length > 0) filters.categoriesIncludes.push(...validCategories);\n }\n }\n }\n if ('label' in node && node.label) {\n if (typeof node.label === 'string') {\n filters.labelIncludes.push(node.label);\n } else {\n if (node.label.$any) filters.labelIncludes.push(...node.label.$any);\n if (node.label.$all) filters.labelIncludes.push(...node.label.$all);\n if (node.label.$none) filters.labelIncludes.push(...node.label.$none);\n }\n }\n }\n walk(parsed);\n return filters;\n}\n"],"names":["OUTLOOK_CATEGORIES","buildQueryFilter","extractOutlookFilters","mapOutlookCategory","toGraphFilter","toOutlookFilter","personal","work","family","travel","important","urgent","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","query","kqlQuery","search","filter","requireBodyClientFilter","hasFullText","hasFullTextIntent","searchCollect","collectSearchTerms","terms","length","usesBody","usesText","filterStr","cleanedFilter","state","usesExact","walkNode","node","$and","forEach","child","$or","$not","exactPhrase","pushExactPhrase","pushOperatorTerms","subject","text","body","value","phrase","String","pushAnyTerms","clause","buildClause","push","Array","isArray","$any","$all","pushAllTerms","$none","clauses","map","term","Boolean","values","val","escapeKQL","replace","_prefix","escaped","shouldQuote","test","some","L","s","p","recip","coll","V","left","right","fv","field","raw","rawStr","includes","addrEq","nameEq","chain","op","arr","first","joined","fieldExpr","results","v","validResults","JSON","stringify","dateExpr","d","parts","$gte","$lt","emit","n","andParts","part","firstPart","orParts","notExpr","hasAttachment","date","k0","fieldValue","parsed","_options","graphResult","filters","subjectIncludes","bodyIncludes","textIncludes","fromIncludes","toIncludes","ccIncludes","bccIncludes","categoriesIncludes","labelIncludes","walk","undefined","since","before","from","to","cc","bcc","categories","validCategories","cat","label"],"mappings":"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"}
|