function extractFeatureValueSets()

in packages/sqrl/src/ast/astIntersects.ts [58:129]


function extractFeatureValueSets(
  ast: Ast
): {
  [feature: string]: Set<boolean | string>;
} {
  /***
   * Returns a map of /either/
   *   feature: true, [for boolean features]
   *   feature: Set(...values), [ for equalities ]
   */
  if (ast.type === "feature") {
    return {
      [ast.value]: booleanSet,
    };
  } else if (ast.type === "not") {
    return extractFeatureValueSets(ast.expr);
  } else if (ast.type === "boolean_expr") {
    sqrlInvariant(
      ast,
      ast.operator === "and" || ast.operator === "or",
      "Only and/or operators are allowed in where clause"
    );

    const results = {};
    for (const sub of [ast.left, ast.right]) {
      foreachObject(extractFeatureValueSets(sub), (values, feature) => {
        if (!results.hasOwnProperty(feature)) {
          results[feature] = values;
        } else if (values === booleanSet) {
          sqrlInvariant(
            ast,
            results[feature] === booleanSet,
            "Invalid where: feature must be defined as boolean or equality"
          );
        } else {
          sqrlInvariant(
            ast,
            results[feature] !== booleanSet,
            "Invalid where: feature must be defined as boolean or equality"
          );
          values.forEach((value) => results[feature].add(value));
        }
      });
    }
    return results;
  } else if (ast.type === "binary_expr") {
    sqrlInvariant(ast, ["=", "!="].indexOf(ast.operator) >= 0, ast.operator);

    if (ast.left.type !== "feature") {
      throw buildSqrlError(
        ast,
        "Counter where clause equality left-hand side must be a feature"
      );
    }

    if (ast.right.type !== "constant" || typeof ast.right.value !== "string") {
      throw buildSqrlError(
        ast,
        "Counter where clause equality right-hand side must be a constant string"
      );
    }

    return {
      [ast.left.value]: new Set([ast.right.value]),
    };
  } else {
    throw buildSqrlError(
      ast,
      "Only and/or/not and constant equality allowed in where clause"
    );
  }
}