class Jets::Lambda::Task

def baseline_replacements

def baseline_replacements
  {
    # camelized because used in not just keys but common used in values
    namespace: @meth.to_s.camelize,
  }
end

def build_function_iam?

def build_function_iam?
  !!(@iam_policy || @managed_iam_policy)
end

def full_handler(handler_function)

def full_handler(handler_function)
  "#{handler_base}.#{handler_function}"
end

def get_type

Returns: "controller", "job" or nil

FunctionConstructor.
For anonymous function classes, we just set to nil and will later fix in

determinated as part of initialization. So we get the type for convenience then.
For controller and job standard ruby classes though it can easily be

as part of the Class.new logic.
We add the class_type to the task later on as we are constructing the class
Class.new the method_added hook has "" (blank string) as the self class name.
are anonymous classes created with Class.new. When classes are created with
The second reason is that functions are not regular ruby classes. Instead they

app/functions/hello_function.rb => HelloFunction => function
app/functions/hello.rb => Hello => function
path => class => type

_function. Examples:
reasons. First, function types are allowed to be named with or without
However, for function types, we are not able to get the type for multiple of

HardJob => job
PostsController => controller

Usually able to get the type from the class name. Examples:

The get_type method works for controller and job classes.
def get_type
  unless @class_name.empty? # when anonymous class is created with Class.new
    @class_name.underscore.split('_').last # controller, job or rule
  end
end

def handler_base

def handler_base
  base = "handlers/#{@type.pluralize}/#{@class_name.underscore}"
  base += "/#{@lang}" if @lang != :ruby
  base += "/#{@meth}"
end

def handler_path

def handler_path
  "#{handler_base}#{lang_ext}"
end

def initialize(class_name, meth, options={})

def initialize(class_name, meth, options={})
  @class_name = class_name.to_s
  @meth = meth
  @options = options
  @type = options[:type] || get_type  # controller, job, or function
  @properties = options[:properties] || {}
  @iam_policy = options[:iam_policy]
  @managed_iam_policy = options[:managed_iam_policy]
  @lang = options[:lang] || :ruby
  @associated_resources = options[:associated_resources] || {}
  @replacements = options[:replacements] || {} # added to baseline replacements
end

def lang_ext

def lang_ext
  @@lang_exts[@lang]
end

def name

def name
  @meth
end

def poly_src_path

def poly_src_path
  handler_path.sub("handlers/", "app/")
end

def public_meth?

def public_meth?
  # For anonymous classes (app/functions/hello.rb) the class name will be blank.
  # These types of classes are treated specially and has only one handler method
  # that is registered. So we know it is public.
  return true if @class_name.nil? || @class_name == ''
  # Consider all polymorphic methods public for now
  return true if @lang != :ruby
  klass = @class_name.constantize
  public_methods = klass.public_instance_methods
  public_methods.include?(meth.to_sym)
end

def replacements

def replacements
  # Merge in the custom replacements specific to each app class: ConfigRule, Job, etc.
  baseline_replacements.merge(@replacements)
end