rails2lb4 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 17a1f0ccbd6c81c97d997cba4184988c8a6932b50091bd6ce5d4123621159258
4
+ data.tar.gz: 23f60cfdffac43b3fa4e23e63db2096e4b3761556521c861c5a82ef863a37776
5
+ SHA512:
6
+ metadata.gz: 803ccfbdb19c79a9f07dc07975fb215bbaaa3044b7c682f9efdc126e4ef3d1a95653a9a9b8cf58165f5f4f4185a619f8ec7ce9941c51fa533359f3778b8b11f6
7
+ data.tar.gz: 26175cd91f0588e6728a0af73284e46f4157250b5d26ec24a080d8e7814e91b7e0f8056d13d1fbc2df922beb7174a7db62067c3ca5003a509c446b05f101fe50
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ MIT license
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,68 @@
1
+ **Warning**: this application is only demo quality at the moment. Do not use on
2
+ an existing loopback4 appication is not under version control where all of the
3
+ changes have already been committed as this application may overwrite files.
4
+
5
+ This tool will create a loopback4 model, respository, and datasource based on
6
+ an existing Rails application.
7
+
8
+ Step 0
9
+ ------
10
+
11
+ Install `rails` and/or `loopback4` if they are not already installed:
12
+
13
+ gem install rails
14
+ npm install -g loopback-cli
15
+
16
+ Note: in order to install these tools, you need to have previously installed `ruby`, `node`, `npm` and other tools. Check the installation instructions for
17
+ [rails](https://guides.rubyonrails.org/getting_started.html#installing-rails) and
18
+ [loopback4](https://loopback.io/doc/en/lb4/Getting-started.html) for details.
19
+
20
+ Step 1
21
+ ------
22
+
23
+ Install this tool:
24
+
25
+ gem install rails2lb4
26
+
27
+ Step 2
28
+ ------
29
+
30
+ Locate a Rails application. If you don't already have one, you can follow the [Creating the Blog Application](https://guides.rubyonrails.org/getting_started.html#creating-the-blog-application) in the Rails guide, or
31
+ clone it from [https://github.com/rubys/railsguide_blog](https://github.com/rubys/railsguide_blog.git).
32
+
33
+ Step 3
34
+ ------
35
+
36
+ Locate or create a new loopback application. To create a new application:
37
+
38
+ lb4 app blog
39
+
40
+ Step 4
41
+ ------
42
+
43
+ Run the tool, specifying the path to the source rails and destination loopback applications:
44
+
45
+ rails2lb4 /path/to/rails/blog /path/to/loopback4/blog
46
+
47
+ Note: by default, this tool will set up the loopback application to access the Rails `development` database. If you would like to access another database, set the `RAILS_ENV` environment variable before running this step.
48
+
49
+
50
+ Step 5 (optional)
51
+ -----------------
52
+
53
+ Create REST controllers for the new models:
54
+
55
+ lb4 controller article
56
+ lb4 controller comment
57
+
58
+ Note: specify `number` as the type of `id` for these controllers.
59
+
60
+ Step 6 (optional)
61
+ -----------------
62
+
63
+ Start the loopback4 server:
64
+
65
+ npm start
66
+
67
+ Note: by default, both Rails and Loopback4 default to listen to port 3000. Be sure to stop your Rails server before starting your loopback4 server.
68
+
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ source = target = Dir.pwd
4
+
5
+ if ARGV.length == 2
6
+ source, target = ARGV
7
+ elsif ARGV.length == 1
8
+ if File.exist? File.expand_path('Rakefile', ARGV.first)
9
+ source = File.expand_path(ARGV.first)
10
+ elsif File.exist? File.expand_path('index.ts', ARGV.first)
11
+ target = File.expand_path(ARGV.first)
12
+ end
13
+ else
14
+ STDERR.puts "Usage: #{$0} [source] [target]"
15
+ exit 1
16
+ end
17
+
18
+ unless File.exist? File.expand_path('Rakefile', source)
19
+ STDERR.puts 'source directory is not a Rails app'
20
+ exit 1
21
+ end
22
+
23
+ unless File.exist? File.expand_path('index.ts', target)
24
+ STDERR.puts 'target directory is not a lb4 app'
25
+ exit 1
26
+ end
27
+
28
+ require 'rails2lb4'
29
+
30
+ rails2lb4 source, target
@@ -0,0 +1,137 @@
1
+ require 'erubis'
2
+ require 'ansi'
3
+ require 'yaml'
4
+ require 'json'
5
+
6
+ require 'active_support/core_ext/string'
7
+ require 'active_support/inflector'
8
+
9
+ def rails2lb4(source, target)
10
+ # import custom pluralization
11
+ if File.exist? "#{source}/config/initializers/inflections.rb"
12
+ require "#{source}/config/initializers/inflections.rb"
13
+ end
14
+
15
+ # define a write operation that colorizes output and determines if the
16
+ # output represent new content or a change.
17
+ def target.write path, contents
18
+ dest = File.join(self, path)
19
+ if File.size?(dest) and IO.read(dest) == contents
20
+ puts ANSI.blue { 'skipping ' } + path
21
+ else
22
+ if File.size?(dest)
23
+ puts ANSI.bold { ANSI.magenta { 'updating ' } } + path
24
+ else
25
+ puts ANSI.bold { ANSI.green { 'creating ' } } + path
26
+ end
27
+ IO.write dest, contents
28
+ end
29
+ end
30
+
31
+ # determine the database type from the configuration
32
+ environment = ENV['RAILS_ENV'] || 'development'
33
+ database = YAML.load_file("#{source}/config/database.yml")
34
+ @adapter = database[environment]['adapter']
35
+
36
+ # common configuration
37
+ config = {
38
+ name: @adapter,
39
+ connector: "loopback-connector-#{@adapter}"
40
+ }
41
+
42
+ # database specific configuration
43
+ if @adapter == 'sqlite3'
44
+ config[:file] = File.expand_path(database[environment]['database'], source)
45
+
46
+ Dir.chdir target do
47
+ unless IO.read('package.json').include? 'loopback-connector-sqlite3'
48
+ system 'npm install loopback-connector-sqlite3 --save'
49
+ end
50
+ end
51
+
52
+ elsif @adapter == 'mysql' or @adapter == 'postgresql'
53
+ environment = database[environment]
54
+ %w(database host password.port username).each do |property|
55
+ config[property] = environment[property] if environment[property]
56
+ end
57
+
58
+ if @adapter == 'mysql'
59
+ config[:socketPath] = environtment[:socket] if environment[:socket]
60
+ config[:connectionLimit] = environtment[:pool] if environment[:pool]
61
+ end
62
+ end
63
+
64
+ # produce datasource.ts
65
+ template = File.read(File.join(__dir__, '../templates/datasource.erb'))
66
+ datasource = Erubis::Eruby.new(template).result(binding)
67
+ path = File.join('src', 'datasources', "#{@adapter}.datasource.ts")
68
+ target.write path, datasource
69
+
70
+ # produce datasource.json
71
+ path = File.join('src', 'datasources', "#{@adapter}.datasource.json")
72
+ target.write path, JSON.pretty_generate(config)
73
+
74
+ # produce datasource/index.ts
75
+ index = Dir["#{target}/src/datasources/*.datasource.ts"].sort.
76
+ map {|file| "export * from './#{File.basename(file, '.ts')}';"}.
77
+ join("\n") + "\n"
78
+ target.write 'src/datasources/index.ts', index
79
+
80
+ # parse schema.rb from the source
81
+ schema = IO.read("#{source}/db/schema.rb")
82
+ table = /^\s+create_table "([^"]+)",.*?\n(.*?)\n\s+end/m
83
+
84
+ data_types = {
85
+ "integer" => "number",
86
+ "float" => "number",
87
+ "text" => "string",
88
+ "boolean" => "boolean",
89
+ "date" => "Date",
90
+ "datetime" => "Date",
91
+ }
92
+
93
+ tables = {}
94
+ schema.scan(table).each do |name, ddl|
95
+ cols = ddl.scan(/^\s+t\.(\w+)\s+"(\w+)/).
96
+ map {|names| [names.last, data_types[names.first] || names.first]}.to_h
97
+ tables[name] = cols
98
+ end
99
+
100
+ # produce model.ts and repository.ts for each model
101
+ Dir["#{source}/app/models/*.rb"].sort.each do |file|
102
+ model = File.read(file)
103
+ basename = File.basename(file, '.rb')
104
+ @table = tables[basename.pluralize] || {}
105
+ @class_name = model[/class (\w+)/, 1]
106
+ @table_name = @class_name.downcase.pluralize
107
+
108
+ @belongs_to = model.scan(/^\s+belongs_to\s*:(\w+)/).
109
+ map {|(name)| [name, name.camelcase]}.to_h
110
+ @has_many = model.scan(/^\s+has_many\s*:(\w+)/).
111
+ map {|(name)| [name.singularize, name.singularize.camelcase]}.to_h
112
+
113
+ template = File.read(File.join(__dir__, '../templates/model.erb'))
114
+ model = Erubis::Eruby.new(template).result(binding)
115
+
116
+ path = File.join('src', 'models', basename+'.model.ts')
117
+ target.write path, model
118
+
119
+ template = File.read(File.join(__dir__, '../templates/repository.erb'))
120
+ repository = Erubis::Eruby.new(template).result(binding)
121
+
122
+ path = File.join('src', 'repositories', basename+'.repository.ts')
123
+ target.write path, repository
124
+ end
125
+
126
+ # produce model.index.ts
127
+ index = Dir["#{target}/src/models/*.model.ts"].sort.
128
+ map {|file| "export * from './#{File.basename(file, '.ts')}';"}.
129
+ join("\n") + "\n"
130
+ target.write 'src/models/index.ts', index
131
+
132
+ # produce repositories.index.ts
133
+ index = Dir["#{target}/src/repositories/*.repository.ts"].sort.
134
+ map {|file| "export * from './#{File.basename(file, '.ts')}';"}.
135
+ join("\n") + "\n"
136
+ target.write 'src/repositories/index.ts', index
137
+ end
@@ -0,0 +1,14 @@
1
+ import {inject} from '@loopback/core';
2
+ import {juggler} from '@loopback/repository';
3
+ import * as config from './<%= @adapter %>.datasource.json';
4
+
5
+ export class Sqlite3DataSource extends juggler.DataSource {
6
+ static dataSourceName = '<%= @adapter %>';
7
+
8
+ constructor(
9
+ @inject('datasources.config.<%= @adapter %>', {optional: true})
10
+ dsConfig: object = config,
11
+ ) {
12
+ super(dsConfig);
13
+ }
14
+ }
@@ -0,0 +1,42 @@
1
+ <%
2
+ imports = %w{Entity property model}
3
+ imports << 'belongsTo' unless @belongs_to.empty?
4
+ imports << 'hasMany' unless @has_many.empty?
5
+ %>
6
+ import {<%= imports.join(', ') %>} from '@loopback/repository';
7
+ <% @belongs_to.merge(@has_many).each do |name, value| %>
8
+ import {<%= value %>} from './<%= name %>.model';
9
+ <% end %>
10
+
11
+ @model({settings: {<%= @adapter %>: {table: '<%= @table_name %>'}}})
12
+ export class <%= @class_name %> extends Entity {
13
+ @property({
14
+ type: 'number',
15
+ id: true
16
+ })
17
+ id: number;
18
+ <% @table.each do |attr, value| %>
19
+
20
+ <% if @belongs_to.keys.any? {|key| "#{key}_id" == attr} %>
21
+ @belongsTo(() => <%= @belongs_to[attr.sub(/_id/, '')] %>, {keyTo: 'id'})
22
+ <% else %>
23
+ @property({
24
+ type: '<%= value %>'
25
+ })
26
+ <% end %>
27
+ <%= attr %>: <%= value %>;
28
+ <% end %>
29
+ <% @has_many.each do |name, value| %>
30
+
31
+ @hasMany(() => <%= value %>, {keyTo: '<%= @class_name.downcase %>_id'})
32
+ <%= name.pluralize %>: <%= value %>[];
33
+ <% end %>
34
+
35
+ getId() {
36
+ return this.id;
37
+ }
38
+
39
+ constructor(data?: Partial<<%= @class_name %>>) {
40
+ super(data);
41
+ }
42
+ }
@@ -0,0 +1,15 @@
1
+ import {DefaultCrudRepository, juggler} from '@loopback/repository';
2
+ import {<%= @class_name %>} from '../models';
3
+ import {Sqlite3DataSource} from '../datasources';
4
+ import {inject} from '@loopback/core';
5
+
6
+ export class <%= @class_name %>Repository extends DefaultCrudRepository<
7
+ <%= @class_name %>,
8
+ typeof <%= @class_name %>.prototype.id
9
+ > {
10
+ constructor(
11
+ @inject('datasources.sqlite3') dataSource: Sqlite3DataSource,
12
+ ) {
13
+ super(<%= @class_name %>, dataSource);
14
+ }
15
+ }
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails2lb4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sam Ruby
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ansi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: erubis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Builds a loopback4 datasource, model, and repository from Rails schema.rb,
42
+ database.yml, and model sources
43
+ email:
44
+ - rubys@intertwingly.net
45
+ executables:
46
+ - rails2lb4
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE
51
+ - README.md
52
+ - bin/rails2lb4
53
+ - lib/rails2lb4.rb
54
+ - templates/datasource.erb
55
+ - templates/model.erb
56
+ - templates/repository.erb
57
+ homepage: http://github.com/rubys/rails2lb4
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.7.4
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Convert Rails model to loopback4
81
+ test_files: []