class Passwordstate::Resource

A simple resource DSL

Attributes

client[R]

Public Class Methods

all(client, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 37
def self.all(client, query = {})
  path = query.fetch(:_api_path, api_path)
  query = passwordstateify_hash query.reject { |k| k.to_s.start_with? '_' }

  [client.request(:get, path, query: query)].flatten.map do |object|
    new object.merge(_client: client)
  end
end
Also aliased as: search
available?(_client) click to toggle source
# File lib/passwordstate/resource.rb, line 33
def self.available?(_client)
  true
end
delete(client, object, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 78
def self.delete(client, object, query = {})
  path = query.fetch(:_api_path, api_path)
  query = passwordstateify_hash query.reject { |k| k.to_s.start_with? '_' }

  object = object.send(object.class.send(index_field)) if object.is_a? Resource
  client.request :delete, "#{path}/#{object}", query: query
end
get(client, object, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 46
def self.get(client, object, query = {})
  object = object.send(object.class.send(index_field)) if object.is_a? Resource

  return new _client: client, index_field => object if query[:_bare]

  path = query.fetch(:_api_path, api_path)
  query = passwordstateify_hash query.reject { |k| k.to_s.start_with? '_' }

  resp = client.request(:get, "#{path}/#{object}", query: query).map do |data|
    new data.merge(_client: client)
  end
  return resp.first if resp.one? || resp.empty?

  resp
end
new(data) click to toggle source
# File lib/passwordstate/resource.rb, line 23
def initialize(data)
  @client = data.delete :_client
  set! data, false
  old
end
passwordstateify_hash(hash) click to toggle source
# File lib/passwordstate/resource.rb, line 86
def self.passwordstateify_hash(hash)
  Hash[hash.map  { |k, v| [ruby_to_passwordstate_field(k), v] }]
end
post(client, data, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 62
def self.post(client, data, query = {})
  path = query.fetch(:_api_path, api_path)
  data = passwordstateify_hash data
  query = passwordstateify_hash query.reject { |k| k.to_s.start_with? '_' }

  new [client.request(:post, path, body: data, query: query)].flatten.first.merge(_client: client)
end
put(client, data, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 70
def self.put(client, data, query = {})
  path = query.fetch(:_api_path, api_path)
  data = passwordstateify_hash data
  query = passwordstateify_hash query.reject { |k| k.to_s.start_with? '_' }

  client.request :put, path, body: data, query: query
end

Protected Class Methods

accessor_field_names() click to toggle source
# File lib/passwordstate/resource.rb, line 174
def accessor_field_names
  @accessor_field_names ||= []
end
accessor_fields(*fields) click to toggle source
# File lib/passwordstate/resource.rb, line 194
def accessor_fields(*fields)
  fields.each do |field|
    if field.is_a? Symbol
      accessor_field_names << field
      attr_accessor field
    else
      field_options[accessor_field_names.last] = field
    end
  end
end
api_path(path = nil) click to toggle source
# File lib/passwordstate/resource.rb, line 148
def api_path(path = nil)
  @api_path = path unless path.nil?
  @api_path
end
field_options() click to toggle source
# File lib/passwordstate/resource.rb, line 186
def field_options
  @field_options ||= {}
end
index_field(field = nil) click to toggle source
# File lib/passwordstate/resource.rb, line 153
def index_field(field = nil)
  @index_field = field unless field.nil?
  @index_field
end
nil_as_string(opt = nil) click to toggle source
# File lib/passwordstate/resource.rb, line 158
def nil_as_string(opt = nil)
  @nil_as_string = opt unless opt.nil?
  @nil_as_string
end
passwordstate_to_ruby_field(field) click to toggle source
# File lib/passwordstate/resource.rb, line 163
def passwordstate_to_ruby_field(field)
  opts = send(:field_options).find { |(_k, v)| v[:name] == field }
  opts&.first || field.to_s.snake_case.to_sym
end
read_field_names() click to toggle source
# File lib/passwordstate/resource.rb, line 178
def read_field_names
  @read_field_names ||= []
end
read_fields(*fields) click to toggle source
# File lib/passwordstate/resource.rb, line 205
def read_fields(*fields)
  fields.each do |field|
    if field.is_a? Symbol
      read_field_names << field
      attr_reader field
    else
      field_options[read_field_names.last] = field
    end
  end
end
read_only() click to toggle source
# File lib/passwordstate/resource.rb, line 190
def read_only
  # TODO
end
ruby_to_passwordstate_field(field) click to toggle source
# File lib/passwordstate/resource.rb, line 168
def ruby_to_passwordstate_field(field)
  send(:field_options)[field]&.[](:name) || field.to_s.camel_case
end
write_field_names() click to toggle source
# File lib/passwordstate/resource.rb, line 182
def write_field_names
  @write_field_names ||= []
end
write_fields(*fields) click to toggle source
# File lib/passwordstate/resource.rb, line 216
def write_fields(*fields)
  fields.each do |field|
    if field.is_a? Symbol
      write_field_names << field
      attr_writer field
    else
      field_options[write_field_names.last] = field
    end
  end
end

Public Instance Methods

api_path() click to toggle source
# File lib/passwordstate/resource.rb, line 90
def api_path
  self.class.instance_variable_get :@api_path
end
attributes(opts = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 94
def attributes(opts = {})
  ignore_redact = opts.fetch(:ignore_redact, true)
  nil_as_string = opts.fetch(:nil_as_string, self.class.nil_as_string)
  Hash[(self.class.send(:accessor_field_names) + self.class.send(:read_field_names) + self.class.send(:write_field_names)).map do |field|
    redact = self.class.send(:field_options)[field]&.fetch(:redact, false) && !ignore_redact
    value = instance_variable_get("@#{field}".to_sym) unless redact
    value = '[ REDACTED ]' if redact
    value = '' if value.nil? && nil_as_string
    [field, value]
  end].reject { |_k, v| v.nil? }
end
delete(query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 19
def delete(query = {})
  self.class.delete(client, send(self.class.index_field), query)
end
get(query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 6
def get(query = {})
  set! self.class.get(client, send(self.class.index_field), query)
end
inspect() click to toggle source
# File lib/passwordstate/resource.rb, line 106
def inspect
  "#{to_s[0..-2]} #{attributes(nil_as_string: false, ignore_redact: false).reject { |_k, v| v.nil? }.map { |k, v| "@#{k}=#{v.inspect}" }.join(', ')}>"
end
post(body = {}, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 15
def post(body = {}, query = {})
  set! self.class.post(client, attributes.merge(body), query)
end
put(body = {}, query = {}) click to toggle source
# File lib/passwordstate/resource.rb, line 10
def put(body = {}, query = {})
  to_send = modified.merge(self.class.index_field => send(self.class.index_field))
  set! self.class.put(client, to_send.merge(body), query).first
end
stored?() click to toggle source
# File lib/passwordstate/resource.rb, line 29
def stored?
  !send(self.class.index_field).nil?
end

Protected Instance Methods

modified() click to toggle source
# File lib/passwordstate/resource.rb, line 112
def modified
  attribs = attributes
  attribs.reject { |field| old[field] == attribs[field] }
end
modified?(field) click to toggle source
# File lib/passwordstate/resource.rb, line 117
def modified?(field)
  modified.include? field
end
old() click to toggle source
# File lib/passwordstate/resource.rb, line 121
def old
  @old ||= attributes.dup
end
set!(data, store_old = true) click to toggle source
# File lib/passwordstate/resource.rb, line 125
def set!(data, store_old = true)
  @old = attributes.dup if store_old
  data = data.attributes if data.is_a? Passwordstate::Resource
  data.each do |key, value|
    field = self.class.passwordstate_to_ruby_field(key)
    opts = self.class.send(:field_options)[field]

    value = nil if value.is_a?(String) && value.empty?

    if !value.nil? && opts&.key?(:is)
      klass = opts.fetch(:is)
      parsed_value = klass.send :parse, value rescue nil if klass.respond_to? :parse
      parsed_value ||= klass.send :new, value rescue nil if klass.respond_to? :new
    end

    instance_variable_set "@#{field}".to_sym, parsed_value || value
  end
  self
end