Module: ZeroClick::Sellers::Stateful::Contracts
- Defined in:
- lib/zeroclick/sellers/stateful/contracts.rb
Class Method Summary collapse
-
.as_version(value) ⇒ Object
A non-negative integer.
- .iso_datetime?(value) ⇒ Boolean
- .non_empty_string?(value) ⇒ Boolean
-
.optional_id(container, key) ⇒ Object
Absent and null both mean "not present"; an empty string is invalid.
- .parse_mint_key_request(body) ⇒ Object
- .parse_money_field(container, key, required:, issues:) ⇒ Object
- .parse_period(value, issues) ⇒ Object
- .parse_plan(value, issues) ⇒ Object
Class Method Details
.as_version(value) ⇒ Object
A non-negative integer. JSON 1.0 counts; true and "1" do not.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 51 def as_version(value) return nil if value.is_a?(TrueClass) || value.is_a?(FalseClass) return value.negative? ? nil : value if value.is_a?(Integer) if value.is_a?(Float) && value.finite? && (value % 1).zero? version = value.to_i return version.negative? ? nil : version end nil end |
.iso_datetime?(value) ⇒ Boolean
42 43 44 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 42 def iso_datetime?(value) value.is_a?(String) && ISO_DATETIME_RE.match?(value) end |
.non_empty_string?(value) ⇒ Boolean
46 47 48 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 46 def non_empty_string?(value) value.is_a?(String) && !value.empty? end |
.optional_id(container, key) ⇒ Object
Absent and null both mean "not present"; an empty string is invalid. Returns [value, ok].
65 66 67 68 69 70 71 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 65 def optional_id(container, key) value = container[key] return [nil, true] if value.nil? return [value, true] if non_empty_string?(value) [nil, false] end |
.parse_mint_key_request(body) ⇒ Object
73 74 75 76 77 78 79 80 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 73 def parse_mint_key_request(body) return nil unless body.is_a?(Hash) && non_empty_string?(body["agentId"]) buyer_id, ok = optional_id(body, "buyerId") return nil unless ok MintKeyRequest.new(agent_id: body["agentId"], buyer_id: buyer_id) end |
.parse_money_field(container, key, required:, issues:) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 121 def parse_money_field(container, key, required:, issues:) unless container.key?(key) issues << "state.#{key}: required (may be null)" if required return nil end value = container[key] return nil if value.nil? return value if Money.money_usd?(value) issues << "state.#{key}: expected a six-decimal USD string or null" nil end |
.parse_period(value, issues) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 101 def parse_period(value, issues) unless value.is_a?(Hash) issues << "state.period: expected an object" return nil end before = issues.length start = value["start"] issues << "state.period.start: expected an ISO datetime" unless iso_datetime?(start) # Required but nullable: absence is a different mistake from null, # and only absence is an error. issues << "state.period.end: required (may be null)" unless value.key?("end") finish = value["end"] issues << "state.period.end: expected an ISO datetime or null" if !finish.nil? && !iso_datetime?(finish) return nil if issues.length != before AccessPeriod.new(start: start, end: finish) end |
.parse_plan(value, issues) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/zeroclick/sellers/stateful/contracts.rb', line 82 def parse_plan(value, issues) unless value.is_a?(Hash) issues << "plan: expected an object" return nil end before = issues.length %w[slug name billingMode interval].each do |key| issues << "plan.#{key}: expected a string" unless value[key].is_a?(String) end issues << "plan.basePriceUsd: expected a six-decimal USD string" unless Money.money_usd?(value["basePriceUsd"]) return nil if issues.length != before EntitlementPlan.new( slug: value["slug"], name: value["name"], billing_mode: value["billingMode"], interval: value["interval"], base_price_usd: value["basePriceUsd"] ) end |