{"version":3,"file":"parseMongoDB.mjs","names":[],"sources":["../src/utils/parseMongoDB/utils.ts","../src/utils/parseMongoDB/parseMongoDB.ts"],"sourcesContent":["import type { DefaultOperatorName } from '../../types';\nimport type { MongoDbSupportedOperators } from './types';\n\nexport const getRegExStr = (re: string | RegExp): string =>\n  typeof re === 'string' ? re : re.source;\n\n// oxlint-disable-next-line typescript/no-explicit-any\nexport const isPrimitive = (v: any): v is string | number | boolean =>\n  typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean';\n\nexport const mongoDbToRqbOperatorMap: Partial<\n  Record<MongoDbSupportedOperators, DefaultOperatorName>\n> = {\n  $eq: '=',\n  $ne: '!=',\n  $gt: '>',\n  $gte: '>=',\n  $lt: '<',\n  $lte: '<=',\n} satisfies Partial<Record<MongoDbSupportedOperators, DefaultOperatorName>>;\n","import type { Except } from 'type-fest';\nimport { defaultOperatorNegationMap } from '../../defaults';\nimport type {\n  DefaultOperatorName,\n  DefaultRuleGroupType,\n  DefaultRuleGroupTypeAny,\n  DefaultRuleGroupTypeIC,\n  DefaultRuleType,\n  RuleGroupType,\n  RuleType,\n} from '../../types';\nimport type { ParserCommonOptions } from '../../types/import';\nimport { joinWith } from '../arrayUtils';\nimport { convertToIC } from '../convertQuery';\nimport { isRuleGroupType } from '../isRuleGroup';\nimport { isPojo } from '../misc';\nimport { objectKeys } from '../objectUtils';\nimport { fieldIsValidUtil, getFieldsArray } from '../parserUtils';\nimport { prepareRuleGroup } from '../prepareQueryObjects';\nimport type { MongoDbSupportedOperators } from './types';\nimport { getRegExStr, isPrimitive, mongoDbToRqbOperatorMap } from './utils';\n\n/**\n * Options object for {@link parseMongoDB}.\n */\nexport interface ParseMongoDbOptions extends ParserCommonOptions {\n  /**\n   * When `true`, MongoDB rules in the form of `{ fieldName: { $not: { <...rule> } } }`\n   * will be parsed into a rule group with the `not` attribute set to `true`. By default\n   * (i.e., when this attribute is `false`), such \"`$not`\" rules will be parsed into a\n   * rule with a negated operator.\n   *\n   * For example, with `preventOperatorNegation` set to `true`, a MongoDB rule like this...\n   *\n   * ```ts\n   * { fieldName: { $not: { $eq: 1 } } }\n   * ```\n   *\n   * ...would yield a rule group like this:\n   *\n   * ```ts\n   * {\n   *   combinator: 'and',\n   *   not: true,\n   *   rules: [{ field: 'fieldName', operator: '=', value: 1 }]\n   * }\n   * ```\n   *\n   * By default, the same MongoDB rule would yield a rule like this:\n   *\n   * ```ts\n   * { field: 'fieldName', operator: '!=', value: 1 }\n   * //              negated operator ^\n   * ```\n   *\n   * @default false\n   */\n  preventOperatorNegation?: boolean;\n  /**\n   * Map of additional operators to their respective processing functions. Operators\n   * must begin with `\"$\"`. Processing functions should return either a {@link index!RuleType RuleType}\n   * or {@link index!RuleGroupType RuleGroupType}.\n   *\n   * (The functions should _not_ return {@link index!RuleGroupTypeIC RuleGroupTypeIC}, even if using independent\n   * combinators. If the `independentCombinators` option is `true`, `parseMongoDB`\n   * will convert the final query to {@link index!RuleGroupTypeIC RuleGroupTypeIC} before returning it.)\n   *\n   * @default {}\n   */\n  additionalOperators?: Record<\n    `$${string}`,\n    (\n      field: string,\n      operator: string,\n      // oxlint-disable-next-line typescript/no-explicit-any\n      value: any,\n      options: ParserCommonOptions\n    ) => RuleType | RuleGroupType\n  >;\n}\n\nconst emptyRuleGroup: DefaultRuleGroupType = { combinator: 'and', rules: [] };\n\n/**\n * Converts a MongoDB query object or parseable string into a query suitable\n * for the {@link index!QueryBuilder QueryBuilder} component's `query` or `defaultQuery` props\n * ({@link index!DefaultRuleGroupType DefaultRuleGroupType}).\n */\n// oxlint-disable-next-line typescript/no-explicit-any\nfunction parseMongoDB(mongoDbRules: string | Record<string, any>): DefaultRuleGroupType;\n/**\n * Converts a MongoDB query object or parseable string into a query suitable\n * for the {@link index!QueryBuilder QueryBuilder} component's `query` or `defaultQuery` props\n * ({@link index!DefaultRuleGroupType DefaultRuleGroupType}).\n */\nfunction parseMongoDB(\n  // oxlint-disable-next-line typescript/no-explicit-any\n  mongoDbRules: string | Record<string, any>,\n  options: Except<ParseMongoDbOptions, 'independentCombinators'> & {\n    independentCombinators?: false;\n  }\n): DefaultRuleGroupType;\n/**\n * Converts a MongoDB query object or parseable string into a query suitable\n * for the {@link index!QueryBuilder QueryBuilder} component's `query` or `defaultQuery` props\n * ({@link index!DefaultRuleGroupTypeIC DefaultRuleGroupTypeIC}).\n */\nfunction parseMongoDB(\n  // oxlint-disable-next-line typescript/no-explicit-any\n  mongoDbRules: string | Record<string, any>,\n  options: Except<ParseMongoDbOptions, 'independentCombinators'> & {\n    independentCombinators: true;\n  }\n): DefaultRuleGroupTypeIC;\nfunction parseMongoDB(\n  // oxlint-disable-next-line typescript/no-explicit-any\n  mongoDbRules: string | Record<string, any>,\n  options: ParseMongoDbOptions = {}\n): DefaultRuleGroupTypeAny {\n  const listsAsArrays = !!options.listsAsArrays;\n  const fieldsFlat = getFieldsArray(options.fields);\n  const getValueSources = options.getValueSources;\n  const additionalOperators = options.additionalOperators ?? {};\n  const preventOperatorNegation = !!options.preventOperatorNegation;\n  const { additionalOperators: _ao, ...otherOptions } = options;\n\n  const fieldIsValid = (\n    fieldName: string,\n    operator: DefaultOperatorName,\n    subordinateFieldName?: string\n  ) =>\n    fieldIsValidUtil({\n      fieldName,\n      fieldsFlat,\n      operator,\n      subordinateFieldName,\n      getValueSources,\n    });\n\n  function processMongoDbQueryBooleanOperator(\n    field: string,\n    mdbOperator: MongoDbSupportedOperators,\n    // oxlint-disable-next-line typescript/no-explicit-any\n    keyValue: any\n  ): DefaultRuleType | false {\n    let operator: DefaultOperatorName = '=';\n    // oxlint-disable-next-line typescript/no-explicit-any\n    let value: any = '';\n\n    // v8 ignore else\n    if (\n      mdbOperator === '$eq' ||\n      mdbOperator === '$ne' ||\n      mdbOperator === '$gt' ||\n      mdbOperator === '$gte' ||\n      mdbOperator === '$lt' ||\n      mdbOperator === '$lte'\n    ) {\n      if (mdbOperator === '$ne' && keyValue === null) {\n        if (fieldIsValid(field, 'notNull')) {\n          return { field, operator: 'notNull', value: null };\n        }\n      } else {\n        operator = mongoDbToRqbOperatorMap[mdbOperator]!;\n        if (fieldIsValid(field, operator)) {\n          return { field, operator, value: keyValue };\n        }\n      }\n    } else if (mdbOperator === '$regex' && /^[^$^]$|^[^^].*[^$]$/.test(getRegExStr(keyValue))) {\n      if (fieldIsValid(field, 'contains')) {\n        return {\n          field,\n          operator: 'contains',\n          value: getRegExStr(keyValue),\n        };\n      }\n    } else if (mdbOperator === '$regex' && /^\\^.*[^$]/.test(getRegExStr(keyValue))) {\n      if (fieldIsValid(field, 'beginsWith')) {\n        return {\n          field,\n          operator: 'beginsWith',\n          value: getRegExStr(keyValue).replace(/^\\^/, ''),\n        };\n      }\n    } else if (mdbOperator === '$regex' && /[^^].*\\$/.test(getRegExStr(keyValue))) {\n      if (fieldIsValid(field, 'endsWith')) {\n        return {\n          field,\n          operator: 'endsWith',\n          value: getRegExStr(keyValue).replace(/\\$$/, ''),\n        };\n      }\n    } else if (mdbOperator === '$in' && Array.isArray(keyValue)) {\n      if (fieldIsValid(field, 'in')) {\n        value = listsAsArrays\n          ? keyValue\n          : joinWith(\n              keyValue.map(v => `${v}`),\n              ','\n            );\n        return { field, operator: 'in', value };\n      }\n    } else if (mdbOperator === '$nin' && Array.isArray(keyValue) && fieldIsValid(field, 'notIn')) {\n      value = listsAsArrays\n        ? keyValue\n        : joinWith(\n            keyValue.map(v => `${v}`),\n            ','\n          );\n      return { field, operator: 'notIn', value };\n    }\n\n    return false;\n  }\n\n  function processMongoDbQueryObjectKey(\n    key: string,\n    // oxlint-disable-next-line typescript/no-explicit-any\n    keyValue: any\n  ): DefaultRuleType | DefaultRuleGroupType | false {\n    let field = '';\n\n    // v8 ignore else\n    if (key === '$and') {\n      if (!Array.isArray(keyValue) || keyValue.length === 0 || !keyValue.every(v => isPojo(v))) {\n        return false;\n      }\n\n      // Check if this should result in a \"between\" clause\n      if (keyValue.length === 2 && keyValue.every(kv => objectKeys(kv).length === 1)) {\n        const [rule1, rule2] = keyValue;\n        const [ruleKey1, ruleKey2] = keyValue.map(kv => objectKeys(kv)[0]);\n        if (\n          ruleKey1 === ruleKey2 &&\n          isPojo(rule1[ruleKey1]) &&\n          objectKeys(rule1[ruleKey1]).length === 1 &&\n          isPojo(rule2[ruleKey2]) &&\n          objectKeys(rule2[ruleKey2]).length === 1 &&\n          (('$gte' in rule1[ruleKey1] &&\n            '$lte' in rule2[ruleKey2] &&\n            rule2[ruleKey2].$lte >= rule1[ruleKey1].$gte) ||\n            ('$lte' in rule1[ruleKey1] &&\n              '$gte' in rule2[ruleKey2] &&\n              rule1[ruleKey1].$lte >= rule2[ruleKey2].$gte))\n        ) {\n          const [val1, val2] = [\n            rule1[ruleKey1].$gte ?? rule1[ruleKey1].$lte,\n            rule2[ruleKey2].$lte ?? rule2[ruleKey2].$gte,\n          ];\n          let value = listsAsArrays ? [val1, val2] : joinWith([val1, val2], ',');\n          if (val1 > val2) {\n            value = listsAsArrays ? [val2, val1] : joinWith([val2, val1], ',');\n          }\n          return { field: ruleKey1, operator: 'between', value };\n        }\n      }\n\n      const rules = keyValue.map(l => processMongoDbQueryObject(l)).filter(Boolean) as (\n        | DefaultRuleType\n        | DefaultRuleGroupType\n      )[];\n\n      return rules.length > 0 ? { combinator: 'and', rules } : false;\n    } else if (key === '$or') {\n      if (!Array.isArray(keyValue) || keyValue.length === 0 || !keyValue.every(v => isPojo(v))) {\n        return false;\n      }\n\n      // Check if this should result in \"notBetween\"\n      if (keyValue.length === 2 && keyValue.every(kv => objectKeys(kv).length === 1)) {\n        const [rule1, rule2] = keyValue;\n        const [ruleKey1, ruleKey2] = keyValue.map(kv => objectKeys(kv)[0]);\n        if (\n          ruleKey1 === ruleKey2 &&\n          isPojo(rule1[ruleKey1]) &&\n          objectKeys(rule1[ruleKey1]).length === 1 &&\n          isPojo(rule2[ruleKey2]) &&\n          objectKeys(rule2[ruleKey2]).length === 1 &&\n          (('$gt' in rule1[ruleKey1] &&\n            '$lt' in rule2[ruleKey2] &&\n            rule1[ruleKey1].$gt >= rule2[ruleKey2].$lt) ||\n            ('$lt' in rule1[ruleKey1] &&\n              '$gt' in rule2[ruleKey2] &&\n              rule2[ruleKey2].$gt >= rule1[ruleKey1].$lt))\n        ) {\n          const [val1, val2] = [\n            rule1[ruleKey1].$gt ?? rule1[ruleKey1].$lt,\n            rule2[ruleKey2].$lt ?? rule2[ruleKey2].$gt,\n          ];\n          let value = listsAsArrays ? [val1, val2] : `${val1},${val2}`;\n          if (val1 > val2) {\n            value = listsAsArrays ? [val2, val1] : `${val2},${val1}`;\n          }\n          return { field: ruleKey1, operator: 'notBetween', value };\n        }\n      }\n\n      const rules = keyValue.map(l => processMongoDbQueryObject(l)).filter(Boolean) as (\n        | DefaultRuleType\n        | DefaultRuleGroupType\n      )[];\n\n      return rules.length > 0 ? { combinator: 'or', rules } : false;\n    } else if (key === '$not' && isPojo(keyValue)) {\n      const ruleOrGroup = processMongoDbQueryObject(keyValue);\n      if (ruleOrGroup) {\n        if (isRuleGroupType(ruleOrGroup)) {\n          return ruleOrGroup.not\n            ? { combinator: 'and', rules: [ruleOrGroup], not: true }\n            : { ...ruleOrGroup, not: true };\n        }\n        return preventOperatorNegation\n          ? { combinator: 'and', rules: [ruleOrGroup], not: true }\n          : { ...ruleOrGroup, operator: defaultOperatorNegationMap[ruleOrGroup.operator] };\n      }\n      return false;\n    } else if (key === '$expr') {\n      const op = objectKeys(keyValue)[0] as MongoDbSupportedOperators;\n      if (\n        /^\\$(eq|gte?|lte?|n?in)$/.test(op) &&\n        Array.isArray(keyValue[op]) &&\n        keyValue[op].length === 2 &&\n        typeof keyValue[op][0] === 'string' &&\n        keyValue[op][0].startsWith('$')\n      ) {\n        field = keyValue[op][0].replace(/^\\$/, '');\n        const val = keyValue[op][1];\n        if (\n          (typeof val === 'string' && val.startsWith('$')) ||\n          (Array.isArray(val) &&\n            val.every(v => typeof v === 'string') &&\n            val.every(v => v.startsWith('$')))\n        ) {\n          const valForProcessing = Array.isArray(val)\n            ? val.map(v => v.replace(/^\\$/, ''))\n            : val.replace(/^\\$/, '');\n          const tempRule = processMongoDbQueryBooleanOperator(field, op, valForProcessing);\n          if (tempRule) {\n            if (\n              typeof tempRule.value === 'string' &&\n              !fieldIsValid(field, tempRule.operator, tempRule.value)\n            ) {\n              return false;\n            }\n            return { ...tempRule, valueSource: 'field' };\n          }\n        }\n        return processMongoDbQueryBooleanOperator(field, op, keyValue[op][1]);\n      }\n    } else if (/^[^$]/.test(key)) {\n      field = key;\n\n      if (isPrimitive(keyValue)) {\n        if (fieldIsValid(field, '=')) {\n          return { field, operator: '=', value: keyValue };\n        }\n      } else if (keyValue === null) {\n        if (fieldIsValid(field, 'null')) {\n          return { field, operator: 'null', value: keyValue };\n        }\n      } else if (isPojo(keyValue)) {\n        let betweenRule: DefaultRuleType | false = false;\n        let notRule: DefaultRuleType | DefaultRuleGroupType | false = false;\n        const additionalOpKeys = objectKeys(additionalOperators).map(o => o.replace(/^\\$/, ''));\n        const allOps = ['eq', 'ne', 'gte?', 'lte?', 'n?in', 'regex', 'not', ...additionalOpKeys];\n        const acceptedOpsRegExp = new RegExp(`^\\\\$(${allOps.join('|')})$`);\n\n        const operators = objectKeys(keyValue)\n          .filter(o => acceptedOpsRegExp.test(o))\n          // oxlint-disable-next-line no-array-sort\n          .sort() as MongoDbSupportedOperators[];\n\n        if (operators.length === 0) {\n          return false;\n        }\n\n        if ('$not' in keyValue && isPojo(keyValue.$not)) {\n          const invertedNotRule = processMongoDbQueryObject({ [field]: keyValue.$not });\n          if (invertedNotRule) {\n            if (isRuleGroupType(invertedNotRule)) {\n              notRule = { ...invertedNotRule, not: true };\n            } else {\n              notRule = preventOperatorNegation\n                ? { combinator: 'and', rules: [invertedNotRule], not: true }\n                : {\n                    ...invertedNotRule,\n                    operator: defaultOperatorNegationMap[invertedNotRule.operator],\n                  };\n            }\n          }\n        }\n\n        if ('$gte' in keyValue && '$lte' in keyValue) {\n          // This is (at least) a compact \"between\" clause\n          betweenRule = {\n            field,\n            operator: 'between',\n            value: listsAsArrays\n              ? [keyValue.$gte, keyValue.$lte]\n              : `${keyValue.$gte},${keyValue.$lte}`,\n          };\n        }\n\n        const rules = operators\n          // filter out $not\n          .filter(op => !(notRule && op === '$not'))\n          // filter out $gte and $lte if they were both present\n          .filter(op => !(betweenRule && (op === '$gte' || op === '$lte')))\n          .map(op =>\n            op in additionalOperators && typeof additionalOperators[op] === 'function'\n              ? additionalOperators[op](field, op, keyValue[op], otherOptions)\n              : processMongoDbQueryBooleanOperator(field, op, keyValue[op])\n          )\n          .filter(Boolean) as (DefaultRuleGroupType | DefaultRuleType)[];\n\n        if (notRule) {\n          rules.unshift(notRule);\n        }\n\n        if (betweenRule) {\n          rules.unshift(betweenRule);\n        }\n\n        if (rules.length === 0) {\n          return false;\n        }\n        if (rules.length === 1) {\n          return rules[0];\n        }\n        return { combinator: 'and', rules };\n      }\n    }\n\n    return false;\n  }\n\n  function processMongoDbQueryObject(\n    // oxlint-disable-next-line typescript/no-explicit-any\n    mongoDbQueryObject: Record<string, any>\n  ): DefaultRuleGroupType | DefaultRuleType | false {\n    const rules = objectKeys(mongoDbQueryObject)\n      .map(k => processMongoDbQueryObjectKey(k, mongoDbQueryObject[k]))\n      .filter(Boolean) as DefaultRuleGroupType[];\n    return rules.length === 1 ? rules[0] : rules.length > 1 ? { combinator: 'and', rules } : false;\n  }\n\n  const prepare = options.generateIDs ? prepareRuleGroup : <T>(g: T) => g;\n\n  let mongoDbPOJO = mongoDbRules;\n  if (typeof mongoDbRules === 'string') {\n    try {\n      mongoDbPOJO = JSON.parse(mongoDbRules);\n    } catch {\n      return prepare(emptyRuleGroup);\n    }\n  }\n\n  // Bail if the mongoDbPOJO is not actually a POJO\n  if (!isPojo(mongoDbPOJO)) {\n    return prepare(emptyRuleGroup);\n  }\n\n  const result = processMongoDbQueryObject(mongoDbPOJO);\n  const finalQuery: DefaultRuleGroupType = result\n    ? isRuleGroupType(result)\n      ? result\n      : { combinator: 'and', rules: [result] }\n    : emptyRuleGroup;\n  return prepare(options.independentCombinators ? convertToIC(finalQuery) : finalQuery);\n}\n\nexport { parseMongoDB };\n"],"mappings":"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"}