mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
* Add Scope plumbing and custom operator extension point Thread evaluation scope through the rules engine and delegate unknown operators to an empty CustomOperators dispatcher, without changing behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix project.pbxproj: restore RewardedAdTrackingMetadata entries The RulesEngine registration edit accidentally dropped four RewardedAdTrackingMetadata.swift entries from the Xcode project. Restore them and normalize CustomOperators identifiers to 24 hex chars. Co-authored-by: Cursor <cursoragent@cursor.com> * Promote firstArgEvaluated to shared Operators helpers Move the unary-arg helper from LogicOperators to Operators so custom operators can use the same json-logic-js spread convention. Co-authored-by: Cursor <cursoragent@cursor.com> * Add rc.lower and rc.upper for case-insensitive rules Locale-independent case conversion via jsString coercion, with predicate fixtures covering coercion, Unicode behavior, and motivating match cases. Co-authored-by: Cursor <cursoragent@cursor.com> * Address review comments on custom operator extension point Drop the cross-engine registration note from CustomOperators, and restore the single-line var extra-args warning that was reflowed without changing its text. Co-authored-by: Cursor <cursoragent@cursor.com> * Pin locale-independent uppercasing of ASCII i rc.lower already had a fixture asserting the Unicode default mapping for the Turkish I, but rc.upper had no equivalent. The uppercase direction is the more consequential one: Turkish maps i to U+0130, a scalar with no ASCII counterpart, so a locale-sensitive implementation would silently change what rules match. Co-authored-by: Cursor <cursoragent@cursor.com> * Require string input for rc.lower and rc.upper Both operators coerced non-strings through jsString, mirroring JS String(x).toLowerCase(). That makes absent data look like real data: a missing var resolves to null, so comparing a lowercased path against "null" would quietly match. Throw typeMismatch instead, matching rc.length and rc.entries. The four coercion fixtures are replaced by nine type-error fixtures covering null, undefined, numbers, booleans, arrays, objects and missing vars, with rc.upper cases pinning that it shares the guard. Co-authored-by: Cursor <cursoragent@cursor.com> * Correct the jsNumberString divergence note The note claimed the JS mismatch only surfaces through var path coercion and looseEq, and only for large magnitudes. cat, substr and in stringify numbers through the same helper, and small values diverge too: 1e-6 renders as "1e-06" rather than "0.000001". Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
40 lines
1.0 KiB
Swift
40 lines
1.0 KiB
Swift
//
|
|
// CustomOperators.swift
|
|
//
|
|
// Created by Antonio Pallares.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
extension RulesEngine {
|
|
|
|
/// RevenueCat-specific JSON Logic operators.
|
|
///
|
|
/// Operators here are namespaced under `rc.` so they cannot collide with a
|
|
/// future standard JSON Logic operator.
|
|
enum CustomOperators {
|
|
|
|
static func dispatch(
|
|
op operatorName: String,
|
|
args: Value,
|
|
vars: Scope
|
|
) throws -> Value {
|
|
switch operatorName {
|
|
case "rc.length":
|
|
return try LengthOperator.opLength(args: args, vars: vars)
|
|
|
|
case "rc.lower":
|
|
return try CaseOperators.opLower(args: args, vars: vars)
|
|
case "rc.upper":
|
|
return try CaseOperators.opUpper(args: args, vars: vars)
|
|
|
|
case "rc.rootVar":
|
|
return try RootVarOperator.opRootVar(args: args, vars: vars)
|
|
|
|
default:
|
|
throw EvaluationError.unsupportedOperator(name: operatorName)
|
|
}
|
|
}
|
|
}
|
|
}
|