{"version":3,"file":"prepareQueryObjects-uA10ZpZX.mjs","names":[],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/parserUtils.ts","../src/utils/generateID.ts","../src/utils/prepareQueryObjects.ts"],"sourcesContent":["import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n  const fullField = toFullOption(field);\n  const fullFieldToCompare = toFullOption(fieldToCompare);\n  if (fullField.value === fullFieldToCompare.value) {\n    return false;\n  }\n  if (typeof fullField.comparator === 'string') {\n    return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n  }\n  return (\n    fullField.comparator?.(fullFieldToCompare, operator) ??\n    /* v8 ignore start -- @preserve */ false /* v8 ignore stop -- @preserve */\n  );\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n  /** The field in question. */\n  field: FullField,\n  /** The full {@link FullField} list to be filtered. */\n  fields: OptionList<FullField>,\n  operator: string\n):\n  | FullField[]\n  | {\n      options: WithUnknownIndex<FullField>[];\n      label: string;\n    }[] => {\n  if (!field.comparator) {\n    const filterOutSameField = (f: FullField) =>\n      (f.value ?? /* v8 ignore start -- @preserve */ f.name) /* v8 ignore stop -- @preserve */ !==\n      (field.value ??\n        /* v8 ignore start -- @preserve */ field.name) /* v8 ignore stop -- @preserve */;\n    if (isFlexibleOptionGroupArray(fields)) {\n      return fields.map(og => ({\n        ...og,\n        options: og.options.filter(v => filterOutSameField(v)),\n      }));\n    }\n    return fields.filter(v => filterOutSameField(v));\n  }\n\n  if (isFlexibleOptionGroupArray(fields)) {\n    return fields\n      .map(og => ({\n        ...og,\n        options: og.options.filter(f => filterByComparator(field, operator, f)),\n      }))\n      .filter(og => og.options.length > 0);\n  }\n\n  return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n  FullField,\n  GetOptionIdentifierType,\n  ValueSourceFlexibleOptions,\n  ValueSourceFullOptions,\n  ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n  { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n  name: 'name',\n  value: 'name',\n  valueSources: null,\n  label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n  fieldData: F,\n  operator: string,\n  getValueSources?: (\n    field: GetOptionIdentifierType<F>,\n    operator: O,\n    misc: { fieldData: F }\n  ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n  // TypeScript doesn't allow it directly, but in practice\n  // `fieldData` can end up being undefined or null. The nullish\n  // coalescing assignment below avoids errors like\n  // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n  const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n  let valueSourcesNEW:\n    | false\n    | ValueSources\n    | ValueSourceFlexibleOptions\n    | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n  if (typeof valueSourcesNEW === 'function') {\n    valueSourcesNEW = valueSourcesNEW(operator as O);\n  }\n\n  if (!valueSourcesNEW && getValueSources) {\n    valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n      fieldData: fd as F,\n    });\n  }\n\n  if (!valueSourcesNEW) {\n    return defaultValueSourcesArray;\n  }\n\n  if (isFlexibleOptionArray(valueSourcesNEW)) {\n    return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n  }\n\n  return valueSourcesNEW.map(\n    vs =>\n      defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n        name: vs,\n        value: vs,\n        label: vs,\n      }\n  ) as ValueSourceFullOptions;\n};\n","import type {\n  DefaultOperatorName,\n  FullField,\n  FullOption,\n  OptionList,\n  ValueSource,\n  ValueSourceFlexibleOptions,\n  ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isFlexibleOptionArray, toFlatOptionArray, toFullOption } from './optGroupUtils';\n\nexport const getFieldsArray = (\n  fields?: OptionList<FullField> | Record<string, FullField>\n): FullOption[] => {\n  const fieldsArray = fields\n    ? Array.isArray(fields)\n      ? fields\n      : Object.keys(fields)\n          .map(fld => Object.assign({}, fields[fld], { name: fld }))\n          // oxlint-disable-next-line no-array-sort\n          .sort((a, b) => a.label.localeCompare(b.label))\n    : [];\n  return toFlatOptionArray(fieldsArray);\n};\n\nexport function fieldIsValidUtil(params: {\n  fieldsFlat: FullField[];\n  getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n  fieldName: string;\n  operator: DefaultOperatorName;\n  subordinateFieldName?: string;\n}): boolean {\n  const { fieldsFlat, fieldName, operator, subordinateFieldName, getValueSources } = params;\n\n  const vsIncludes = (vs: ValueSource) => {\n    const vss = getValueSourcesUtil(primaryField, operator, getValueSources);\n    return isFlexibleOptionArray(vss) && vss.some(vso => vso.value === vs || vso.name === vs);\n  };\n\n  // If fields option was an empty array or undefined, then all identifiers\n  // are considered valid.\n  if (fieldsFlat.length === 0) return true;\n\n  let valid = false;\n\n  const primaryField = toFullOption(fieldsFlat.find(ff => ff.name === fieldName)!);\n  if (primaryField) {\n    valid = !(\n      !subordinateFieldName &&\n      operator !== 'notNull' &&\n      operator !== 'null' &&\n      !vsIncludes('value')\n    );\n\n    if (valid && !!subordinateFieldName) {\n      if (vsIncludes('field') && fieldName !== subordinateFieldName) {\n        const validSubordinateFields = filterFieldsByComparator(\n          primaryField,\n          fieldsFlat,\n          operator\n        ) as FullField[];\n        if (!validSubordinateFields.some(vsf => vsf.name === subordinateFieldName)) {\n          valid = false;\n        }\n      } else {\n        valid = false;\n      }\n    }\n  }\n\n  return valid;\n}\n","/* v8 ignore file -- this is fine */\n\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\nexport const uuidV4regex: RegExp =\n  /^[\\da-f]{8}-[\\da-f]{4}-4[\\da-f]{3}-[89ab][\\da-f]{3}-[\\da-f]{12}$/i;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// v8 ignore next\nexport let generateID = (): UUID =>\n  '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n    (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n      .toString(16)\n      .padStart(4, '0')\n  ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// v8 ignore else\nif (cryptoModule) {\n  // v8 ignore else\n  if (typeof cryptoModule.randomUUID === 'function') {\n    generateID = () => cryptoModule.randomUUID();\n  } else if (typeof cryptoModule.getRandomValues === 'function') {\n    // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n    // available in secure contexts (server-side, https, etc.). `generateID`\n    // doesn't really need to be cryptographically secure, it only needs a\n    // fairly low chance of collisions. We fall back to the always-available\n    // `getRandomValues` here (while still generating a valid v4 UUID) when\n    // `randomUUID` is not available.\n    const position19vals = '89ab';\n    const container = new Uint32Array(32);\n\n    generateID = () => {\n      cryptoModule.getRandomValues(container);\n      let id = (container[0] % 16).toString(16);\n      for (let i = 1; i < 32; i++) {\n        if (i === 12) {\n          id = `${id}${'4'}`;\n        } else if (i === 16) {\n          id = `${id}${position19vals[container[17] % 4]}`;\n        } else {\n          id = `${id}${(container[i] % 16).toString(16)}`;\n        }\n\n        if (i === 7 || i === 11 || i === 15 || i === 19) {\n          id = `${id}${'-'}`;\n        }\n      }\n      return id as UUID;\n    };\n  }\n}\n","import type {\n  RuleGroupArray,\n  RuleGroupICArray,\n  RuleGroupType,\n  RuleGroupTypeAny,\n  RuleGroupTypeIC,\n  RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n  idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n  rule: RuleType,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RuleType => {\n  const needsId = !rule.id;\n  const hasMatchMode = processMatchMode(rule);\n\n  if (!needsId && !hasMatchMode) {\n    return rule;\n  }\n\n  return {\n    ...rule,\n    ...(needsId && { id: idGenerator() }),\n    ...(hasMatchMode && { value: prepareRuleGroup(rule.value, { idGenerator }) }),\n  };\n};\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n  queryObject: RG,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RG => {\n  const needsId = !queryObject.id;\n  let rulesChanged = false;\n  const newRules: (RuleGroupTypeAny | RuleType | string)[] = [];\n\n  for (let i = 0; i < queryObject.rules.length; i++) {\n    const r = queryObject.rules[i];\n    if (typeof r === 'string') {\n      newRules.push(r);\n    } else {\n      const prepared = isRuleGroup(r)\n        ? prepareRuleGroup(r, { idGenerator })\n        : prepareRule(r, { idGenerator });\n      newRules.push(prepared);\n      if (prepared !== r) {\n        rulesChanged = true;\n      }\n    }\n  }\n\n  if (!needsId && !rulesChanged) {\n    return queryObject;\n  }\n\n  return {\n    ...queryObject,\n    ...(needsId && { id: idGenerator() }),\n    rules: newRules as RuleGroupArray | RuleGroupICArray,\n  };\n};\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = (\n  rg: RuleGroupTypeAny | RuleType,\n  { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n  isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n"],"mappings":"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"}