{"version":3,"file":"prepareQueryObjects-Dmyf3Wi_.mjs","names":[],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/generateID.ts","../src/utils/getValueSourcesUtil.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","/* 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  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);\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  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\n/**\n * Resolves the query a query builder should render from the available sources, in precedence\n * order: the controlled `query`, then whatever is already in the store, then the uncontrolled\n * `defaultQuery`, then a freshly created empty group.\n *\n * The result is prepared with {@link prepareRuleGroup} unless it already has an `id`, which is\n * taken to mean it has been prepared before—most often because the caller is passing back the\n * object it received from `onQueryChange`.\n *\n * @group Query Tools\n */\nexport const resolveCandidateQuery = <RG extends RuleGroupTypeAny>(\n  sources: {\n    query?: RG;\n    storeQuery?: RG;\n    defaultQuery?: RG;\n    fallbackQuery: RG;\n  },\n  options?: { idGenerator?: () => string }\n): RG => {\n  const candidateQuery =\n    sources.query ?? sources.storeQuery ?? sources.defaultQuery ?? sources.fallbackQuery;\n\n  return candidateQuery.id ? candidateQuery : prepareRuleGroup(candidateQuery, options);\n};\n"],"mappings":";;;AAGA,MAAM,sBAAsB,OAAkB,UAAkB,mBAA8B;CAC5F,MAAM,YAAY,aAAa,KAAK;CACpC,MAAM,qBAAqB,aAAa,cAAc;CACtD,IAAI,UAAU,UAAU,mBAAmB,OACzC,OAAO;CAET,IAAI,OAAO,UAAU,eAAe,UAClC,OAAO,UAAU,UAAU,gBAAgB,mBAAmB,UAAU;CAE1E,OACE,UAAU,aAAa,oBAAoB,QAAQ;oCAChB;AAEvC;;;;;;;;;;;;AAaA,MAAa,4BAEX,OAEA,QACA,aAMS;CACT,IAAI,CAAC,MAAM,YAAY;EACrB,MAAM,sBAAsB,OACzB,EAAE,4CAA4C,EAAE,WAChD,MAAM;qCAC8B,MAAM;EAC7C,IAAI,2BAA2B,MAAM,GACnC,OAAO,OAAO,KAAI,QAAO;GACvB,GAAG;GACH,SAAS,GAAG,QAAQ,QAAO,MAAK,mBAAmB,CAAC,CAAC;EACvD,EAAE;EAEJ,OAAO,OAAO,QAAO,MAAK,mBAAmB,CAAC,CAAC;CACjD;CAEA,IAAI,2BAA2B,MAAM,GACnC,OAAO,OACJ,KAAI,QAAO;EACV,GAAG;EACH,SAAS,GAAG,QAAQ,QAAO,MAAK,mBAAmB,OAAO,UAAU,CAAC,CAAC;CACxE,EAAE,CAAC,CACF,QAAO,OAAM,GAAG,QAAQ,SAAS,CAAC;CAGvC,OAAO,OAAO,QAAO,MAAK,mBAAmB,OAAO,UAAU,CAAC,CAAC;AAClE;;;;AC7DA,MAAM,eAAe,WAAW;AAEhC,MAAa,cACX;;;;;;;;;;;AAaF,IAAW,mBACT,eAAe,WAAW,UAAS,QAC9B,KAAK,OAAO,IAAI,KAAK,MAAM,CAAsB,KAAK,SAAc,OAAO,SAAS,CAAC,EAAA,CACrF,SAAS,EAAE,CAAC,CACZ,SAAS,GAAG,GAAG,CACpB;;AAIF,IAAI,cAAc;;CAEhB,IAAI,OAAO,aAAa,eAAe,YACrC,mBAAmB,aAAa,WAAW;MACtC,IAAI,OAAO,aAAa,oBAAoB,YAAY;EAO7D,MAAM,iBAAiB;EACvB,MAAM,4BAAY,IAAI,YAAY,EAAE;EAEpC,mBAAmB;GACjB,aAAa,gBAAgB,SAAS;GACtC,IAAI,MAAM,UAAU,KAAK,GAAA,CAAI,SAAS,EAAE;GACxC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;IAC3B,IAAI,MAAM,IACR,KAAK,GAAG,GAAA;SACH,IAAI,MAAM,IACf,KAAK,GAAG,KAAK,eAAe,UAAU,MAAM;SAE5C,KAAK,GAAG,MAAM,UAAU,KAAK,GAAA,CAAI,SAAS,EAAE;IAG9C,IAAI,MAAM,KAAK,MAAM,MAAM,MAAM,MAAM,MAAM,IAC3C,KAAK,GAAG,GAAA;GAEZ;GACA,OAAO;EACT;CACF;AACF;;;ACpDA,MAAM,2BAAmD,CACvD;CAAE,MAAM;CAAS,OAAO;CAAS,OAAO;AAAQ,CAClD;AAEA,MAAM,UAAU;CACd,MAAM;CACN,OAAO;CACP,cAAc;CACd,OAAO;AACT;;;;;;;AASA,MAAa,uBACX,WACA,UACA,oBAK2B;CAK3B,MAAM,KAAK,YAAY,aAAa,SAAS,IAAI;CAEjD,IAAI,kBAIoE,GAAG,gBAAgB;CAE3F,IAAI,OAAO,oBAAoB,YAC7B,kBAAkB,gBAAgB,QAAQ;CAG5C,IAAI,CAAC,mBAAmB,iBACtB,kBAAkB,gBAAgB,GAAG,OAAqC,UAAe,EACvF,WAAW,GACb,CAAC;CAGH,IAAI,CAAC,iBACH,OAAO;CAGT,IAAI,sBAAsB,eAAe,GACvC,OAAO,iBAAiB,eAAyC;CAGnE,OAAO,gBAAgB,KACrB,OACE,yBAAyB,MAAK,QAAO,IAAI,UAAU,GAAG,EAAE,CAAC,KAAK;EAC5D,MAAM;EACN,OAAO;EACP,OAAO;CACT,CACJ;AACF;;;;;;ACrDA,MAAa,eACX,MACA,EAAE,cAAc,eAAgC,CAAC,MACpC;CACb,MAAM,UAAU,CAAC,KAAK;CACtB,MAAM,eAAe,iBAAiB,IAAI;CAE1C,IAAI,CAAC,WAAW,CAAC,cACf,OAAO;CAGT,OAAO;EACL,GAAG;EACH,GAAI,WAAW,EAAE,IAAI,YAAY,EAAE;EACnC,GAAI,gBAAgB,EAAE,OAAO,iBAAiB,KAAK,OAAO,EAAE,YAAY,CAAC,EAAE;CAC7E;AACF;;;;;AAMA,MAAa,oBACX,aACA,EAAE,cAAc,eAAgC,CAAC,MAC1C;CACP,MAAM,UAAU,CAAC,YAAY;CAC7B,IAAI,eAAe;CACnB,MAAM,WAAqD,CAAC;CAE5D,KAAK,IAAI,IAAI,GAAG,IAAI,YAAY,MAAM,QAAQ,KAAK;EACjD,MAAM,IAAI,YAAY,MAAM;EAC5B,IAAI,OAAO,MAAM,UACf,SAAS,KAAK,CAAC;OACV;GACL,MAAM,WAAW,YAAY,CAAC,IAC1B,iBAAiB,GAAG,EAAE,YAAY,CAAC,IACnC,YAAY,GAAG,EAAE,YAAY,CAAC;GAClC,SAAS,KAAK,QAAQ;GACtB,IAAI,aAAa,GACf,eAAe;EAEnB;CACF;CAEA,IAAI,CAAC,WAAW,CAAC,cACf,OAAO;CAGT,OAAO;EACL,GAAG;EACH,GAAI,WAAW,EAAE,IAAI,YAAY,EAAE;EACnC,OAAO;CACT;AACF;;;;AAKA,MAAa,sBACX,IACA,EAAE,cAAc,eAAgC,CAAC,MAEjD,YAAY,EAAE,IAAI,iBAAiB,IAAI,EAAE,YAAY,CAAC,IAAI,YAAY,IAAI,EAAE,YAAY,CAAC;;;;;;;;;;;;AAa3F,MAAa,yBACX,SAMA,YACO;CACP,MAAM,iBACJ,QAAQ,SAAS,QAAQ,cAAc,QAAQ,gBAAgB,QAAQ;CAEzE,OAAO,eAAe,KAAK,iBAAiB,iBAAiB,gBAAgB,OAAO;AACtF"}