{"version":3,"sources":["../src/Lucene.ts"],"sourcesContent":["import {\n  DateTime,\n  entries,\n  Func,\n  ifDefined,\n  ifNotEmpty,\n  ifTrue,\n  isDefined,\n  isEmptyObject,\n  isFunction,\n  List,\n  on,\n  OneOrMore,\n  Optional,\n  RequireAtLeastOne,\n  toArray,\n  toList,\n} from '@thisisagile/easy';\nimport { toMongoType } from './Utils';\n\ntype FuzzyOptions = {\n  maxEdits: number;\n  prefixLength: number;\n  maxExpansions: number;\n};\n\nexport type Facet =\n  | { path: string; type: 'string'; numBuckets: number }\n  | { path: string; type: 'number'; boundaries: number[]; default?: string }\n  | { path: string; type: 'date'; boundaries: Date[]; default?: string };\n\nexport type Operator = Func<Optional<object>, string>;\nexport type Clause = object | Operator;\nexport type Clauses = Record<string, Clause>;\nexport type SearchDefinition = Record<\n  string,\n  (\n    v: string | number,\n    q?: Record<string, string | number>\n  ) => RequireAtLeastOne<{\n    should?: Clauses;\n    filter?: Clauses;\n    must?: Clauses;\n    mustNot?: Clauses;\n    sort?: Record<string, 1 | -1>;\n    facet?: Facet;\n  }>\n>;\n\ntype Compound = {\n  must: OneOrMore<Clauses>;\n  should: OneOrMore<Clauses>;\n  mustNot: OneOrMore<Clauses>;\n  filter: OneOrMore<Clauses>;\n};\n\nconst should = (query: Record<string, string | number>, def: SearchDefinition): Clauses[] => entries(query).mapDefined(([k, v]) => def[k]?.(v, query)?.should);\nconst must = (query: Record<string, string | number>, def: SearchDefinition): Clauses[] => entries(query).mapDefined(([k, v]) => def[k]?.(v, query)?.must);\nconst mustNot = (query: Record<string, string | number>, def: SearchDefinition): Clauses[] =>\n  entries(query).mapDefined(([k, v]) => def[k]?.(v, query)?.mustNot);\nconst filter = (query: Record<string, string | number>, def: SearchDefinition): Clauses[] => entries(query).mapDefined(([k, v]) => def[k]?.(v, query)?.filter);\n\nexport const lucene = {\n  clause: (c: Clauses) => entries(c).reduce((res, [k, v]) => res.add(isFunction(v) ? v(k) : v), toList()),\n  clauses: (cs: OneOrMore<Clauses>) => toArray(cs).flatMap(c => lucene.clause(c)),\n  compound: (query: Record<string, string | number>, def: SearchDefinition, wildcard = true): Partial<Compound> =>\n    ifNotEmpty(\n      entries({\n        should: should(query, def),\n        filter: filter(query, def),\n        mustNot: mustNot(query, def),\n        must: must(query, def),\n      }).filter(([_, v]) => v.length > 0),\n      e => e.reduce((res, [k, v]) => on(res, r => (r[k] = lucene.clauses(v))), should(query, def).length > 0 ? { minimumShouldMatch: 1 } : ({} as any)),\n      () =>\n        ifTrue(wildcard, () => ({\n          should: lucene.clauses([{ r: { exists: { path: 'id' } } }]),\n          minimumShouldMatch: 0,\n        }))\n    ),\n  search: (c: Partial<Compound>, index?: string) => ({\n    $search: {\n      ...ifDefined(index, { index }),\n      compound: entries(c).reduce((res, [k, v]) => on(res, r => (r[k] = lucene.clauses(v))), {} as any),\n    },\n  }),\n  searchWithDef: (query: Record<string, string | number>, options: SearchDefinition, count: 'total' | 'lowerBound' = 'total', index?: string) => {\n    const sort = entries(query)\n      .mapDefined(([k, v]) => options[k]?.(v, query)?.sort)\n      .first();\n    return {\n      $search: {\n        ...ifDefined(index, { index }),\n        compound: lucene.compound(query, options),\n        ...ifDefined(sort, { sort }),\n        count: { type: count },\n      },\n    };\n  },\n  searchMeta: (query: Record<string, string | number>, def: SearchDefinition, count: 'total' | 'lowerBound' = 'total', index?: string) => ({\n    $searchMeta: {\n      ...ifDefined(index, { index }),\n      ...ifTrue(\n        !isEmptyObject(lucene.facets(def)),\n        {\n          facet: {\n            operator: {\n              compound: lucene.compound(query, def),\n            },\n            facets: lucene.facets(def),\n          },\n        },\n        { compound: lucene.compound(query, def) }\n      ),\n      count: { type: count },\n    },\n  }),\n  exists: (): Operator => (path: string) => ({ exists: { path } }),\n  equals:\n    (value: unknown): Operator =>\n    (path: string) => ({ equals: { path, value: value === 1 } }),\n  text:\n    (value?: OneOrMore<unknown>, fuzzy?: Partial<FuzzyOptions>): Operator =>\n    (path: string) =>\n      ifDefined(value, v => ({\n        text: {\n          path: path === 'wildcard' ? { wildcard: '*' } : path,\n          query: v,\n          ...ifDefined(fuzzy, { fuzzy }),\n        },\n      })),\n  wildcard:\n    (value?: OneOrMore<unknown>, allowAnalyzedField = true): Operator =>\n    (path: string) => ({\n      wildcard: {\n        path: path === 'wildcard' ? { wildcard: '*' } : path,\n        query: ifDefined(value, value, '*'),\n        allowAnalyzedField,\n      },\n    }),\n  lt:\n    (value: unknown): Operator =>\n    (path: string) =>\n      ifDefined(value, lt => ({ range: { path, lt } })),\n  lte:\n    (value: unknown): Operator =>\n    (path: string) =>\n      ifDefined(value, lte => ({ range: { path, lte } })),\n  gt:\n    (value: unknown): Operator =>\n    (path: string) =>\n      ifDefined(value, gt => ({ range: { path, gt } })),\n  gte:\n    (value: unknown): Operator =>\n    (path: string) =>\n      ifDefined(value, gte => ({ range: { path, gte } })),\n  after: (date: unknown): Operator => lucene.gte(toMongoType(date)),\n  before: (date: unknown): Operator => lucene.lt(toMongoType(date)),\n  between:\n    (after: unknown, before: unknown, includeLimit?: boolean): Operator =>\n    (path: string) => {\n      const upperLimit = includeLimit ? { lte: toMongoType(before) } : { lt: toMongoType(before) };\n      return {\n        range: {\n          path,\n          gte: toMongoType(after),\n          ...upperLimit,\n        },\n      };\n    },\n  facets: (def: SearchDefinition) =>\n    entries(def)\n      .filter(([k, v]) => isDefined(v(k)?.facet))\n      .map(([k, v]) => ({ [k]: v(k)?.facet }))\n      .reduce((acc, v) => ({ ...acc, ...v }), {}),\n  facet: {\n    string: (path: string, numBuckets = 1000): Facet => ({\n      type: 'string',\n      path,\n      numBuckets,\n    }),\n    number: (path: string, boundaries: List<number>, alt?: string): Facet => ({\n      type: 'number',\n      path,\n      boundaries,\n      ...ifDefined(alt, a => ({ default: a })),\n    }),\n    date: (path: string, boundaries: List<DateTime>, alt?: string): Facet => ({\n      type: 'date',\n      path,\n      boundaries: boundaries.mapDefined(b => b.toDate()),\n      ...ifDefined(alt, a => ({ default: a })),\n    }),\n  },\n};\n"],"mappings":"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","names":[]}