Skip to content

Repository files navigation

@react-querybuilder/migrate-raqb

Conversion utilities for migrating between react-awesome-query-builder (RAQB) and React Query Builder.

These utilities give RAQB users a straightforward path to React Query Builder, and—for a phased migration where both query builders must read the same stored queries—a way back.

Full migration guide

Installation

npm i @react-querybuilder/migrate-raqb
# OR bun add / yarn add / pnpm add

Requires @react-querybuilder/core v8.21.2 or later as a peer dependency (it's a transitive dependency of react-querybuilder, so no extra install is needed if you already use that). Major versions of this package align with major versions of React Query Builder.

RAQB → RQB

parseRAQB accepts an RAQB query tree in its plain-JSON form and returns a query suitable for the query/defaultQuery props. Call RAQB's Utils.getTree() first if you have an immutable.js tree—passing one directly throws.

import { parseRAQB, parseRAQBFields } from '@react-querybuilder/migrate-raqb';

const fields = parseRAQBFields(raqbConfig.fields);
const query = parseRAQB(Utils.getTree(immutableTree), { fields });
Option Default Description
fields Field list. Rules referencing unknown fields are skipped.
operatorMap {} Additional/overriding RAQB-to-RQB operator mappings.
functionMap {} Additional/overriding RAQB-to-@react-querybuilder/expr function name mappings.
funcArgOrder {} Explicit argument order per RAQB function name. Defaults to the key order of the serialized object.
relativeDateTimes true Convert RAQB's built-in date/time functions to @react-querybuilder/datetime relative date/time values rather than expressions.
onUnsupported Called for each construct that can't be represented, instead of silently dropping it.
listsAsArrays false Emit in/between values as arrays rather than comma-separated strings.
generateIDs false Generate a unique id for each rule and group.
independentCombinators false Produce a RuleGroupTypeIC query.

RQB → RAQB

formatRAQB is the inverse of parseRAQB. Pass its output to RAQB's Utils.loadTree():

import { Utils } from '@react-awesome-query-builder/core';
import { formatRAQB, formatRAQBFields } from '@react-querybuilder/migrate-raqb';

const raqbConfig = { ...BasicConfig, fields: formatRAQBFields(fields) };

const jsonTree = formatRAQB(query, { fields });
const immutableTree = Utils.checkTree(Utils.loadTree(jsonTree), raqbConfig);

Pass fields for the most faithful output—several RAQB operators collapse to a single RQB operator, and the field's valueEditorType is used to disambiguate them.

formatRAQB accepts all formatQuery options except format, ruleGroupProcessor, and fallbackExpression, plus:

Option Default Description
fallbackTree raqbFallback Tree returned when the query is empty or fails validation.
raqbOperatorMap {} Additional/overriding RQB-to-RAQB operator mappings, keyed by RQB operator name.
raqbFunctionMap {} Additional/overriding expression-function-to-RAQB function name mappings.
raqbFuncArgOrder {} Argument names per RAQB function name. Defaults cover RAQB's built-ins; others get arg0, arg1, ...
raqbFieldSeparator "." Separator used to qualify sub-query rule fields with their parent !group field name.
raqbRelativeDateTimes true Convert relative date/time values to RAQB's built-in date/time functions.
raqbValueTypes false Emit valueType entries inferred from each field's inputType/valueEditorType.

If you'd rather drive formatQuery yourself—to combine RAQB output with other formatQuery behavior, or to supply a custom ruleProcessor—use the underlying defaultRuleGroupProcessorRAQB directly. It takes precedence over format, and RAQB options move into context:

const jsonTree = formatQuery(query, {
  ruleGroupProcessor: defaultRuleGroupProcessorRAQB,
  fields,
  context: { raqbValueTypes: true },
  // Needed only when a `validator` can invalidate the whole query:
  fallbackExpression: raqbFallback as unknown as string,
});

defaultRuleProcessorRAQB is used automatically; pass an explicit ruleProcessor only to override it.

Caveats

  • RQB's doesNotBeginWith and doesNotEndWith have no RAQB default equivalent (there is no not_starts_with/not_ends_with); rules using them are omitted unless you supply a raqbOperatorMap entry.
  • The "parameter" value source has no RAQB counterpart, so those rules are omitted.
  • in/notIn map to select_any_in/select_not_any_in, which RAQB only allows for select and multiselect fields. On a plain text field RAQB's checkTree will reject the rule.
  • Field-to-field comparisons are more restricted in RAQB: its field widget for the text type supports only equal, not_equal, and proximity, so contains/beginsWith/endsWith/</> against another field are rejected.
  • RAQB clamps inverted ranges, so a between rule with preserveValueOrder and out-of-order bounds (e.g. [100, 0]) becomes [100, 100] once loaded.
  • bigint values are narrowed to number, since RAQB trees must be JSON-serializable.
  • endOf* relative date/time anchors are emitted as plain values, since RAQB's built-in functions only truncate to the start of a period.
  • RAQB defines no XOR conjunction. xor combinators are emitted as "XOR" rather than silently degraded, so RAQB's checkTree will flag them unless a matching custom conjunction is configured.
  • RAQB's several operators that collapse to one RQB operator (equal/select_equals/multiselect_equals=) are disambiguated using each field's valueEditorType, so pass fields for the most faithful output.
  • formatQuery short-circuits on a failed top-level validator before the rule group processor runs, and its default fallback is the SQL string "(1 = 1)". formatRAQB handles this for you (see fallbackTree above); if you call formatQuery directly, pass fallbackExpression: raqbFallback as unknown as string.

License

MIT

About

Migration tools for react-awesome-query-builder

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages