@mcp-z/mcp-outlook 1.0.14 → 1.0.15
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.js +3 -1
- package/dist/cjs/email/querying/query-builder.js.map +1 -1
- package/dist/cjs/email/querying/search-execution.js +0 -9
- package/dist/cjs/email/querying/search-execution.js.map +1 -1
- package/dist/cjs/mcp/tools/message-search.js +0 -3
- package/dist/cjs/mcp/tools/message-search.js.map +1 -1
- package/dist/esm/email/querying/query-builder.js +3 -1
- package/dist/esm/email/querying/query-builder.js.map +1 -1
- package/dist/esm/email/querying/search-execution.js +0 -3
- package/dist/esm/email/querying/search-execution.js.map +1 -1
- package/dist/esm/mcp/tools/message-search.js +0 -1
- package/dist/esm/mcp/tools/message-search.js.map +1 -1
- package/package.json +1 -1
|
@@ -198,7 +198,9 @@ function collectSearchTerms(query) {
|
|
|
198
198
|
return buildClause(null, val);
|
|
199
199
|
}).filter(Boolean);
|
|
200
200
|
if (!clauses.length) return;
|
|
201
|
-
|
|
201
|
+
// Graph $search silently ignores "(A AND B)" expressions, so narrow with the
|
|
202
|
+
// first term only; the client-side $all predicate enforces the rest.
|
|
203
|
+
state.terms.push(clauses[0]);
|
|
202
204
|
}
|
|
203
205
|
function escapeKQL(value) {
|
|
204
206
|
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, '\\_');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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 // Graph $search silently ignores \"(A AND B)\" expressions, so narrow with the\n // first term only; the client-side $all predicate enforces the rest.\n state.terms.push(clauses[0]);\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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"}
|
|
@@ -136,10 +136,6 @@ function _ts_generator(thisArg, body) {
|
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
function _type_of(obj) {
|
|
140
|
-
"@swc/helpers - typeof";
|
|
141
|
-
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
142
|
-
}
|
|
143
139
|
function searchMessages(graph, opts) {
|
|
144
140
|
return _async_to_generator(function() {
|
|
145
141
|
var _graphPlan_search, query, _opts_includeBody, includeBody, _opts_pageSize, pageSize, pageToken, _opts_maxPages, maxPages, _opts_maxItemsScanned, maxItemsScanned, logger, graphPlan, pageState, useClientFiltering, predicate, requireBody, effectiveIncludeBody, _graphPlan_search1, _graphPlan_filter, result, searchResult, fallbackFilter, fallbackResult;
|
|
@@ -211,11 +207,6 @@ function searchMessages(graph, opts) {
|
|
|
211
207
|
];
|
|
212
208
|
case 3:
|
|
213
209
|
searchResult = _state.sent();
|
|
214
|
-
if (query && 'text' in query && _type_of(query.text) === 'object' && Array.isArray(query.text.$all)) {
|
|
215
|
-
console.log('SEARCH RESULT IDS', searchResult.collected.map(function(msg) {
|
|
216
|
-
return msg.id;
|
|
217
|
-
}));
|
|
218
|
-
}
|
|
219
210
|
if (searchResult.capHit) {
|
|
220
211
|
return [
|
|
221
212
|
2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/email/querying/search-execution.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { Message } from '@microsoft/microsoft-graph-types';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { buildClientPredicate } from './client-filter.ts';\nimport { decodeNextPageToken, encodeNextPageToken, FIRST_PAGE_SKIP_TOKEN } from './pagination-token.ts';\nimport { buildQueryFilter, toGraphFilter } from './query-builder.ts';\n\nexport interface OutlookSearchOptions {\n query?: QueryNode;\n limit?: number;\n includeBody?: boolean;\n maxPages?: number | null;\n maxItemsScanned?: number | null;\n pageSize?: number;\n pageToken?: string | undefined;\n logger: Logger;\n}\n\nexport interface OutlookSearchResult {\n messages: Message[];\n nextPageToken?: string | undefined;\n}\n\nexport async function searchMessages(graph: Client, opts: OutlookSearchOptions): Promise<OutlookSearchResult> {\n const { query, includeBody = false, pageSize = 50, pageToken, maxPages = null, maxItemsScanned = null, logger } = opts;\n\n const graphPlan = query\n ? toGraphFilter(query)\n : {\n search: null,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n const pageState = decodeNextPageToken(pageToken);\n const useClientFiltering = Boolean(query && graphPlan.hasFullText);\n const predicate = useClientFiltering && query ? buildClientPredicate(query) : null;\n const requireBody = graphPlan.requireBodyClientFilter;\n const effectiveIncludeBody = includeBody || (requireBody && !includeBody);\n\n logger.info('Executing Outlook search', {\n hasSearch: !!graphPlan.search,\n hasFilter: !!graphPlan.filter,\n useClientFiltering,\n pageSize,\n includeBody: effectiveIncludeBody,\n pageToken: pageToken ? '[provided]' : undefined,\n forcedBody: requireBody && !includeBody,\n });\n\n if (!useClientFiltering) {\n const result = await fetchGraphPage(graph, {\n search: graphPlan.search ?? undefined,\n filter: graphPlan.filter ?? undefined,\n skipToken: pageState.skipToken,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n });\n return {\n messages: result.messages,\n nextPageToken: result.nextSkipToken,\n };\n }\n\n const searchResult = await collectClientFilteredPages({\n graph,\n search: graphPlan.search ?? undefined,\n filter: undefined,\n startSkipToken: pageState.skipToken,\n startOffset: pageState.offset,\n predicate,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n mode: 'search',\n });\n\n if (query && 'text' in query && typeof query.text === 'object' && Array.isArray(query.text.$all)) {\n console.log(\n 'SEARCH RESULT IDS',\n searchResult.collected.map((msg) => msg.id)\n );\n }\n\n if (searchResult.capHit) {\n return { messages: searchResult.collected };\n }\n if (searchResult.midPageToken) {\n return { messages: searchResult.collected, nextPageToken: searchResult.midPageToken };\n }\n if (searchResult.nextSkipToken) {\n return {\n messages: searchResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: searchResult.nextSkipToken, offset: 0, mode: 'search' }),\n };\n }\n if (searchResult.collected.length > 0) {\n return { messages: searchResult.collected };\n }\n\n if (predicate && query) {\n const fallbackFilter = buildQueryFilter(query).trim();\n if (fallbackFilter) {\n const fallbackResult = await collectClientFilteredPages({\n graph,\n filter: fallbackFilter,\n includeBody: effectiveIncludeBody,\n pageSize,\n predicate,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n startSkipToken: undefined,\n startOffset: 0,\n mode: 'filter',\n });\n\n if (fallbackResult.capHit) {\n return { messages: fallbackResult.collected };\n }\n if (fallbackResult.midPageToken) {\n return { messages: fallbackResult.collected, nextPageToken: fallbackResult.midPageToken };\n }\n if (fallbackResult.nextSkipToken) {\n return {\n messages: fallbackResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: fallbackResult.nextSkipToken, offset: 0, mode: 'filter' }),\n };\n }\n if (fallbackResult.collected.length > 0) {\n return { messages: fallbackResult.collected };\n }\n }\n }\n\n return { messages: searchResult.collected };\n}\n\ninterface GraphPageParams {\n search?: string;\n filter?: string;\n skipToken?: string;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n}\n\nasync function fetchGraphPage(graph: Client, params: GraphPageParams): Promise<{ messages: Message[]; nextSkipToken?: string }> {\n const { search, filter, skipToken, includeBody, pageSize, logger } = params;\n let request = graph.api('/me/messages');\n\n if (search) {\n request = request.search(search);\n }\n if (filter) {\n request = request.filter(filter);\n }\n\n const top = Math.min(pageSize, 1000);\n request = request.top(top);\n\n const selectFields = includeBody ? ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'body', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'] : ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'];\n request = request.select(selectFields.join(','));\n\n if (skipToken && skipToken !== FIRST_PAGE_SKIP_TOKEN) {\n request = request.skipToken(skipToken);\n }\n\n logger.info('Fetching Outlook Graph page', {\n search: !!search,\n filter: !!filter,\n skipToken: skipToken ? '[provided]' : undefined,\n pageSize: top,\n });\n\n const response = await request.get();\n const messages: Message[] = response.value || [];\n let nextSkipToken: string | undefined;\n if (response['@odata.nextLink']) {\n try {\n const nextLinkUrl = new URL(response['@odata.nextLink']);\n nextSkipToken = nextLinkUrl.searchParams.get('$skiptoken') || undefined;\n } catch {\n logger.info('Failed to parse nextLink skipToken', { nextLink: response['@odata.nextLink'] });\n }\n }\n\n logger.info(`Graph page returned ${messages.length} messages`, {\n hasNextPage: !!nextSkipToken,\n });\n\n return { messages, nextSkipToken };\n}\n\ninterface CollectParams {\n graph: Client;\n search?: string;\n filter?: string;\n startSkipToken?: string;\n startOffset?: number;\n predicate: ((message: Message) => boolean) | null;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n maxPages: number | null;\n maxItemsScanned: number | null;\n mode: 'search' | 'filter';\n}\n\ninterface CollectResult {\n collected: Message[];\n midPageToken?: string;\n nextSkipToken?: string;\n capHit: boolean;\n}\n\nasync function collectClientFilteredPages(params: CollectParams): Promise<CollectResult> {\n const { graph, search, filter, startSkipToken, startOffset = 0, predicate, includeBody, pageSize, logger, maxPages, maxItemsScanned, mode } = params;\n let currentSkipToken = startSkipToken;\n let offset = startOffset;\n const collected: Message[] = [];\n let midPageToken: string | undefined;\n let lastNextSkipToken: string | undefined;\n let capHit = false;\n let pagesFetched = 0;\n let scannedItems = 0;\n\n mainLoop: while (collected.length < pageSize) {\n if (maxPages !== null && pagesFetched >= maxPages) {\n capHit = true;\n break;\n }\n\n const pageTokenUsed = currentSkipToken;\n const graphPage = await fetchGraphPage(graph, {\n search,\n filter,\n skipToken: currentSkipToken,\n includeBody,\n pageSize,\n logger,\n });\n\n pagesFetched += 1;\n lastNextSkipToken = graphPage.nextSkipToken;\n const pageItems = graphPage.messages;\n if (!pageItems.length) {\n break;\n }\n\n const startIndex = offset;\n const sliced = startIndex > 0 ? pageItems.slice(startIndex) : pageItems;\n offset = 0;\n\n for (let idx = 0; idx < sliced.length; idx += 1) {\n const message = sliced[idx];\n scannedItems += 1;\n if (maxItemsScanned !== null && scannedItems > maxItemsScanned) {\n capHit = true;\n break mainLoop;\n }\n if (predicate && !predicate(message)) {\n continue;\n }\n collected.push(message);\n if (collected.length === pageSize) {\n const nextOffset = startIndex + idx + 1;\n midPageToken = encodeNextPageToken({\n skipToken: pageTokenUsed,\n offset: nextOffset,\n mode,\n });\n break mainLoop;\n }\n }\n\n currentSkipToken = graphPage.nextSkipToken;\n if (!currentSkipToken) {\n break;\n }\n }\n\n return {\n collected,\n midPageToken,\n nextSkipToken: lastNextSkipToken,\n capHit,\n };\n}\n"],"names":["searchMessages","graph","opts","graphPlan","query","includeBody","pageSize","pageToken","maxPages","maxItemsScanned","logger","pageState","useClientFiltering","predicate","requireBody","effectiveIncludeBody","result","searchResult","fallbackFilter","fallbackResult","toGraphFilter","search","filter","requireBodyClientFilter","hasFullText","decodeNextPageToken","Boolean","buildClientPredicate","info","hasSearch","hasFilter","undefined","forcedBody","fetchGraphPage","skipToken","messages","nextPageToken","nextSkipToken","collectClientFilteredPages","startSkipToken","startOffset","offset","mode","text","Array","isArray","$all","console","log","collected","map","msg","id","capHit","midPageToken","encodeNextPageToken","length","buildQueryFilter","trim","params","request","top","selectFields","response","nextLinkUrl","api","Math","min","select","join","FIRST_PAGE_SKIP_TOKEN","get","value","URL","searchParams","nextLink","hasNextPage","currentSkipToken","lastNextSkipToken","pagesFetched","scannedItems","pageTokenUsed","graphPage","pageItems","startIndex","sliced","idx","message","nextOffset","slice","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/email/querying/search-execution.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { Message } from '@microsoft/microsoft-graph-types';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { buildClientPredicate } from './client-filter.ts';\nimport { decodeNextPageToken, encodeNextPageToken, FIRST_PAGE_SKIP_TOKEN } from './pagination-token.ts';\nimport { buildQueryFilter, toGraphFilter } from './query-builder.ts';\n\nexport interface OutlookSearchOptions {\n query?: QueryNode;\n limit?: number;\n includeBody?: boolean;\n maxPages?: number | null;\n maxItemsScanned?: number | null;\n pageSize?: number;\n pageToken?: string | undefined;\n logger: Logger;\n}\n\nexport interface OutlookSearchResult {\n messages: Message[];\n nextPageToken?: string | undefined;\n}\n\nexport async function searchMessages(graph: Client, opts: OutlookSearchOptions): Promise<OutlookSearchResult> {\n const { query, includeBody = false, pageSize = 50, pageToken, maxPages = null, maxItemsScanned = null, logger } = opts;\n\n const graphPlan = query\n ? toGraphFilter(query)\n : {\n search: null,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n const pageState = decodeNextPageToken(pageToken);\n const useClientFiltering = Boolean(query && graphPlan.hasFullText);\n const predicate = useClientFiltering && query ? buildClientPredicate(query) : null;\n const requireBody = graphPlan.requireBodyClientFilter;\n const effectiveIncludeBody = includeBody || (requireBody && !includeBody);\n\n logger.info('Executing Outlook search', {\n hasSearch: !!graphPlan.search,\n hasFilter: !!graphPlan.filter,\n useClientFiltering,\n pageSize,\n includeBody: effectiveIncludeBody,\n pageToken: pageToken ? '[provided]' : undefined,\n forcedBody: requireBody && !includeBody,\n });\n\n if (!useClientFiltering) {\n const result = await fetchGraphPage(graph, {\n search: graphPlan.search ?? undefined,\n filter: graphPlan.filter ?? undefined,\n skipToken: pageState.skipToken,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n });\n return {\n messages: result.messages,\n nextPageToken: result.nextSkipToken,\n };\n }\n\n const searchResult = await collectClientFilteredPages({\n graph,\n search: graphPlan.search ?? undefined,\n filter: undefined,\n startSkipToken: pageState.skipToken,\n startOffset: pageState.offset,\n predicate,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n mode: 'search',\n });\n\n if (searchResult.capHit) {\n return { messages: searchResult.collected };\n }\n if (searchResult.midPageToken) {\n return { messages: searchResult.collected, nextPageToken: searchResult.midPageToken };\n }\n if (searchResult.nextSkipToken) {\n return {\n messages: searchResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: searchResult.nextSkipToken, offset: 0, mode: 'search' }),\n };\n }\n if (searchResult.collected.length > 0) {\n return { messages: searchResult.collected };\n }\n\n if (predicate && query) {\n const fallbackFilter = buildQueryFilter(query).trim();\n if (fallbackFilter) {\n const fallbackResult = await collectClientFilteredPages({\n graph,\n filter: fallbackFilter,\n includeBody: effectiveIncludeBody,\n pageSize,\n predicate,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n startSkipToken: undefined,\n startOffset: 0,\n mode: 'filter',\n });\n\n if (fallbackResult.capHit) {\n return { messages: fallbackResult.collected };\n }\n if (fallbackResult.midPageToken) {\n return { messages: fallbackResult.collected, nextPageToken: fallbackResult.midPageToken };\n }\n if (fallbackResult.nextSkipToken) {\n return {\n messages: fallbackResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: fallbackResult.nextSkipToken, offset: 0, mode: 'filter' }),\n };\n }\n if (fallbackResult.collected.length > 0) {\n return { messages: fallbackResult.collected };\n }\n }\n }\n\n return { messages: searchResult.collected };\n}\n\ninterface GraphPageParams {\n search?: string;\n filter?: string;\n skipToken?: string;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n}\n\nasync function fetchGraphPage(graph: Client, params: GraphPageParams): Promise<{ messages: Message[]; nextSkipToken?: string }> {\n const { search, filter, skipToken, includeBody, pageSize, logger } = params;\n let request = graph.api('/me/messages');\n\n if (search) {\n request = request.search(search);\n }\n if (filter) {\n request = request.filter(filter);\n }\n\n const top = Math.min(pageSize, 1000);\n request = request.top(top);\n\n const selectFields = includeBody ? ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'body', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'] : ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'];\n request = request.select(selectFields.join(','));\n\n if (skipToken && skipToken !== FIRST_PAGE_SKIP_TOKEN) {\n request = request.skipToken(skipToken);\n }\n\n logger.info('Fetching Outlook Graph page', {\n search: !!search,\n filter: !!filter,\n skipToken: skipToken ? '[provided]' : undefined,\n pageSize: top,\n });\n\n const response = await request.get();\n const messages: Message[] = response.value || [];\n let nextSkipToken: string | undefined;\n if (response['@odata.nextLink']) {\n try {\n const nextLinkUrl = new URL(response['@odata.nextLink']);\n nextSkipToken = nextLinkUrl.searchParams.get('$skiptoken') || undefined;\n } catch {\n logger.info('Failed to parse nextLink skipToken', { nextLink: response['@odata.nextLink'] });\n }\n }\n\n logger.info(`Graph page returned ${messages.length} messages`, {\n hasNextPage: !!nextSkipToken,\n });\n\n return { messages, nextSkipToken };\n}\n\ninterface CollectParams {\n graph: Client;\n search?: string;\n filter?: string;\n startSkipToken?: string;\n startOffset?: number;\n predicate: ((message: Message) => boolean) | null;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n maxPages: number | null;\n maxItemsScanned: number | null;\n mode: 'search' | 'filter';\n}\n\ninterface CollectResult {\n collected: Message[];\n midPageToken?: string;\n nextSkipToken?: string;\n capHit: boolean;\n}\n\nasync function collectClientFilteredPages(params: CollectParams): Promise<CollectResult> {\n const { graph, search, filter, startSkipToken, startOffset = 0, predicate, includeBody, pageSize, logger, maxPages, maxItemsScanned, mode } = params;\n let currentSkipToken = startSkipToken;\n let offset = startOffset;\n const collected: Message[] = [];\n let midPageToken: string | undefined;\n let lastNextSkipToken: string | undefined;\n let capHit = false;\n let pagesFetched = 0;\n let scannedItems = 0;\n\n mainLoop: while (collected.length < pageSize) {\n if (maxPages !== null && pagesFetched >= maxPages) {\n capHit = true;\n break;\n }\n\n const pageTokenUsed = currentSkipToken;\n const graphPage = await fetchGraphPage(graph, {\n search,\n filter,\n skipToken: currentSkipToken,\n includeBody,\n pageSize,\n logger,\n });\n\n pagesFetched += 1;\n lastNextSkipToken = graphPage.nextSkipToken;\n const pageItems = graphPage.messages;\n if (!pageItems.length) {\n break;\n }\n\n const startIndex = offset;\n const sliced = startIndex > 0 ? pageItems.slice(startIndex) : pageItems;\n offset = 0;\n\n for (let idx = 0; idx < sliced.length; idx += 1) {\n const message = sliced[idx];\n scannedItems += 1;\n if (maxItemsScanned !== null && scannedItems > maxItemsScanned) {\n capHit = true;\n break mainLoop;\n }\n if (predicate && !predicate(message)) {\n continue;\n }\n collected.push(message);\n if (collected.length === pageSize) {\n const nextOffset = startIndex + idx + 1;\n midPageToken = encodeNextPageToken({\n skipToken: pageTokenUsed,\n offset: nextOffset,\n mode,\n });\n break mainLoop;\n }\n }\n\n currentSkipToken = graphPage.nextSkipToken;\n if (!currentSkipToken) {\n break;\n }\n }\n\n return {\n collected,\n midPageToken,\n nextSkipToken: lastNextSkipToken,\n capHit,\n };\n}\n"],"names":["searchMessages","graph","opts","graphPlan","query","includeBody","pageSize","pageToken","maxPages","maxItemsScanned","logger","pageState","useClientFiltering","predicate","requireBody","effectiveIncludeBody","result","searchResult","fallbackFilter","fallbackResult","toGraphFilter","search","filter","requireBodyClientFilter","hasFullText","decodeNextPageToken","Boolean","buildClientPredicate","info","hasSearch","hasFilter","undefined","forcedBody","fetchGraphPage","skipToken","messages","nextPageToken","nextSkipToken","collectClientFilteredPages","startSkipToken","startOffset","offset","mode","capHit","collected","midPageToken","encodeNextPageToken","length","buildQueryFilter","trim","params","request","top","selectFields","response","nextLinkUrl","api","Math","min","select","join","FIRST_PAGE_SKIP_TOKEN","get","value","URL","searchParams","nextLink","hasNextPage","currentSkipToken","lastNextSkipToken","pagesFetched","scannedItems","pageTokenUsed","graphPage","pageItems","startIndex","sliced","idx","message","nextOffset","slice","push"],"mappings":";;;;+BAwBsBA;;;eAAAA;;;8BApBe;iCAC2C;8BAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBzC,SAAeA,eAAeC,KAAa,EAAEC,IAA0B;;YA4ClEC,mBA3CFC,0BAAOC,6BAAqBC,UAAeC,2BAAWC,iCAAiBC,iBAAwBC,QAEjGP,WAQAQ,WACAC,oBACAC,WACAC,aACAC,sBAcMZ,oBACAA,mBAFJa,QAcFC,cAgCEC,gBAEEC;;;;oBA3EFf,QAA0GF,KAA1GE,2BAA0GF,KAAnGG,aAAAA,6CAAc,4CAAqFH,KAA9EI,UAAAA,uCAAW,qBAAIC,YAA+DL,KAA/DK,4BAA+DL,KAApDM,UAAAA,uCAAW,+CAAyCN,KAAnCO,iBAAAA,qDAAkB,8BAAMC,SAAWR,KAAXQ;oBAEjGP,YAAYC,QACdgB,IAAAA,6BAAa,EAAChB,SACd;wBACEiB,QAAQ;wBACRC,QAAQ;wBACRC,yBAAyB;wBACzBC,aAAa;oBACf;oBACEb,YAAYc,IAAAA,sCAAmB,EAAClB;oBAChCK,qBAAqBc,QAAQtB,SAASD,UAAUqB,WAAW;oBAC3DX,YAAYD,sBAAsBR,QAAQuB,IAAAA,oCAAoB,EAACvB,SAAS;oBACxEU,cAAcX,UAAUoB,uBAAuB;oBAC/CR,uBAAuBV,eAAgBS,eAAe,CAACT;oBAE7DK,OAAOkB,IAAI,CAAC,4BAA4B;wBACtCC,WAAW,CAAC,CAAC1B,UAAUkB,MAAM;wBAC7BS,WAAW,CAAC,CAAC3B,UAAUmB,MAAM;wBAC7BV,oBAAAA;wBACAN,UAAAA;wBACAD,aAAaU;wBACbR,WAAWA,YAAY,eAAewB;wBACtCC,YAAYlB,eAAe,CAACT;oBAC9B;yBAEI,CAACO,oBAAD;;;;oBACa;;wBAAMqB,eAAehC,OAAO;4BACzCoB,MAAM,GAAElB,qBAAAA,UAAUkB,MAAM,cAAhBlB,gCAAAA,qBAAoB4B;4BAC5BT,MAAM,GAAEnB,oBAAAA,UAAUmB,MAAM,cAAhBnB,+BAAAA,oBAAoB4B;4BAC5BG,WAAWvB,UAAUuB,SAAS;4BAC9B7B,aAAaU;4BACbT,UAAAA;4BACAI,QAAAA;wBACF;;;oBAPMM,SAAS;oBAQf;;wBAAO;4BACLmB,UAAUnB,OAAOmB,QAAQ;4BACzBC,eAAepB,OAAOqB,aAAa;wBACrC;;;oBAGmB;;wBAAMC,2BAA2B;4BACpDrC,OAAAA;4BACAoB,MAAM,GAAElB,oBAAAA,UAAUkB,MAAM,cAAhBlB,+BAAAA,oBAAoB4B;4BAC5BT,QAAQS;4BACRQ,gBAAgB5B,UAAUuB,SAAS;4BACnCM,aAAa7B,UAAU8B,MAAM;4BAC7B5B,WAAAA;4BACAR,aAAaU;4BACbT,UAAAA;4BACAI,QAAAA;4BACAF,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;4BACtBC,eAAe,EAAEA,4BAAAA,6BAAAA,kBAAmB;4BACpCiC,MAAM;wBACR;;;oBAbMzB,eAAe;oBAerB,IAAIA,aAAa0B,MAAM,EAAE;wBACvB;;4BAAO;gCAAER,UAAUlB,aAAa2B,SAAS;4BAAC;;oBAC5C;oBACA,IAAI3B,aAAa4B,YAAY,EAAE;wBAC7B;;4BAAO;gCAAEV,UAAUlB,aAAa2B,SAAS;gCAAER,eAAenB,aAAa4B,YAAY;4BAAC;;oBACtF;oBACA,IAAI5B,aAAaoB,aAAa,EAAE;wBAC9B;;4BAAO;gCACLF,UAAUlB,aAAa2B,SAAS;gCAChCR,eAAeU,IAAAA,sCAAmB,EAAC;oCAAEZ,WAAWjB,aAAaoB,aAAa;oCAAEI,QAAQ;oCAAGC,MAAM;gCAAS;4BACxG;;oBACF;oBACA,IAAIzB,aAAa2B,SAAS,CAACG,MAAM,GAAG,GAAG;wBACrC;;4BAAO;gCAAEZ,UAAUlB,aAAa2B,SAAS;4BAAC;;oBAC5C;yBAEI/B,CAAAA,aAAaT,KAAI,GAAjBS;;;;oBACIK,iBAAiB8B,IAAAA,gCAAgB,EAAC5C,OAAO6C,IAAI;yBAC/C/B,gBAAAA;;;;oBACqB;;wBAAMoB,2BAA2B;4BACtDrC,OAAAA;4BACAqB,QAAQJ;4BACRb,aAAaU;4BACbT,UAAAA;4BACAO,WAAAA;4BACAH,QAAAA;4BACAF,QAAQ,EAAEA,qBAAAA,sBAAAA,WAAY;4BACtBC,eAAe,EAAEA,4BAAAA,6BAAAA,kBAAmB;4BACpC8B,gBAAgBR;4BAChBS,aAAa;4BACbE,MAAM;wBACR;;;oBAZMvB,iBAAiB;oBAcvB,IAAIA,eAAewB,MAAM,EAAE;wBACzB;;4BAAO;gCAAER,UAAUhB,eAAeyB,SAAS;4BAAC;;oBAC9C;oBACA,IAAIzB,eAAe0B,YAAY,EAAE;wBAC/B;;4BAAO;gCAAEV,UAAUhB,eAAeyB,SAAS;gCAAER,eAAejB,eAAe0B,YAAY;4BAAC;;oBAC1F;oBACA,IAAI1B,eAAekB,aAAa,EAAE;wBAChC;;4BAAO;gCACLF,UAAUhB,eAAeyB,SAAS;gCAClCR,eAAeU,IAAAA,sCAAmB,EAAC;oCAAEZ,WAAWf,eAAekB,aAAa;oCAAEI,QAAQ;oCAAGC,MAAM;gCAAS;4BAC1G;;oBACF;oBACA,IAAIvB,eAAeyB,SAAS,CAACG,MAAM,GAAG,GAAG;wBACvC;;4BAAO;gCAAEZ,UAAUhB,eAAeyB,SAAS;4BAAC;;oBAC9C;;;oBAIJ;;wBAAO;4BAAET,UAAUlB,aAAa2B,SAAS;wBAAC;;;;IAC5C;;AAWA,SAAeX,eAAehC,KAAa,EAAEiD,MAAuB;;YAC1D7B,QAAQC,QAAQY,WAAW7B,aAAaC,UAAUI,QACtDyC,SASEC,KAGAC,cAcAC,UACAnB,UACFE,eAGMkB;;;;oBAhCFlC,SAA6D6B,OAA7D7B,QAAQC,SAAqD4B,OAArD5B,QAAQY,YAA6CgB,OAA7ChB,WAAW7B,cAAkC6C,OAAlC7C,aAAaC,WAAqB4C,OAArB5C,UAAUI,SAAWwC,OAAXxC;oBACtDyC,UAAUlD,MAAMuD,GAAG,CAAC;oBAExB,IAAInC,QAAQ;wBACV8B,UAAUA,QAAQ9B,MAAM,CAACA;oBAC3B;oBACA,IAAIC,QAAQ;wBACV6B,UAAUA,QAAQ7B,MAAM,CAACA;oBAC3B;oBAEM8B,MAAMK,KAAKC,GAAG,CAACpD,UAAU;oBAC/B6C,UAAUA,QAAQC,GAAG,CAACA;oBAEhBC,eAAehD;wBAAe;wBAAM;wBAAkB;wBAAoB;wBAAW;wBAAe;wBAAQ;wBAAQ;wBAAgB;wBAAgB;;wBAAoB;wBAAM;wBAAkB;wBAAoB;wBAAW;wBAAe;wBAAQ;wBAAgB;wBAAgB;;oBAC5R8C,UAAUA,QAAQQ,MAAM,CAACN,aAAaO,IAAI,CAAC;oBAE3C,IAAI1B,aAAaA,cAAc2B,wCAAqB,EAAE;wBACpDV,UAAUA,QAAQjB,SAAS,CAACA;oBAC9B;oBAEAxB,OAAOkB,IAAI,CAAC,+BAA+B;wBACzCP,QAAQ,CAAC,CAACA;wBACVC,QAAQ,CAAC,CAACA;wBACVY,WAAWA,YAAY,eAAeH;wBACtCzB,UAAU8C;oBACZ;oBAEiB;;wBAAMD,QAAQW,GAAG;;;oBAA5BR,WAAW;oBACXnB,WAAsBmB,SAASS,KAAK;oBAE1C,IAAIT,QAAQ,CAAC,kBAAkB,EAAE;wBAC/B,IAAI;4BACIC,cAAc,IAAIS,IAAIV,QAAQ,CAAC,kBAAkB;4BACvDjB,gBAAgBkB,YAAYU,YAAY,CAACH,GAAG,CAAC,iBAAiB/B;wBAChE,EAAE,eAAM;4BACNrB,OAAOkB,IAAI,CAAC,sCAAsC;gCAAEsC,UAAUZ,QAAQ,CAAC,kBAAkB;4BAAC;wBAC5F;oBACF;oBAEA5C,OAAOkB,IAAI,CAAC,AAAC,uBAAsC,OAAhBO,SAASY,MAAM,EAAC,cAAY;wBAC7DoB,aAAa,CAAC,CAAC9B;oBACjB;oBAEA;;wBAAO;4BAAEF,UAAAA;4BAAUE,eAAAA;wBAAc;;;;IACnC;;AAwBA,SAAeC,2BAA2BY,MAAqB;;YACrDjD,OAAOoB,QAAQC,QAAQiB,qCAAgBC,aAAiB3B,WAAWR,aAAaC,UAAUI,QAAQF,UAAUC,iBAAiBiC,MACjI0B,kBACA3B,QACEG,WACFC,cACAwB,mBACA1B,QACA2B,cACAC,cAQIC,eACAC,WAWAC,WAKAC,YACAC,QAGGC,KACDC,SAWEC;;;;oBAjDJ9E,QAAsIiD,OAAtIjD,OAAOoB,SAA+H6B,OAA/H7B,QAAQC,SAAuH4B,OAAvH5B,QAAQiB,iBAA+GW,OAA/GX,sCAA+GW,OAA/FV,aAAAA,+CAAc,yBAAG3B,YAA8EqC,OAA9ErC,WAAWR,cAAmE6C,OAAnE7C,aAAaC,WAAsD4C,OAAtD5C,UAAUI,SAA4CwC,OAA5CxC,QAAQF,WAAoC0C,OAApC1C,UAAUC,kBAA0ByC,OAA1BzC,iBAAiBiC,OAASQ,OAATR;oBACjI0B,mBAAmB7B;oBACnBE,SAASD;oBACPI;oBAGFD,SAAS;oBACT2B,eAAe;oBACfC,eAAe;;;yBAEF3B,CAAAA,UAAUG,MAAM,GAAGzC,QAAO;;;;oBACzC,IAAIE,aAAa,QAAQ8D,gBAAgB9D,UAAU;wBACjDmC,SAAS;wBACT;;;;oBACF;oBAEM6B,gBAAgBJ;oBACJ;;wBAAMnC,eAAehC,OAAO;4BAC5CoB,QAAAA;4BACAC,QAAAA;4BACAY,WAAWkC;4BACX/D,aAAAA;4BACAC,UAAAA;4BACAI,QAAAA;wBACF;;;oBAPM+D,YAAY;oBASlBH,gBAAgB;oBAChBD,oBAAoBI,UAAUpC,aAAa;oBACrCqC,YAAYD,UAAUtC,QAAQ;oBACpC,IAAI,CAACuC,UAAU3B,MAAM,EAAE;wBACrB;;;;oBACF;oBAEM4B,aAAalC;oBACbmC,SAASD,aAAa,IAAID,UAAUM,KAAK,CAACL,cAAcD;oBAC9DjC,SAAS;oBAET,IAASoC,MAAM,GAAGA,MAAMD,OAAO7B,MAAM,EAAE8B,OAAO,EAAG;wBACzCC,UAAUF,MAAM,CAACC,IAAI;wBAC3BN,gBAAgB;wBAChB,IAAI9D,oBAAoB,QAAQ8D,eAAe9D,iBAAiB;4BAC9DkC,SAAS;4BACT;;;;wBACF;wBACA,IAAI9B,aAAa,CAACA,UAAUiE,UAAU;4BACpC;wBACF;wBACAlC,UAAUqC,IAAI,CAACH;wBACf,IAAIlC,UAAUG,MAAM,KAAKzC,UAAU;4BAC3ByE,aAAaJ,aAAaE,MAAM;4BACtChC,eAAeC,IAAAA,sCAAmB,EAAC;gCACjCZ,WAAWsC;gCACX/B,QAAQsC;gCACRrC,MAAAA;4BACF;4BACA;;;;wBACF;oBACF;oBAEA0B,mBAAmBK,UAAUpC,aAAa;oBAC1C,IAAI,CAAC+B,kBAAkB;wBACrB;;;;oBACF;;;;;;oBAGF;;wBAAO;4BACLxB,WAAAA;4BACAC,cAAAA;4BACAR,eAAegC;4BACf1B,QAAAA;wBACF;;;;IACF"}
|
|
@@ -338,9 +338,6 @@ function handler(_0, _1) {
|
|
|
338
338
|
filteredItems = exec.items.map(function(item) {
|
|
339
339
|
return (0, _server.filterFields)(item, requestedFields);
|
|
340
340
|
});
|
|
341
|
-
console.log('HANDLER OUTPUT IDS', filteredItems.map(function(item) {
|
|
342
|
-
return item.id;
|
|
343
|
-
}));
|
|
344
341
|
logger.info('outlook.message.search returning', {
|
|
345
342
|
query: query,
|
|
346
343
|
pageSize: pageSize,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { needsBody } from '../../email/querying/client-filter.ts';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema, parseOutlookQueryParameter } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseOutlookQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const needsBodyContent = needsBody(parsedQuery);\n const includeBody = requestedFields === 'all' || requestedFields.has('body') || needsBodyContent;\n\n logger.info('outlook.search called with', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n parsedQuery,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n console.log(\n 'HANDLER OUTPUT IDS',\n filteredItems.map((item) => item.id)\n );\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","OutlookQueryParameterSchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","maxPageSize","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","parsedQuery","requestedFields","needsBodyContent","includeBody","graph","started","exec","durationMs","filteredItems","metadataObj","error","message","parseOutlookQueryParameter","parseFields","needsBody","has","info","undefined","Client","initWithMiddleware","authProvider","authContext","auth","Date","now","executeOutlookQuery","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","item","filterFields","console","log","itemsLength","length","metadata","toColumnarFormat","text","JSON","stringify","structuredContent","Error","String","McpError","ErrorCode","InternalError","stack"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { needsBody } from '../../email/querying/client-filter.ts';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema, parseOutlookQueryParameter } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseOutlookQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const needsBodyContent = needsBody(parsedQuery);\n const includeBody = requestedFields === 'all' || requestedFields.has('body') || needsBodyContent;\n\n logger.info('outlook.search called with', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n parsedQuery,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["createTool","AuthRequiredBranchSchema","schemas","inputSchema","z","object","query","OutlookQueryParameterSchema","optional","describe","fields","createFieldsSchema","availableFields","EMAIL_FIELDS","fieldDescriptions","EMAIL_FIELD_DESCRIPTIONS","commonPatterns","EMAIL_COMMON_PATTERNS","resourceName","createPaginationSchema","defaultPageSize","maxPageSize","provider","shape","createShapeSchema","contentType","EmailContentTypeSchema","excludeThreadHistory","ExcludeThreadHistorySchema","successObjectsBranchSchema","type","literal","items","array","EmailDetailSchema","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","extra","pageSize","pageToken","logger","parsedQuery","requestedFields","needsBodyContent","includeBody","graph","started","exec","durationMs","filteredItems","metadataObj","error","message","parseOutlookQueryParameter","parseFields","needsBody","has","info","undefined","Client","initWithMiddleware","authProvider","authContext","auth","Date","now","executeOutlookQuery","limit","m","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","item","filterFields","itemsLength","length","metadata","toColumnarFormat","text","JSON","stringify","structuredContent","Error","String","McpError","ErrorCode","InternalError","stack"],"mappings":"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"}
|
|
@@ -133,7 +133,9 @@ function collectSearchTerms(query) {
|
|
|
133
133
|
function pushAllTerms(values) {
|
|
134
134
|
const clauses = values.map((val)=>buildClause(null, val)).filter(Boolean);
|
|
135
135
|
if (!clauses.length) return;
|
|
136
|
-
|
|
136
|
+
// Graph $search silently ignores "(A AND B)" expressions, so narrow with the
|
|
137
|
+
// first term only; the client-side $all predicate enforces the rest.
|
|
138
|
+
state.terms.push(clauses[0]);
|
|
137
139
|
}
|
|
138
140
|
function escapeKQL(value) {
|
|
139
141
|
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, '\\_');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","toGraphFilter","query","kqlQuery","search","filter","requireBodyClientFilter","hasFullText","hasFullTextIntent","searchCollect","collectSearchTerms","terms","length","usesBody","usesText","filterStr","buildQueryFilter","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","toOutlookFilter","parsed","_options","graphResult","filters","extractOutlookFilters","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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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/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 // Graph $search silently ignores \"(A AND B)\" expressions, so narrow with the\n // first term only; the client-side $all predicate enforces the rest.\n state.terms.push(clauses[0]);\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","personal","work","family","travel","important","urgent","mapOutlookCategory","category","Error","trimmed","trim","normalizedCategory","toLowerCase","systemCategory","Object","keys","join","toGraphFilter","query","kqlQuery","search","filter","requireBodyClientFilter","hasFullText","hasFullTextIntent","searchCollect","collectSearchTerms","terms","length","usesBody","usesText","filterStr","buildQueryFilter","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","toOutlookFilter","parsed","_options","graphResult","filters","extractOutlookFilters","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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"}
|
|
@@ -53,9 +53,6 @@ export async function searchMessages(graph, opts) {
|
|
|
53
53
|
maxItemsScanned: maxItemsScanned !== null && maxItemsScanned !== void 0 ? maxItemsScanned : null,
|
|
54
54
|
mode: 'search'
|
|
55
55
|
});
|
|
56
|
-
if (query && 'text' in query && typeof query.text === 'object' && Array.isArray(query.text.$all)) {
|
|
57
|
-
console.log('SEARCH RESULT IDS', searchResult.collected.map((msg)=>msg.id));
|
|
58
|
-
}
|
|
59
56
|
if (searchResult.capHit) {
|
|
60
57
|
return {
|
|
61
58
|
messages: searchResult.collected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/email/querying/search-execution.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { Message } from '@microsoft/microsoft-graph-types';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { buildClientPredicate } from './client-filter.ts';\nimport { decodeNextPageToken, encodeNextPageToken, FIRST_PAGE_SKIP_TOKEN } from './pagination-token.ts';\nimport { buildQueryFilter, toGraphFilter } from './query-builder.ts';\n\nexport interface OutlookSearchOptions {\n query?: QueryNode;\n limit?: number;\n includeBody?: boolean;\n maxPages?: number | null;\n maxItemsScanned?: number | null;\n pageSize?: number;\n pageToken?: string | undefined;\n logger: Logger;\n}\n\nexport interface OutlookSearchResult {\n messages: Message[];\n nextPageToken?: string | undefined;\n}\n\nexport async function searchMessages(graph: Client, opts: OutlookSearchOptions): Promise<OutlookSearchResult> {\n const { query, includeBody = false, pageSize = 50, pageToken, maxPages = null, maxItemsScanned = null, logger } = opts;\n\n const graphPlan = query\n ? toGraphFilter(query)\n : {\n search: null,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n const pageState = decodeNextPageToken(pageToken);\n const useClientFiltering = Boolean(query && graphPlan.hasFullText);\n const predicate = useClientFiltering && query ? buildClientPredicate(query) : null;\n const requireBody = graphPlan.requireBodyClientFilter;\n const effectiveIncludeBody = includeBody || (requireBody && !includeBody);\n\n logger.info('Executing Outlook search', {\n hasSearch: !!graphPlan.search,\n hasFilter: !!graphPlan.filter,\n useClientFiltering,\n pageSize,\n includeBody: effectiveIncludeBody,\n pageToken: pageToken ? '[provided]' : undefined,\n forcedBody: requireBody && !includeBody,\n });\n\n if (!useClientFiltering) {\n const result = await fetchGraphPage(graph, {\n search: graphPlan.search ?? undefined,\n filter: graphPlan.filter ?? undefined,\n skipToken: pageState.skipToken,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n });\n return {\n messages: result.messages,\n nextPageToken: result.nextSkipToken,\n };\n }\n\n const searchResult = await collectClientFilteredPages({\n graph,\n search: graphPlan.search ?? undefined,\n filter: undefined,\n startSkipToken: pageState.skipToken,\n startOffset: pageState.offset,\n predicate,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n mode: 'search',\n });\n\n if (query && 'text' in query && typeof query.text === 'object' && Array.isArray(query.text.$all)) {\n console.log(\n 'SEARCH RESULT IDS',\n searchResult.collected.map((msg) => msg.id)\n );\n }\n\n if (searchResult.capHit) {\n return { messages: searchResult.collected };\n }\n if (searchResult.midPageToken) {\n return { messages: searchResult.collected, nextPageToken: searchResult.midPageToken };\n }\n if (searchResult.nextSkipToken) {\n return {\n messages: searchResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: searchResult.nextSkipToken, offset: 0, mode: 'search' }),\n };\n }\n if (searchResult.collected.length > 0) {\n return { messages: searchResult.collected };\n }\n\n if (predicate && query) {\n const fallbackFilter = buildQueryFilter(query).trim();\n if (fallbackFilter) {\n const fallbackResult = await collectClientFilteredPages({\n graph,\n filter: fallbackFilter,\n includeBody: effectiveIncludeBody,\n pageSize,\n predicate,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n startSkipToken: undefined,\n startOffset: 0,\n mode: 'filter',\n });\n\n if (fallbackResult.capHit) {\n return { messages: fallbackResult.collected };\n }\n if (fallbackResult.midPageToken) {\n return { messages: fallbackResult.collected, nextPageToken: fallbackResult.midPageToken };\n }\n if (fallbackResult.nextSkipToken) {\n return {\n messages: fallbackResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: fallbackResult.nextSkipToken, offset: 0, mode: 'filter' }),\n };\n }\n if (fallbackResult.collected.length > 0) {\n return { messages: fallbackResult.collected };\n }\n }\n }\n\n return { messages: searchResult.collected };\n}\n\ninterface GraphPageParams {\n search?: string;\n filter?: string;\n skipToken?: string;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n}\n\nasync function fetchGraphPage(graph: Client, params: GraphPageParams): Promise<{ messages: Message[]; nextSkipToken?: string }> {\n const { search, filter, skipToken, includeBody, pageSize, logger } = params;\n let request = graph.api('/me/messages');\n\n if (search) {\n request = request.search(search);\n }\n if (filter) {\n request = request.filter(filter);\n }\n\n const top = Math.min(pageSize, 1000);\n request = request.top(top);\n\n const selectFields = includeBody ? ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'body', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'] : ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'];\n request = request.select(selectFields.join(','));\n\n if (skipToken && skipToken !== FIRST_PAGE_SKIP_TOKEN) {\n request = request.skipToken(skipToken);\n }\n\n logger.info('Fetching Outlook Graph page', {\n search: !!search,\n filter: !!filter,\n skipToken: skipToken ? '[provided]' : undefined,\n pageSize: top,\n });\n\n const response = await request.get();\n const messages: Message[] = response.value || [];\n let nextSkipToken: string | undefined;\n if (response['@odata.nextLink']) {\n try {\n const nextLinkUrl = new URL(response['@odata.nextLink']);\n nextSkipToken = nextLinkUrl.searchParams.get('$skiptoken') || undefined;\n } catch {\n logger.info('Failed to parse nextLink skipToken', { nextLink: response['@odata.nextLink'] });\n }\n }\n\n logger.info(`Graph page returned ${messages.length} messages`, {\n hasNextPage: !!nextSkipToken,\n });\n\n return { messages, nextSkipToken };\n}\n\ninterface CollectParams {\n graph: Client;\n search?: string;\n filter?: string;\n startSkipToken?: string;\n startOffset?: number;\n predicate: ((message: Message) => boolean) | null;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n maxPages: number | null;\n maxItemsScanned: number | null;\n mode: 'search' | 'filter';\n}\n\ninterface CollectResult {\n collected: Message[];\n midPageToken?: string;\n nextSkipToken?: string;\n capHit: boolean;\n}\n\nasync function collectClientFilteredPages(params: CollectParams): Promise<CollectResult> {\n const { graph, search, filter, startSkipToken, startOffset = 0, predicate, includeBody, pageSize, logger, maxPages, maxItemsScanned, mode } = params;\n let currentSkipToken = startSkipToken;\n let offset = startOffset;\n const collected: Message[] = [];\n let midPageToken: string | undefined;\n let lastNextSkipToken: string | undefined;\n let capHit = false;\n let pagesFetched = 0;\n let scannedItems = 0;\n\n mainLoop: while (collected.length < pageSize) {\n if (maxPages !== null && pagesFetched >= maxPages) {\n capHit = true;\n break;\n }\n\n const pageTokenUsed = currentSkipToken;\n const graphPage = await fetchGraphPage(graph, {\n search,\n filter,\n skipToken: currentSkipToken,\n includeBody,\n pageSize,\n logger,\n });\n\n pagesFetched += 1;\n lastNextSkipToken = graphPage.nextSkipToken;\n const pageItems = graphPage.messages;\n if (!pageItems.length) {\n break;\n }\n\n const startIndex = offset;\n const sliced = startIndex > 0 ? pageItems.slice(startIndex) : pageItems;\n offset = 0;\n\n for (let idx = 0; idx < sliced.length; idx += 1) {\n const message = sliced[idx];\n scannedItems += 1;\n if (maxItemsScanned !== null && scannedItems > maxItemsScanned) {\n capHit = true;\n break mainLoop;\n }\n if (predicate && !predicate(message)) {\n continue;\n }\n collected.push(message);\n if (collected.length === pageSize) {\n const nextOffset = startIndex + idx + 1;\n midPageToken = encodeNextPageToken({\n skipToken: pageTokenUsed,\n offset: nextOffset,\n mode,\n });\n break mainLoop;\n }\n }\n\n currentSkipToken = graphPage.nextSkipToken;\n if (!currentSkipToken) {\n break;\n }\n }\n\n return {\n collected,\n midPageToken,\n nextSkipToken: lastNextSkipToken,\n capHit,\n };\n}\n"],"names":["buildClientPredicate","decodeNextPageToken","encodeNextPageToken","FIRST_PAGE_SKIP_TOKEN","buildQueryFilter","toGraphFilter","searchMessages","graph","opts","graphPlan","query","includeBody","pageSize","pageToken","maxPages","maxItemsScanned","logger","search","filter","requireBodyClientFilter","hasFullText","pageState","useClientFiltering","Boolean","predicate","requireBody","effectiveIncludeBody","info","hasSearch","hasFilter","undefined","forcedBody","result","fetchGraphPage","skipToken","messages","nextPageToken","nextSkipToken","searchResult","collectClientFilteredPages","startSkipToken","startOffset","offset","mode","text","Array","isArray","$all","console","log","collected","map","msg","id","capHit","midPageToken","length","fallbackFilter","trim","fallbackResult","params","request","api","top","Math","min","selectFields","select","join","response","get","value","nextLinkUrl","URL","searchParams","nextLink","hasNextPage","currentSkipToken","lastNextSkipToken","pagesFetched","scannedItems","mainLoop","pageTokenUsed","graphPage","pageItems","startIndex","sliced","slice","idx","message","push","nextOffset"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/email/querying/search-execution.ts"],"sourcesContent":["import type { Client } from '@microsoft/microsoft-graph-client';\nimport type { Message } from '@microsoft/microsoft-graph-types';\nimport type { OutlookQuery as QueryNode } from '../../schemas/outlook-query-schema.ts';\nimport type { Logger } from '../../types.ts';\nimport { buildClientPredicate } from './client-filter.ts';\nimport { decodeNextPageToken, encodeNextPageToken, FIRST_PAGE_SKIP_TOKEN } from './pagination-token.ts';\nimport { buildQueryFilter, toGraphFilter } from './query-builder.ts';\n\nexport interface OutlookSearchOptions {\n query?: QueryNode;\n limit?: number;\n includeBody?: boolean;\n maxPages?: number | null;\n maxItemsScanned?: number | null;\n pageSize?: number;\n pageToken?: string | undefined;\n logger: Logger;\n}\n\nexport interface OutlookSearchResult {\n messages: Message[];\n nextPageToken?: string | undefined;\n}\n\nexport async function searchMessages(graph: Client, opts: OutlookSearchOptions): Promise<OutlookSearchResult> {\n const { query, includeBody = false, pageSize = 50, pageToken, maxPages = null, maxItemsScanned = null, logger } = opts;\n\n const graphPlan = query\n ? toGraphFilter(query)\n : {\n search: null,\n filter: null,\n requireBodyClientFilter: false,\n hasFullText: false,\n };\n const pageState = decodeNextPageToken(pageToken);\n const useClientFiltering = Boolean(query && graphPlan.hasFullText);\n const predicate = useClientFiltering && query ? buildClientPredicate(query) : null;\n const requireBody = graphPlan.requireBodyClientFilter;\n const effectiveIncludeBody = includeBody || (requireBody && !includeBody);\n\n logger.info('Executing Outlook search', {\n hasSearch: !!graphPlan.search,\n hasFilter: !!graphPlan.filter,\n useClientFiltering,\n pageSize,\n includeBody: effectiveIncludeBody,\n pageToken: pageToken ? '[provided]' : undefined,\n forcedBody: requireBody && !includeBody,\n });\n\n if (!useClientFiltering) {\n const result = await fetchGraphPage(graph, {\n search: graphPlan.search ?? undefined,\n filter: graphPlan.filter ?? undefined,\n skipToken: pageState.skipToken,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n });\n return {\n messages: result.messages,\n nextPageToken: result.nextSkipToken,\n };\n }\n\n const searchResult = await collectClientFilteredPages({\n graph,\n search: graphPlan.search ?? undefined,\n filter: undefined,\n startSkipToken: pageState.skipToken,\n startOffset: pageState.offset,\n predicate,\n includeBody: effectiveIncludeBody,\n pageSize,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n mode: 'search',\n });\n\n if (searchResult.capHit) {\n return { messages: searchResult.collected };\n }\n if (searchResult.midPageToken) {\n return { messages: searchResult.collected, nextPageToken: searchResult.midPageToken };\n }\n if (searchResult.nextSkipToken) {\n return {\n messages: searchResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: searchResult.nextSkipToken, offset: 0, mode: 'search' }),\n };\n }\n if (searchResult.collected.length > 0) {\n return { messages: searchResult.collected };\n }\n\n if (predicate && query) {\n const fallbackFilter = buildQueryFilter(query).trim();\n if (fallbackFilter) {\n const fallbackResult = await collectClientFilteredPages({\n graph,\n filter: fallbackFilter,\n includeBody: effectiveIncludeBody,\n pageSize,\n predicate,\n logger,\n maxPages: maxPages ?? null,\n maxItemsScanned: maxItemsScanned ?? null,\n startSkipToken: undefined,\n startOffset: 0,\n mode: 'filter',\n });\n\n if (fallbackResult.capHit) {\n return { messages: fallbackResult.collected };\n }\n if (fallbackResult.midPageToken) {\n return { messages: fallbackResult.collected, nextPageToken: fallbackResult.midPageToken };\n }\n if (fallbackResult.nextSkipToken) {\n return {\n messages: fallbackResult.collected,\n nextPageToken: encodeNextPageToken({ skipToken: fallbackResult.nextSkipToken, offset: 0, mode: 'filter' }),\n };\n }\n if (fallbackResult.collected.length > 0) {\n return { messages: fallbackResult.collected };\n }\n }\n }\n\n return { messages: searchResult.collected };\n}\n\ninterface GraphPageParams {\n search?: string;\n filter?: string;\n skipToken?: string;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n}\n\nasync function fetchGraphPage(graph: Client, params: GraphPageParams): Promise<{ messages: Message[]; nextSkipToken?: string }> {\n const { search, filter, skipToken, includeBody, pageSize, logger } = params;\n let request = graph.api('/me/messages');\n\n if (search) {\n request = request.search(search);\n }\n if (filter) {\n request = request.filter(filter);\n }\n\n const top = Math.min(pageSize, 1000);\n request = request.top(top);\n\n const selectFields = includeBody ? ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'body', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'] : ['id', 'conversationId', 'receivedDateTime', 'subject', 'bodyPreview', 'from', 'toRecipients', 'ccRecipients', 'bccRecipients'];\n request = request.select(selectFields.join(','));\n\n if (skipToken && skipToken !== FIRST_PAGE_SKIP_TOKEN) {\n request = request.skipToken(skipToken);\n }\n\n logger.info('Fetching Outlook Graph page', {\n search: !!search,\n filter: !!filter,\n skipToken: skipToken ? '[provided]' : undefined,\n pageSize: top,\n });\n\n const response = await request.get();\n const messages: Message[] = response.value || [];\n let nextSkipToken: string | undefined;\n if (response['@odata.nextLink']) {\n try {\n const nextLinkUrl = new URL(response['@odata.nextLink']);\n nextSkipToken = nextLinkUrl.searchParams.get('$skiptoken') || undefined;\n } catch {\n logger.info('Failed to parse nextLink skipToken', { nextLink: response['@odata.nextLink'] });\n }\n }\n\n logger.info(`Graph page returned ${messages.length} messages`, {\n hasNextPage: !!nextSkipToken,\n });\n\n return { messages, nextSkipToken };\n}\n\ninterface CollectParams {\n graph: Client;\n search?: string;\n filter?: string;\n startSkipToken?: string;\n startOffset?: number;\n predicate: ((message: Message) => boolean) | null;\n includeBody: boolean;\n pageSize: number;\n logger: Logger;\n maxPages: number | null;\n maxItemsScanned: number | null;\n mode: 'search' | 'filter';\n}\n\ninterface CollectResult {\n collected: Message[];\n midPageToken?: string;\n nextSkipToken?: string;\n capHit: boolean;\n}\n\nasync function collectClientFilteredPages(params: CollectParams): Promise<CollectResult> {\n const { graph, search, filter, startSkipToken, startOffset = 0, predicate, includeBody, pageSize, logger, maxPages, maxItemsScanned, mode } = params;\n let currentSkipToken = startSkipToken;\n let offset = startOffset;\n const collected: Message[] = [];\n let midPageToken: string | undefined;\n let lastNextSkipToken: string | undefined;\n let capHit = false;\n let pagesFetched = 0;\n let scannedItems = 0;\n\n mainLoop: while (collected.length < pageSize) {\n if (maxPages !== null && pagesFetched >= maxPages) {\n capHit = true;\n break;\n }\n\n const pageTokenUsed = currentSkipToken;\n const graphPage = await fetchGraphPage(graph, {\n search,\n filter,\n skipToken: currentSkipToken,\n includeBody,\n pageSize,\n logger,\n });\n\n pagesFetched += 1;\n lastNextSkipToken = graphPage.nextSkipToken;\n const pageItems = graphPage.messages;\n if (!pageItems.length) {\n break;\n }\n\n const startIndex = offset;\n const sliced = startIndex > 0 ? pageItems.slice(startIndex) : pageItems;\n offset = 0;\n\n for (let idx = 0; idx < sliced.length; idx += 1) {\n const message = sliced[idx];\n scannedItems += 1;\n if (maxItemsScanned !== null && scannedItems > maxItemsScanned) {\n capHit = true;\n break mainLoop;\n }\n if (predicate && !predicate(message)) {\n continue;\n }\n collected.push(message);\n if (collected.length === pageSize) {\n const nextOffset = startIndex + idx + 1;\n midPageToken = encodeNextPageToken({\n skipToken: pageTokenUsed,\n offset: nextOffset,\n mode,\n });\n break mainLoop;\n }\n }\n\n currentSkipToken = graphPage.nextSkipToken;\n if (!currentSkipToken) {\n break;\n }\n }\n\n return {\n collected,\n midPageToken,\n nextSkipToken: lastNextSkipToken,\n capHit,\n };\n}\n"],"names":["buildClientPredicate","decodeNextPageToken","encodeNextPageToken","FIRST_PAGE_SKIP_TOKEN","buildQueryFilter","toGraphFilter","searchMessages","graph","opts","graphPlan","query","includeBody","pageSize","pageToken","maxPages","maxItemsScanned","logger","search","filter","requireBodyClientFilter","hasFullText","pageState","useClientFiltering","Boolean","predicate","requireBody","effectiveIncludeBody","info","hasSearch","hasFilter","undefined","forcedBody","result","fetchGraphPage","skipToken","messages","nextPageToken","nextSkipToken","searchResult","collectClientFilteredPages","startSkipToken","startOffset","offset","mode","capHit","collected","midPageToken","length","fallbackFilter","trim","fallbackResult","params","request","api","top","Math","min","selectFields","select","join","response","get","value","nextLinkUrl","URL","searchParams","nextLink","hasNextPage","currentSkipToken","lastNextSkipToken","pagesFetched","scannedItems","mainLoop","pageTokenUsed","graphPage","pageItems","startIndex","sliced","slice","idx","message","push","nextOffset"],"mappings":"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"}
|
|
@@ -129,7 +129,6 @@ async function handler({ query, pageSize = 50, pageToken, fields, shape = 'array
|
|
|
129
129
|
});
|
|
130
130
|
const durationMs = Date.now() - started;
|
|
131
131
|
const filteredItems = exec.items.map((item)=>filterFields(item, requestedFields));
|
|
132
|
-
console.log('HANDLER OUTPUT IDS', filteredItems.map((item)=>item.id));
|
|
133
132
|
logger.info('outlook.message.search returning', {
|
|
134
133
|
query,
|
|
135
134
|
pageSize,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { needsBody } from '../../email/querying/client-filter.ts';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema, parseOutlookQueryParameter } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseOutlookQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const needsBodyContent = needsBody(parsedQuery);\n const includeBody = requestedFields === 'all' || requestedFields.has('body') || needsBodyContent;\n\n logger.info('outlook.search called with', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n parsedQuery,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n console.log(\n 'HANDLER OUTPUT IDS',\n filteredItems.map((item) => item.id)\n );\n\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","createFieldsSchema","createPaginationSchema","createShapeSchema","filterFields","parseFields","toColumnarFormat","Client","ErrorCode","McpError","z","needsBody","executeQuery","executeOutlookQuery","OutlookQueryParameterSchema","parseOutlookQueryParameter","inputSchema","object","query","optional","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","defaultPageSize","maxPageSize","provider","shape","contentType","excludeThreadHistory","successObjectsBranchSchema","type","literal","items","array","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","pageSize","pageToken","extra","logger","parsedQuery","requestedFields","needsBodyContent","includeBody","has","info","undefined","graph","initWithMiddleware","authProvider","authContext","auth","started","Date","now","exec","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","durationMs","filteredItems","item","console","log","itemsLength","length","metadata","metadataObj","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","createTool"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/mcp-z/mcp-outlook/src/mcp/tools/message-search.ts"],"sourcesContent":["import { EMAIL_COMMON_PATTERNS, EMAIL_FIELD_DESCRIPTIONS, EMAIL_FIELDS, EmailContentTypeSchema, type EmailDetail, EmailDetailSchema, ExcludeThreadHistorySchema, extractCurrentMessageFromHtml, extractCurrentMessageFromHtmlToText } from '@mcp-z/email';\nimport type { EnrichedExtra } from '@mcp-z/oauth-microsoft';\nimport { schemas } from '@mcp-z/oauth-microsoft';\n\nconst { AuthRequiredBranchSchema } = schemas;\n\nimport { createFieldsSchema, createPaginationSchema, createShapeSchema, filterFields, parseFields, type ToolModule, toColumnarFormat } from '@mcp-z/server';\nimport { Client } from '@microsoft/microsoft-graph-client';\nimport type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';\nimport { type CallToolResult, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { needsBody } from '../../email/querying/client-filter.ts';\nimport { executeQuery as executeOutlookQuery } from '../../email/querying/execute-query.ts';\nimport { OutlookQueryParameterSchema, parseOutlookQueryParameter } from '../../schemas/outlook-query-schema.ts';\n\nconst inputSchema = z.object({\n query: OutlookQueryParameterSchema.optional().describe('Structured query object or JSON string for filtering messages. Use query-syntax prompt for reference and kqlQuery for KQL syntax.'),\n fields: createFieldsSchema({\n availableFields: EMAIL_FIELDS,\n fieldDescriptions: EMAIL_FIELD_DESCRIPTIONS,\n commonPatterns: EMAIL_COMMON_PATTERNS,\n resourceName: 'email message',\n }),\n ...createPaginationSchema({\n defaultPageSize: 50,\n maxPageSize: 500,\n provider: 'outlook',\n }).shape,\n shape: createShapeSchema(),\n contentType: EmailContentTypeSchema,\n excludeThreadHistory: ExcludeThreadHistorySchema,\n});\n\n// Success branch schemas for different shapes\nconst successObjectsBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('objects'),\n items: z.array(EmailDetailSchema).describe('Matching email messages'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\nconst successArraysBranchSchema = z.object({\n type: z.literal('success'),\n shape: z.literal('arrays'),\n columns: z.array(z.string()).describe('Column names in canonical order'),\n rows: z.array(z.array(z.unknown())).describe('Row data matching column order'),\n nextPageToken: z.string().optional().describe('Token for fetching next page of results'),\n});\n\n// Output schema with auth_required support\n// Using z.union instead of discriminatedUnion since we have two success branches with different shapes\nconst outputSchema = z.union([successObjectsBranchSchema, successArraysBranchSchema, AuthRequiredBranchSchema]);\n\nconst config = {\n description: 'Search Outlook messages using structured query objects with flexible field selection.',\n inputSchema: inputSchema,\n outputSchema: z.object({\n result: outputSchema,\n }),\n} as const;\n\nexport type Input = z.infer<typeof inputSchema>;\nexport type Output = z.infer<typeof outputSchema>;\n\nasync function handler({ query, pageSize = 50, pageToken, fields, shape = 'arrays', contentType, excludeThreadHistory }: Input, extra: EnrichedExtra): Promise<CallToolResult> {\n const logger = extra.logger;\n\n try {\n const parsedQuery = parseOutlookQueryParameter(query);\n const requestedFields = parseFields(fields, EMAIL_FIELDS);\n const needsBodyContent = needsBody(parsedQuery);\n const includeBody = requestedFields === 'all' || requestedFields.has('body') || needsBodyContent;\n\n logger.info('outlook.search called with', {\n query: parsedQuery,\n pageSize,\n pageToken: pageToken ? '[provided]' : undefined,\n fields: fields || 'all',\n includeBody,\n });\n\n const graph = Client.initWithMiddleware({\n authProvider: extra.authContext.auth,\n });\n const started = Date.now();\n const exec = await executeOutlookQuery(\n graph,\n parsedQuery,\n {\n logger,\n pageSize,\n ...(pageToken ? { pageToken } : {}),\n includeBody,\n limit: pageSize,\n },\n (m: unknown) => {\n const message = m as MicrosoftGraph.Message;\n const to = Array.isArray(message?.toRecipients)\n ? message.toRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const cc = Array.isArray(message?.ccRecipients)\n ? message.ccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const bcc = Array.isArray(message?.bccRecipients)\n ? message.bccRecipients\n .map((r: MicrosoftGraph.Recipient) => r?.emailAddress?.address)\n .filter(Boolean)\n .join(', ')\n : undefined;\n const fromAddr = message?.from?.emailAddress?.address ?? null;\n const fromName = message?.from?.emailAddress?.name ?? null;\n // Process body based on contentType and excludeThreadHistory options\n let bodyContent: string | undefined;\n if (includeBody && message?.body?.content) {\n const isHtml = message.body.contentType?.toLowerCase() === 'html';\n bodyContent = message.body.content;\n\n if (isHtml && excludeThreadHistory) {\n bodyContent = extractCurrentMessageFromHtml(bodyContent);\n }\n\n if (isHtml && contentType === 'text') {\n bodyContent = excludeThreadHistory ? extractCurrentMessageFromHtmlToText(bodyContent) : extractCurrentMessageFromHtmlToText(message.body.content);\n }\n }\n\n const mapped: Partial<EmailDetail> = {\n id: message?.id ?? undefined,\n subject: message?.subject ?? undefined,\n from: fromAddr ?? undefined,\n fromName: fromName ?? undefined,\n to,\n cc,\n bcc,\n date: message?.receivedDateTime ?? undefined,\n snippet: message?.bodyPreview ?? undefined,\n ...(bodyContent && { body: bodyContent, bodyContentType: contentType }),\n };\n return mapped;\n }\n );\n const durationMs = Date.now() - started;\n\n const filteredItems = exec.items.map((item) => filterFields(item, requestedFields));\n logger.info('outlook.message.search returning', {\n query,\n pageSize,\n itemsLength: filteredItems.length,\n fields: fields || 'all',\n });\n logger.info('outlook.message.search metrics', {\n durationMs,\n metadata: exec.metadata,\n });\n\n // Type-safe metadata access\n const metadataObj = exec.metadata as { nextPageToken?: string } | undefined;\n\n // Build result based on shape\n const result: Output =\n shape === 'arrays'\n ? {\n type: 'success' as const,\n shape: 'arrays' as const,\n ...toColumnarFormat(filteredItems, requestedFields, EMAIL_FIELDS),\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n }\n : {\n type: 'success' as const,\n shape: 'objects' as const,\n items: filteredItems,\n ...(metadataObj?.nextPageToken && { nextPageToken: metadataObj.nextPageToken }),\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result),\n },\n ],\n structuredContent: { result },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error('outlook.message.search error', { error: message });\n\n throw new McpError(ErrorCode.InternalError, `Error searching messages: ${message}`, {\n stack: error instanceof Error ? error.stack : undefined,\n });\n }\n}\n\nexport default function createTool() {\n return {\n name: 'message-search',\n config,\n handler,\n } satisfies ToolModule;\n}\n"],"names":["EMAIL_COMMON_PATTERNS","EMAIL_FIELD_DESCRIPTIONS","EMAIL_FIELDS","EmailContentTypeSchema","EmailDetailSchema","ExcludeThreadHistorySchema","extractCurrentMessageFromHtml","extractCurrentMessageFromHtmlToText","schemas","AuthRequiredBranchSchema","createFieldsSchema","createPaginationSchema","createShapeSchema","filterFields","parseFields","toColumnarFormat","Client","ErrorCode","McpError","z","needsBody","executeQuery","executeOutlookQuery","OutlookQueryParameterSchema","parseOutlookQueryParameter","inputSchema","object","query","optional","describe","fields","availableFields","fieldDescriptions","commonPatterns","resourceName","defaultPageSize","maxPageSize","provider","shape","contentType","excludeThreadHistory","successObjectsBranchSchema","type","literal","items","array","nextPageToken","string","successArraysBranchSchema","columns","rows","unknown","outputSchema","union","config","description","result","handler","pageSize","pageToken","extra","logger","parsedQuery","requestedFields","needsBodyContent","includeBody","has","info","undefined","graph","initWithMiddleware","authProvider","authContext","auth","started","Date","now","exec","limit","m","message","to","Array","isArray","toRecipients","map","r","emailAddress","address","filter","Boolean","join","cc","ccRecipients","bcc","bccRecipients","fromAddr","from","fromName","name","bodyContent","body","content","isHtml","toLowerCase","mapped","id","subject","date","receivedDateTime","snippet","bodyPreview","bodyContentType","durationMs","filteredItems","item","itemsLength","length","metadata","metadataObj","text","JSON","stringify","structuredContent","error","Error","String","InternalError","stack","createTool"],"mappings":"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"}
|