camille 1.0.0 → 1.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +6 -2
- data/README.md +3 -1
- data/lib/camille/code_generator.rb +29 -12
- data/lib/camille/main_controller.rb +1 -1
- data/lib/camille/schema.rb +13 -1
- data/lib/camille/schema_literal_generator.rb +51 -0
- data/lib/camille/schemas.rb +1 -41
- data/lib/camille/type_literal_generator.rb +14 -0
- data/lib/camille/types.rb +1 -4
- data/lib/camille/version.rb +1 -1
- data/lib/camille.rb +3 -1
- metadata +5 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 82a091b46cd7266990fb540e54febefd78773260f780283d624fa88321090d81
|
|
4
|
+
data.tar.gz: 33a660f689f967f3be04e9bc70b15214fa28d36c74df223357f66dbe17bce7b1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 32442ecdc91cd62092d3d49ce67c6cfe2ccedaeb1a285a1e6f44615792ce9408d8d245690cb96ff269853a72d3807080f1bdcb88639439b4e957a4d8ced726f4
|
|
7
|
+
data.tar.gz: 21398e4687f2a7e3f56b06b86ad1c86a80bbe8719c57227a413df09ad7251c28e86af89145b9656243d80c68b9eeb4a9dea412b1a6e67c6189cc6b55d2af943f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
* Added `TypeLiteralGenerator` and `SchemaLiteralGenerator` to allow partial endpoint generation with `CodeGenerator`.
|
|
8
|
+
|
|
9
|
+
## 1.1.0
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
* Added support for HTTP verbs `put`, `patch` and `delete`.
|
|
14
|
+
|
|
3
15
|
## 1.0.0
|
|
4
16
|
|
|
5
17
|
### Changed
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
camille (
|
|
4
|
+
camille (1.1.0)
|
|
5
5
|
rails (>= 6.1, < 8.1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -108,6 +108,7 @@ GEM
|
|
|
108
108
|
net-smtp
|
|
109
109
|
marcel (1.0.4)
|
|
110
110
|
mini_mime (1.1.5)
|
|
111
|
+
mini_portile2 (2.8.9)
|
|
111
112
|
minitest (5.25.4)
|
|
112
113
|
net-imap (0.5.6)
|
|
113
114
|
date
|
|
@@ -119,6 +120,9 @@ GEM
|
|
|
119
120
|
net-smtp (0.5.1)
|
|
120
121
|
net-protocol
|
|
121
122
|
nio4r (2.7.4)
|
|
123
|
+
nokogiri (1.17.2)
|
|
124
|
+
mini_portile2 (~> 2.8.2)
|
|
125
|
+
racc (~> 1.4)
|
|
122
126
|
nokogiri (1.17.2-x86_64-linux)
|
|
123
127
|
racc (~> 1.4)
|
|
124
128
|
psych (5.2.1)
|
|
@@ -210,4 +214,4 @@ DEPENDENCIES
|
|
|
210
214
|
rspec-rails
|
|
211
215
|
|
|
212
216
|
BUNDLED WITH
|
|
213
|
-
2.2
|
|
217
|
+
2.7.2
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Camille
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
## Why?
|
|
4
6
|
|
|
5
7
|
Traditionally, the JSON response from a Rails API server isn't typed. So even if we have TypeScript at the front-end, we still have little guarantee that our back-end would return the correct type and structure of data.
|
|
@@ -90,7 +92,7 @@ The `params` type for an endpoint is required to be an object type, or a hash in
|
|
|
90
92
|
|
|
91
93
|
Camille will automatically add a Rails route for each endpoint. You don't need to do anything other than having the schema file in place.
|
|
92
94
|
|
|
93
|
-
When defining an endpoint, you can
|
|
95
|
+
When defining an endpoint, you can use any of `get`, `post`, `put`, `patch`, or `delete`.
|
|
94
96
|
|
|
95
97
|
### Custom types
|
|
96
98
|
|
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
require 'stringio'
|
|
2
2
|
|
|
3
3
|
module Camille
|
|
4
|
-
|
|
5
|
-
def
|
|
4
|
+
class CodeGenerator
|
|
5
|
+
def initialize types_literal_lines: Camille::Types.literal_lines, schemas_literal_lines: Camille::Schemas.literal_lines
|
|
6
|
+
@types_literal_lines = types_literal_lines
|
|
7
|
+
@schemas_literal_lines = schemas_literal_lines
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def generate_ts
|
|
6
11
|
io = StringIO.new
|
|
7
|
-
io
|
|
8
|
-
io
|
|
9
|
-
|
|
10
|
-
io.puts "export #{line}"
|
|
11
|
-
end
|
|
12
|
-
io.puts
|
|
13
|
-
io.print "export default "
|
|
14
|
-
Camille::Schemas.literal_lines.each do |line|
|
|
15
|
-
io.puts line
|
|
16
|
-
end
|
|
12
|
+
generate_header io
|
|
13
|
+
generate_types io
|
|
14
|
+
generate_schemas io
|
|
17
15
|
io.string
|
|
18
16
|
end
|
|
19
17
|
|
|
18
|
+
private
|
|
19
|
+
def generate_header io
|
|
20
|
+
io.puts Camille::Configuration.ts_header
|
|
21
|
+
io.puts
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def generate_types io
|
|
25
|
+
@types_literal_lines.each do |line|
|
|
26
|
+
io.puts "export #{line}"
|
|
27
|
+
end
|
|
28
|
+
io.puts
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def generate_schemas io
|
|
32
|
+
io.print "export default "
|
|
33
|
+
@schemas_literal_lines.each do |line|
|
|
34
|
+
io.puts line
|
|
35
|
+
end
|
|
36
|
+
end
|
|
20
37
|
end
|
|
21
38
|
end
|
data/lib/camille/schema.rb
CHANGED
|
@@ -46,5 +46,17 @@ module Camille
|
|
|
46
46
|
def self.post name, &block
|
|
47
47
|
define_endpoint :post, name, &block
|
|
48
48
|
end
|
|
49
|
+
|
|
50
|
+
def self.put name, &block
|
|
51
|
+
define_endpoint :put, name, &block
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.patch name, &block
|
|
55
|
+
define_endpoint :patch, name, &block
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.delete name, &block
|
|
59
|
+
define_endpoint :delete, name, &block
|
|
60
|
+
end
|
|
49
61
|
end
|
|
50
|
-
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Camille
|
|
2
|
+
class SchemaLiteralGenerator
|
|
3
|
+
def initialize schemas
|
|
4
|
+
@schemas = schemas
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def literal_lines
|
|
8
|
+
[
|
|
9
|
+
Camille::Line.new('{'),
|
|
10
|
+
tree_literal_lines(namespace_tree).map(&:do_indent),
|
|
11
|
+
Camille::Line.new('}')
|
|
12
|
+
]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
def namespace_tree
|
|
17
|
+
tree = {}
|
|
18
|
+
|
|
19
|
+
@schemas.sort_by(&:klass_name).each do |s|
|
|
20
|
+
path = s.klass_name.split('::')
|
|
21
|
+
*namespaces, schema_name = path
|
|
22
|
+
|
|
23
|
+
level = namespaces.inject(tree) do |level, namespace|
|
|
24
|
+
level[namespace] ||= {}
|
|
25
|
+
level[namespace]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
level[schema_name] = s
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
tree
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def tree_literal_lines tree
|
|
35
|
+
tree.map do |key, value|
|
|
36
|
+
if value.is_a? ::Hash
|
|
37
|
+
[
|
|
38
|
+
Camille::Line.new("#{Camille::Configuration.response_key_converter.call(key.to_s)}: {"),
|
|
39
|
+
tree_literal_lines(value).map(&:do_indent),
|
|
40
|
+
Camille::Line.new('},')
|
|
41
|
+
]
|
|
42
|
+
else
|
|
43
|
+
value.literal_lines.tap do |lines|
|
|
44
|
+
lines.first.prepend("#{Camille::Configuration.response_key_converter.call(key.to_s)}: ")
|
|
45
|
+
lines.last.append(',')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end.flatten
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/camille/schemas.rb
CHANGED
|
@@ -1,47 +1,7 @@
|
|
|
1
1
|
module Camille
|
|
2
2
|
module Schemas
|
|
3
3
|
def self.literal_lines
|
|
4
|
-
|
|
5
|
-
Camille::Line.new('{'),
|
|
6
|
-
tree_literal_lines(namespace_tree).map(&:do_indent),
|
|
7
|
-
Camille::Line.new('}')
|
|
8
|
-
]
|
|
4
|
+
Camille::SchemaLiteralGenerator.new(Camille::Loader.loaded_schemas).literal_lines
|
|
9
5
|
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
def self.namespace_tree
|
|
13
|
-
tree = {}
|
|
14
|
-
|
|
15
|
-
Camille::Loader.loaded_schemas.sort_by(&:klass_name).each do |s|
|
|
16
|
-
path = s.klass_name.split('::')
|
|
17
|
-
*namespaces, schema_name = path
|
|
18
|
-
|
|
19
|
-
level = namespaces.inject(tree) do |level, namespace|
|
|
20
|
-
level[namespace] ||= {}
|
|
21
|
-
level[namespace]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
level[schema_name] = s
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
tree
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.tree_literal_lines tree
|
|
31
|
-
tree.map do |key, value|
|
|
32
|
-
if value.is_a? ::Hash
|
|
33
|
-
[
|
|
34
|
-
Camille::Line.new("#{Camille::Configuration.response_key_converter.call(key.to_s)}: {"),
|
|
35
|
-
tree_literal_lines(value).map(&:do_indent),
|
|
36
|
-
Camille::Line.new('},')
|
|
37
|
-
]
|
|
38
|
-
else
|
|
39
|
-
value.literal_lines.tap do |lines|
|
|
40
|
-
lines.first.prepend("#{Camille::Configuration.response_key_converter.call(key.to_s)}: ")
|
|
41
|
-
lines.last.append(',')
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end.flatten
|
|
45
|
-
end
|
|
46
6
|
end
|
|
47
7
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Camille
|
|
2
|
+
class TypeLiteralGenerator
|
|
3
|
+
def initialize types
|
|
4
|
+
@types = types
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def literal_lines
|
|
8
|
+
@types.sort_by(&:klass_name).map do |type|
|
|
9
|
+
instance = type.new
|
|
10
|
+
Camille::Line.new("type #{instance.literal} = #{instance.underlying.literal}")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/camille/types.rb
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
module Camille
|
|
2
2
|
module Types
|
|
3
3
|
def self.literal_lines
|
|
4
|
-
Camille::Loader.loaded_types
|
|
5
|
-
instance = type.new
|
|
6
|
-
Camille::Line.new("type #{instance.literal} = #{instance.underlying.literal}")
|
|
7
|
-
end
|
|
4
|
+
Camille::TypeLiteralGenerator.new(Camille::Loader.loaded_types).literal_lines
|
|
8
5
|
end
|
|
9
6
|
end
|
|
10
7
|
end
|
data/lib/camille/version.rb
CHANGED
data/lib/camille.rb
CHANGED
|
@@ -40,6 +40,8 @@ require_relative "camille/railtie"
|
|
|
40
40
|
require_relative "camille/controller"
|
|
41
41
|
require_relative "camille/loader"
|
|
42
42
|
require_relative "camille/configuration"
|
|
43
|
+
require_relative "camille/type_literal_generator"
|
|
44
|
+
require_relative "camille/schema_literal_generator"
|
|
43
45
|
require_relative "camille/code_generator"
|
|
44
46
|
require_relative "camille/main_controller"
|
|
45
47
|
require_relative "camille/key_converter"
|
|
@@ -57,6 +59,6 @@ module Camille
|
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
def self.generate_ts
|
|
60
|
-
Camille::CodeGenerator.generate_ts
|
|
62
|
+
Camille::CodeGenerator.new.generate_ts
|
|
61
63
|
end
|
|
62
64
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: camille
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- merely
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -77,11 +76,13 @@ files:
|
|
|
77
76
|
- lib/camille/railtie.rb
|
|
78
77
|
- lib/camille/rendered.rb
|
|
79
78
|
- lib/camille/schema.rb
|
|
79
|
+
- lib/camille/schema_literal_generator.rb
|
|
80
80
|
- lib/camille/schemas.rb
|
|
81
81
|
- lib/camille/syntax.rb
|
|
82
82
|
- lib/camille/type.rb
|
|
83
83
|
- lib/camille/type_error.rb
|
|
84
84
|
- lib/camille/type_error_printer.rb
|
|
85
|
+
- lib/camille/type_literal_generator.rb
|
|
85
86
|
- lib/camille/types.rb
|
|
86
87
|
- lib/camille/types/any.rb
|
|
87
88
|
- lib/camille/types/array.rb
|
|
@@ -107,7 +108,6 @@ licenses:
|
|
|
107
108
|
metadata:
|
|
108
109
|
homepage_uri: https://github.com/onyxblade/camille
|
|
109
110
|
source_code_uri: https://github.com/onyxblade/camille
|
|
110
|
-
post_install_message:
|
|
111
111
|
rdoc_options: []
|
|
112
112
|
require_paths:
|
|
113
113
|
- lib
|
|
@@ -122,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: '0'
|
|
124
124
|
requirements: []
|
|
125
|
-
rubygems_version: 3.
|
|
126
|
-
signing_key:
|
|
125
|
+
rubygems_version: 3.6.9
|
|
127
126
|
specification_version: 4
|
|
128
127
|
summary: Typed API schema for Rails with TypeScript codegen
|
|
129
128
|
test_files: []
|