mobile_workflow 0.1.0

This diff has not been reviewed by any users.
Log in in order to be able to vote.
@@ -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: []