mobile_workflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '068f070743f72d5743182cd41021c33b89579ecef7182a5747c799393a1d4208'
4
+ data.tar.gz: 41aef887eb318cf98736112ce4aad51835af98f1d20e0d75f7810c9014f4c5e4
5
+ SHA512:
6
+ metadata.gz: 90ad8d639c45ff2c757a933199022a1fad59d649c815211425366c45d72a9596e516fe382835b7ffca76f1dc7bdbc85b14d35b65b723dcd751750ff10195803d
7
+ data.tar.gz: 8adcf9c22591e5644b484c0216a9f8d157222078f8ed37cebcdc9333560c30294f018e06cdfc26c8d3a27bfe9f7016346658ff4fe83a215d162f2a0946dbcaa6
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Matt Brooke-Smith
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # MobileWorkflow
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'mobile_workflow'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install mobile_workflow
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'MobileWorkflow'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/mobile_workflow .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,35 @@
1
+ module MobileWorkflow
2
+ module S3Storable
3
+ if Object.const_defined?("Aws::S3")
4
+ extend ActiveSupport::Concern
5
+
6
+ def binary_urls(object)
7
+ return unless params["binaries"]
8
+
9
+ params["binaries"].collect do |binary|
10
+ property = binary["identifier"].split('/')[0] # i.e. image/jpg --> image, video/mp4 --> video
11
+
12
+ {
13
+ "identifier" => binary["identifier"],
14
+ "url" => presigned_url("#{object.class.name.underscore}/#{object.id}/#{property}"),
15
+ "method" => "PUT"
16
+ }
17
+ end
18
+ end
19
+
20
+ private
21
+ def presigned_url(key)
22
+ presigner.presigned_url(:put_object, bucket: ENV['AWS_BUCKET_NAME'], key: key, metadata: {})
23
+ end
24
+
25
+ def presigner
26
+ Aws::S3::Presigner.new(client: s3_client)
27
+ end
28
+
29
+ def s3_client
30
+ Aws::S3::Client.new(region: ENV['AWS_REGION'], access_key_id: ENV['AWS_ACCESS_ID'], secret_access_key: ENV['AWS_SECRET_KEY'])
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,97 @@
1
+ module MobileWorkflow
2
+ class SnsNotificationsController < ApiController
3
+ if Object.const_defined?("Aws::S3") && Object.const_defined?("Aws::SNS")
4
+ before_action :verify_request_authenticity
5
+
6
+ def create
7
+ Rails.logger.info("Message body: #{message_body}")
8
+
9
+ case message_body['Type']
10
+ when 'SubscriptionConfirmation'
11
+ confirm_subscription ? (head :ok) : (head :bad_request)
12
+ else
13
+ @object = find_object
14
+ @object.send("#{attribute_name}=",active_record_blob)
15
+ if @object.save
16
+ head :ok
17
+ else
18
+ Rails.logger.warn "Error saving object: #{@object} #{object.errors.full_messages}"
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+ def verify_request_authenticity
25
+ head :unauthorized if raw_post.blank?
26
+
27
+ #head :unauthorized if raw_post.blank? || !message_verifier.authentic?(raw_post) # Not working
28
+ end
29
+
30
+ def active_record_blob
31
+ s3_object = s3_bucket.object(object_key)
32
+ checksum_base64 = checksum_base64(object_key, s3_object)
33
+ ActiveStorage::Blob.create! key: s3_object.key, filename: s3_object.key, byte_size: s3_object.size, checksum: checksum_base64, content_type: s3_object.content_type
34
+ end
35
+
36
+ def checksum_base64(object_key, s3_object)
37
+ path = Tempfile.new(object_key).path
38
+ s3_object.download_file(path)
39
+ file = File.new(path)
40
+ Digest::MD5.file(file).base64digest
41
+ end
42
+
43
+ def find_object
44
+ object_class_name, object_id = key_identifiers
45
+ object_class_name.camelcase.constantize.find(object_id.to_i)
46
+ end
47
+
48
+ def attribute_name
49
+ key_identifiers[2]
50
+ end
51
+
52
+ def key_identifiers
53
+ object_class_name, object_id, attribute_name = object_key.split("/")
54
+ return object_class_name, object_id, attribute_name
55
+ end
56
+
57
+ def object_key
58
+ @object_key ||= message['Records'][0]['s3']['object']['key']
59
+ end
60
+
61
+ def message
62
+ message = JSON.parse(message_body['Message'])
63
+ end
64
+
65
+ def message_body
66
+ @message_body ||= JSON.parse(raw_post)
67
+ end
68
+
69
+ def raw_post
70
+ @raw_post ||= request.raw_post
71
+ end
72
+
73
+ def message_verifier
74
+ @message_verifier ||= Aws::SNS::MessageVerifier.new
75
+ end
76
+
77
+ def confirm_subscription
78
+ sns_client.confirm_subscription(
79
+ topic_arn: message_body['TopicArn'],
80
+ token: message_body['Token']
81
+ )
82
+ return true
83
+ rescue Aws::SNS::Errors::ServiceError => e
84
+ Rails.logger.warn(e.message)
85
+ return false
86
+ end
87
+
88
+ def s3_bucket
89
+ Aws::S3::Resource.new(region: ENV['AWS_REGION'], access_key_id: ENV['AWS_ACCESS_ID'], secret_access_key: ENV['AWS_SECRET_KEY']).bucket(ENV['AWS_BUCKET_NAME'])
90
+ end
91
+
92
+ def sns_client
93
+ Aws::SNS::Client.new(region: ENV['AWS_REGION'], access_key_id: ENV['AWS_ACCESS_ID'], secret_access_key: ENV['AWS_SECRET_KEY'])
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,4 @@
1
+ module MobileWorkflow
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MobileWorkflow
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module MobileWorkflow
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module MobileWorkflow
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Mobile workflow</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "mobile_workflow/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,2 @@
1
+ MobileWorkflow::Engine.routes.draw do
2
+ end
@@ -0,0 +1,32 @@
1
+ module MobileWorkflow
2
+ module Generators
3
+ # Custom scaffolding generator
4
+ # https://github.com/rails/rails/blob/master/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
5
+ class ControllerGenerator < Rails::Generators::NamedBase
6
+ include Rails::Generators::ResourceHelpers
7
+ source_root File.expand_path("../templates", __FILE__)
8
+
9
+ class_option :attributes, type: :array, default: [], banner: "field:type field:type"
10
+ class_option :actions, type: :array, default: [], banner: "index create update destroy"
11
+
12
+ def copy_controller_and_spec_files
13
+ template "controller.rb.erb", File.join("app/controllers", controller_class_path, "#{controller_file_name}_controller.rb")
14
+ template "controller_spec.rb.erb", File.join("spec/controllers", controller_class_path, "#{controller_file_name}_controller_spec.rb")
15
+ end
16
+
17
+ private
18
+ def attributes_names
19
+ options[:attributes].map{ |attribute| attribute.split(":").first }
20
+ end
21
+
22
+ def permitted_params
23
+ params = attributes_names.map{ |name| ":#{name}" }
24
+ params.join(", ")
25
+ end
26
+
27
+ def rewrite_params
28
+ attributes_names.map {|name| "params[:#{singular_table_name}][:#{name}] = params[:payload][:#{name}][:answer]" }.join("\n\t\t")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ require "rails/generators/base"
2
+
3
+ module MobileWorkflow
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ class_option :open_api_spec_path, type: :string, default: "config/open_api_spec.json"
9
+
10
+ def create_api_controller
11
+ template(
12
+ "api_controller.rb.erb",
13
+ "app/controllers/api_controller.rb",
14
+ )
15
+ end
16
+
17
+ def generate_models
18
+ say "Generating models"
19
+ @model_properties = {}
20
+ open_api_spec[:components][:schemas].each_pair do |model_name, schema|
21
+ next if ["answer", "attachment"].include? model_name # Don't generate schemas for MW schemas
22
+
23
+ model_name = model_name.underscore
24
+ model_properties = model_properties(model_name, schema)
25
+ generate(:model, "#{model_name} #{model_properties}")
26
+ @model_properties[model_name] = model_properties
27
+ end
28
+ end
29
+
30
+ def generate_controllers_and_routes
31
+ say "Generating controllers"
32
+ controller_names = open_api_spec[:paths].keys.collect{|url_path| url_path.split('/').last }
33
+
34
+ route "root to: 'admin/#{controller_names.first}#index'"
35
+
36
+ controller_names.each do |plural_controller_name|
37
+ controller_name = plural_controller_name.singularize
38
+ model_properties = @model_properties[controller_name]
39
+ generate "mobile_workflow:controller #{controller_name} --attributes #{model_properties}"
40
+ route "resources :#{plural_controller_name}, only: [:index, :show, :create]"
41
+ end
42
+ end
43
+
44
+ private
45
+ def open_api_spec
46
+ @open_api_spec ||= read_openapi_spec
47
+ end
48
+
49
+ def read_openapi_spec
50
+ say "Loading OpenAPI Spec: #{open_api_spec_path}"
51
+ return JSON.parse(File.read(open_api_spec_path)).with_indifferent_access
52
+ end
53
+
54
+ def open_api_spec_path
55
+ options[:open_api_spec_path]
56
+ end
57
+
58
+ def model_properties(name, schema)
59
+ generated_properties_args = schema["properties"].keys.collect{|key| "#{key}:string" }.join(" ")
60
+ if yes?("Use generated schema #{name}(#{generated_properties_args})[yn]?")
61
+ generated_properties_args
62
+ else
63
+ ask "Specify schema for #{name}: (e.g. text:string image:attachment region:reference)"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ class ApiController < ActionController::API
2
+ def current_user
3
+ nil
4
+ end
5
+ end
@@ -0,0 +1,41 @@
1
+ <% module_namespacing do -%>
2
+ class <%= controller_class_name %>Controller < ApiController
3
+ before_action :rewrite_payload, only: :create
4
+
5
+ load_and_authorize_resource
6
+
7
+ def index
8
+ render json: @<%= plural_table_name %>.collect(&:list_item_as_json)
9
+ end
10
+
11
+ def show
12
+ render json: @<%= singular_table_name %>.display_as_json
13
+ end
14
+
15
+ def create
16
+ if @<%= singular_table_name %>.save
17
+ render json: { binary_urls: binary_urls(@<%= singular_table_name %>), response: @<%= singular_table_name %> }, status: :created
18
+ else
19
+ head :unprocessable_entity
20
+ end
21
+ end
22
+
23
+ private
24
+ def rewrite_payload
25
+ # Use this method to make any changes to params to make them compatible with ActiveRecord
26
+
27
+ # 1. Example to get properties from question
28
+ # params[:payload][:name] = params.dig(:payload, :name, :answer)
29
+
30
+ # 2. Example to get selected id from a list
31
+ # passport_id = params.dig(:payload, :choose_passport, :selected, :id)
32
+
33
+ Rails.logger.debug "Pre-rewrite params: #{params}"
34
+ <%= rewrite_params %>
35
+ end
36
+
37
+ def <%= singular_table_name.underscore %>_params
38
+ params.require(:<%= singular_table_name %>).permit(<%= permitted_params %>)
39
+ end
40
+ end
41
+ <% end %>
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'json'
5
+
6
+ RSpec.describe <%= controller_class_name %>Controller do
7
+ let(:params) { {} }
8
+ let(:json_response) { JSON.parse(response.body, symbolize_names: true) }
9
+
10
+ describe 'GET #index' do
11
+ let!(:<%= controller_class_name.singularize.underscore %>) { <%= controller_class_name.singularize %>.create }
12
+ before(:each) { get :index, params: params }
13
+
14
+ context 'ok' do
15
+ it { expect(json_response[0][:id]).to eq <%= controller_class_name.singularize.underscore %>.id }
16
+ it { expect(response.status).to eq 200 }
17
+ end
18
+ end
19
+
20
+ describe 'GET #show' do
21
+ let(:<%= controller_class_name.singularize.underscore %>) { <%= controller_class_name.singularize %>.create }
22
+ let(:params) { { id: <%= controller_class_name.singularize.underscore %>.id } }
23
+ before(:each) { get :show, params: params }
24
+
25
+ context 'ok' do
26
+ it { expect(response.status).to eq 200 }
27
+ end
28
+ end
29
+
30
+ describe 'POST #create' do
31
+ let(:payload_params) { {text: 'OK'} }
32
+ let(:params) { { payload: payload_params, binaries: [{identifier: 'record', mimetype: 'video/mp4'}] } }
33
+ before(:each) { post :create, params: params }
34
+
35
+ context 'ok' do
36
+ it { expect(<%= controller_class_name.singularize %>.count).to eq 1 }
37
+ it { expect(response.status).to eq 201 }
38
+ it { expect(json_response[:binary_urls]).to_not be_nil }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ require "mobile_workflow/engine"
2
+
3
+ module MobileWorkflow
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,9 @@
1
+ module MobileWorkflow
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace MobileWorkflow
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module MobileWorkflow
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :mobile_workflow do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,56 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %> < <%= parent_class_name.classify %>
3
+ # Enable if you need to generate attachment URLs
4
+ # include Rails.application.routes.url_helpers
5
+
6
+ <% attributes.select(&:reference?).each do |attribute| -%>
7
+ belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
8
+ <% end -%>
9
+ <% attributes.select(&:attachment?).each do |attribute| -%>
10
+ has_one_attached :<%= attribute.name %>
11
+ <% end -%>
12
+ <% attributes.select(&:attachments?).each do |attribute| -%>
13
+ has_many_attached :<%= attribute.name %>
14
+ <% end -%>
15
+
16
+ def list_item_as_json
17
+ {
18
+ id: id,
19
+ text: text,
20
+ # detailText: nil,
21
+ # sfSymbolName: nil,
22
+ # imageURL: preview_url(image, height: 100, width: 100)
23
+ }
24
+ end
25
+
26
+ def display_as_json
27
+ [
28
+ {label: "ID", text: text, mimeType: 'text/plain'},
29
+ {label: "Text", text: text, mimeType: 'text/plain'}
30
+ ]
31
+ end
32
+
33
+ # private
34
+ # include Rails.application.routes.url_helpers # for attachment URLs
35
+ # def preview_url(attachment, height:, width:, options: { resize_to_fill: [height, width]} )
36
+ # return nil unless attachment.attached?
37
+ #
38
+ # if attachment.image?
39
+ # Rails.application.routes.url_helpers.rails_representation_url(attachment.variant(combine_options: options), host: attachment_host)
40
+ # elsif attachment.previewable?
41
+ # Rails.application.routes.url_helpers.rails_representation_url(attachment.preview(options), host: attachment_host)
42
+ # else
43
+ # return nil
44
+ # end
45
+ # end
46
+ #
47
+ # def attachment_url(attachment)
48
+ # Rails.application.routes.url_helpers.rails_blob_url(attachment, host: attachment_host)
49
+ # end
50
+ #
51
+ # def attachment_host
52
+ # "https://#{ENV['HEROKU_APP_NAME']}.herokuapp.com"
53
+ # end
54
+
55
+ end
56
+ <% end -%>
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mobile_workflow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Brooke-Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.3
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.0.3.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 6.0.3
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.0.3.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: sqlite3
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ description:
62
+ email:
63
+ - matt@futureworkshops.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - MIT-LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - app/assets/config/mobile_workflow_manifest.js
72
+ - app/assets/stylesheets/mobile_workflow/application.css
73
+ - app/controllers/concerns/mobile_workflow/s3_storable.rb
74
+ - app/controllers/mobile_workflow/sns_notifications_controller.rb
75
+ - app/helpers/mobile_workflow/application_helper.rb
76
+ - app/jobs/mobile_workflow/application_job.rb
77
+ - app/mailers/mobile_workflow/application_mailer.rb
78
+ - app/models/mobile_workflow/application_record.rb
79
+ - app/views/layouts/mobile_workflow/application.html.erb
80
+ - config/routes.rb
81
+ - lib/generators/mobile_workflow/controller_generator.rb
82
+ - lib/generators/mobile_workflow/install/install_generator.rb
83
+ - lib/generators/mobile_workflow/install/templates/api_controller.rb.erb
84
+ - lib/generators/mobile_workflow/templates/controller.rb.erb
85
+ - lib/generators/mobile_workflow/templates/controller_spec.rb.erb
86
+ - lib/mobile_workflow.rb
87
+ - lib/mobile_workflow/engine.rb
88
+ - lib/mobile_workflow/version.rb
89
+ - lib/tasks/mobile_workflow_tasks.rake
90
+ - lib/templates/active_record/model/model.rb.erb
91
+ homepage: https://github.com/futureworkshops/mobile_workflow
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubygems_version: 3.0.8
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: A Rails engine to provide API support for Mobile Workflow Apps.
114
+ test_files: []