apiway 0.0.1
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.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +1 -0
- data/Rakefile +0 -0
- data/bin/apiway +13 -0
- data/lib/apiway/application.rb +53 -0
- data/lib/apiway/client.rb +171 -0
- data/lib/apiway/commands.rb +62 -0
- data/lib/apiway/controller.rb +124 -0
- data/lib/apiway/diff.rb +84 -0
- data/lib/apiway/errors.rb +62 -0
- data/lib/apiway/events.rb +23 -0
- data/lib/apiway/extensions.rb +29 -0
- data/lib/apiway/generator.rb +111 -0
- data/lib/apiway/logger.rb +41 -0
- data/lib/apiway/model.rb +58 -0
- data/lib/apiway/path.rb +7 -0
- data/lib/apiway/resource.rb +110 -0
- data/lib/apiway/version.rb +5 -0
- data/lib/apiway.rb +17 -0
- data/lib/generator/application/.gitignore +1 -0
- data/lib/generator/application/Gemfile +9 -0
- data/lib/generator/application/Procfile +1 -0
- data/lib/generator/application/README.md +0 -0
- data/lib/generator/application/Rakefile +3 -0
- data/lib/generator/application/app/base/.keep +0 -0
- data/lib/generator/application/app/base/base.rb +5 -0
- data/lib/generator/application/app/base/client.rb +21 -0
- data/lib/generator/application/app/base/routes.rb +11 -0
- data/lib/generator/application/app/controllers/.keep +0 -0
- data/lib/generator/application/app/controllers/application.rb +5 -0
- data/lib/generator/application/app/models/.keep +0 -0
- data/lib/generator/application/app/resources/.keep +0 -0
- data/lib/generator/application/app/resources/application.rb +5 -0
- data/lib/generator/application/config/application.rb +13 -0
- data/lib/generator/application/config/database.yml +17 -0
- data/lib/generator/application/config/environments/development.rb +9 -0
- data/lib/generator/application/config/environments/production.rb +9 -0
- data/lib/generator/application/config/environments/test.rb +10 -0
- data/lib/generator/application/config.ru +3 -0
- data/lib/generator/application/db/migrate/.keep +0 -0
- data/lib/generator/application/lib/.keep +0 -0
- data/lib/generator/application/public/.keep +0 -0
- data/lib/generator/templates/controller.tpl +22 -0
- data/lib/generator/templates/model.tpl +5 -0
- data/lib/generator/templates/resource.tpl +29 -0
- metadata +174 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module Generator
|
4
|
+
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
HANDLERS = {
|
9
|
+
create_application: [ '-a', 'a', 'app' ],
|
10
|
+
create_controller: [ '-c', 'c', 'controller' ],
|
11
|
+
create_resource: [ '-r', 'r', 'resource' ],
|
12
|
+
create_model: [ '-m', 'm', 'model' ],
|
13
|
+
help: [ '-h', 'h', 'help' ]
|
14
|
+
}
|
15
|
+
|
16
|
+
DESC = {
|
17
|
+
create_application: 'Creating a new application (`apiway generate app Chat`)',
|
18
|
+
create_controller: 'Creating a new controller (`apiway generate controller Messages`)',
|
19
|
+
create_resource: 'Creating a new resource (`apiway generate resource Messages`)',
|
20
|
+
create_model: 'Creating a new model (`apiway generate model Message`)',
|
21
|
+
help: 'Show list of generator commands'
|
22
|
+
}
|
23
|
+
|
24
|
+
def run( command = nil, *args )
|
25
|
+
return help unless command
|
26
|
+
HANDLERS.each { |handler, commands| return send( handler, *args ) if commands.include? command }
|
27
|
+
puts "Apiway: Unknown generate command `#{ args.unshift( command ).join " " }`"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def create_application( name = nil )
|
34
|
+
check_name( 'application', name ) do
|
35
|
+
source = File.join Apiway.path, 'generator/application'
|
36
|
+
target = File.join Dir.pwd, name
|
37
|
+
FileUtils.cp_r source, target
|
38
|
+
puts "Apiway: Application `#{ name }` created"
|
39
|
+
puts "Installing gems"
|
40
|
+
exec "cd #{ name } && bundle install"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_controller( name = nil )
|
45
|
+
check_name( 'controller', name ) do
|
46
|
+
in_root_folder do
|
47
|
+
filename = name.underscore
|
48
|
+
classname = filename.camelize
|
49
|
+
write "app/controllers/#{ filename }.rb", render( 'controller', classname )
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_resource( name = nil )
|
55
|
+
check_name( 'resource', name ) do
|
56
|
+
in_root_folder do
|
57
|
+
filename = name.underscore
|
58
|
+
classname = filename.camelize
|
59
|
+
write "app/resources/#{ filename }.rb", render( 'resource', classname )
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_model( name = nil )
|
65
|
+
check_name( 'model', name ) do
|
66
|
+
in_root_folder do
|
67
|
+
if name.scan( '_' ).size > 0
|
68
|
+
puts 'Apiway: Please do not use an underscore'
|
69
|
+
else
|
70
|
+
filename = name.downcase
|
71
|
+
classname = name.camelize
|
72
|
+
write "app/models/#{ filename }.rb", render( 'model', classname )
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def help( *args )
|
79
|
+
puts "\n Apiway generator commands: \n\n"
|
80
|
+
HANDLERS.each do |handler, commands|
|
81
|
+
puts " [#{ commands.join( "], [" ) }]".ljust(30) << "# #{ DESC[ handler ] } "
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_name( type, name )
|
86
|
+
if name then yield
|
87
|
+
else puts "Apiway: Enter a name of #{ type }" end
|
88
|
+
end
|
89
|
+
|
90
|
+
def in_root_folder
|
91
|
+
if Dir.exists?( File.join( Dir.pwd, 'app' ) ) then yield
|
92
|
+
else puts 'Apiway: Please go to application root folder' end
|
93
|
+
end
|
94
|
+
|
95
|
+
def render( name, classname )
|
96
|
+
modelname = classname.chomp 's'
|
97
|
+
varname = modelname.downcase
|
98
|
+
ERB.new( File.read( File.join( Apiway.path, 'generator/templates', "#{ name }.tpl" ) ) ).result binding
|
99
|
+
end
|
100
|
+
|
101
|
+
def write( path, content )
|
102
|
+
File.open( File.join( Dir.pwd, path ), 'w' ) { |file| file.write( content ) }
|
103
|
+
puts "Apiway: Created: #{ path }"
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module LoggerBase
|
4
|
+
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def apiway_log_level( level )
|
9
|
+
set_log_level( Log, level || :unknown )
|
10
|
+
end
|
11
|
+
|
12
|
+
def activerecord_log_level( level )
|
13
|
+
ActiveRecord::Base.logger = level ? set_log_level( new_logger, level ) : false
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_logger
|
17
|
+
logger = Logger.new STDOUT
|
18
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
19
|
+
"#{ datetime.strftime( "%H:%M:%S" ) } - #{ severity }> #{ msg }\n"
|
20
|
+
end
|
21
|
+
logger
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def set_log_level( logger, level )
|
28
|
+
logger.level = Logger.const_get level.to_s.upcase
|
29
|
+
logger
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
Log = LoggerBase::new_logger
|
39
|
+
|
40
|
+
|
41
|
+
end
|
data/lib/apiway/model.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module Model
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def included( base )
|
10
|
+
all << base
|
11
|
+
base.class_eval do
|
12
|
+
extend ClassMethods
|
13
|
+
include InstanceMethods
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def all
|
18
|
+
@all ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def self.extended( base )
|
28
|
+
base.class_eval do
|
29
|
+
|
30
|
+
if self.ancestors.include? ActiveRecord::Base
|
31
|
+
after_save :sync
|
32
|
+
after_destroy :sync
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def sync
|
39
|
+
Thread.current[ :changed_models ] << self
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
module InstanceMethods
|
47
|
+
|
48
|
+
def sync
|
49
|
+
self.class.sync
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/apiway/path.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
module Apiway
|
2
|
+
|
3
|
+
module Resource
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def included( base )
|
10
|
+
base.class_eval do
|
11
|
+
extend ClassMethods
|
12
|
+
include InstanceMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def depend_on( *models )
|
23
|
+
models.empty? ? @depend_on ||= [] : @depend_on = models
|
24
|
+
end
|
25
|
+
|
26
|
+
def access( &block )
|
27
|
+
block_given? ? @access = block : @access ||= Proc.new {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def data( &block )
|
31
|
+
block_given? ? @data = block : @data
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
module InstanceMethods
|
39
|
+
|
40
|
+
def initialize( id, client )
|
41
|
+
@id = id
|
42
|
+
@client = client
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_params( params = {} )
|
46
|
+
@params = params
|
47
|
+
@current_error = nil
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def sync_changes( changed_models )
|
52
|
+
sync if self.class.depend_on.any? { |dependency| changed_models.include? dependency }
|
53
|
+
end
|
54
|
+
|
55
|
+
def sync
|
56
|
+
begin
|
57
|
+
instance_eval &self.class.access
|
58
|
+
rescue ResourceError => e
|
59
|
+
sync_error e.params
|
60
|
+
else
|
61
|
+
sync_data instance_eval &self.class.data
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
attr_reader :client, :params
|
69
|
+
|
70
|
+
def error( params )
|
71
|
+
raise ResourceError, params
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def sync_params( error: nil, full: nil, patch: nil )
|
78
|
+
params = { id: @id }
|
79
|
+
params[ :error ] = error if error
|
80
|
+
params[ :full ] = full if full
|
81
|
+
params[ :patch ] = patch if patch
|
82
|
+
params
|
83
|
+
end
|
84
|
+
|
85
|
+
def sync_error( error )
|
86
|
+
new_error_json = JSON.generate error, quirks_mode: true
|
87
|
+
if !@current_error || @current_error != new_error_json
|
88
|
+
@current_error = new_error_json
|
89
|
+
@client.trigger RESOURCE::SYNC, sync_params( error: error )
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def sync_data( data )
|
94
|
+
@current_error = nil
|
95
|
+
new_data_json = JSON.generate data, quirks_mode: true
|
96
|
+
if !@current_data || @current_data != new_data_json
|
97
|
+
patch = Diff.new( @current_data, new_data_json ).patch
|
98
|
+
patch_json = JSON.generate patch, quirks_mode: true
|
99
|
+
params_sync = @current_data && patch_json.size < new_data_json.size ? sync_params( patch: patch ) : sync_params( full: data )
|
100
|
+
@current_data = new_data_json
|
101
|
+
@client.trigger RESOURCE::SYNC, params_sync
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
data/lib/apiway.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/activerecord'
|
4
|
+
require 'sinatra/contrib'
|
5
|
+
require 'sinatra-websocket'
|
6
|
+
|
7
|
+
require 'apiway/logger'
|
8
|
+
require 'apiway/errors'
|
9
|
+
require 'apiway/diff'
|
10
|
+
require 'apiway/events'
|
11
|
+
require 'apiway/extensions'
|
12
|
+
require 'apiway/path'
|
13
|
+
require 'apiway/client'
|
14
|
+
require 'apiway/controller'
|
15
|
+
require 'apiway/resource'
|
16
|
+
require 'apiway/model'
|
17
|
+
require 'apiway/application'
|
@@ -0,0 +1 @@
|
|
1
|
+
*.sqlite3
|
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec thin --max-conns 3000 --max-persistent-conns 1500 start -p $PORT
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
development:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: db/development.sqlite3
|
4
|
+
pool: 5
|
5
|
+
timeout: 5000
|
6
|
+
|
7
|
+
test:
|
8
|
+
adapter: sqlite3
|
9
|
+
database: db/test.sqlite3
|
10
|
+
pool: 5
|
11
|
+
timeout: 5000
|
12
|
+
|
13
|
+
production:
|
14
|
+
adapter: postgresql
|
15
|
+
database: pg_production
|
16
|
+
pool: 5
|
17
|
+
timeout: 5000
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class <%= classname %>Controller < ApplicationController
|
2
|
+
|
3
|
+
include Apiway::Controller
|
4
|
+
|
5
|
+
|
6
|
+
# before_action :auth?
|
7
|
+
|
8
|
+
# action :new do
|
9
|
+
#
|
10
|
+
# begin
|
11
|
+
# <%= modelname %>.create! params
|
12
|
+
# rescue Exception => e
|
13
|
+
# error e.message
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# end
|
17
|
+
|
18
|
+
# def auth?
|
19
|
+
# error :auth_error unless client[ :user_id ]
|
20
|
+
# end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class <%= classname %>Resource < ApplicationResource
|
2
|
+
|
3
|
+
include Apiway::Resource
|
4
|
+
|
5
|
+
depend_on <%= modelname %>
|
6
|
+
|
7
|
+
|
8
|
+
access do
|
9
|
+
# auth?
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
data do
|
14
|
+
|
15
|
+
# <%= modelname %>.limit( params[ :limit ] ).map do |<%= varname %>|
|
16
|
+
# {
|
17
|
+
# id: <%= varname %>.id,
|
18
|
+
# name: <%= varname %>.name
|
19
|
+
# }
|
20
|
+
# end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# def auth?
|
26
|
+
# error :auth_error unless client[ :user_id ]
|
27
|
+
# end
|
28
|
+
|
29
|
+
end
|