Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/finitio/typescript.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Finitio
module Typescript
class Error < Finitio::Error; end
end # module Typescript
end # module Finitio
require_relative 'typescript/type'
require_relative 'typescript/ad_type'
require_relative 'typescript/any_type'
require_relative 'typescript/alias_type'
require_relative 'typescript/builtin_type'
require_relative 'typescript/hash_based_type'
require_relative 'typescript/high_order_type'
require_relative 'typescript/rel_based_type'
require_relative 'typescript/seq_type'
require_relative 'typescript/set_type'
require_relative 'typescript/struct_type'
require_relative 'typescript/sub_type'
require_relative 'typescript/union_type'
require_relative 'typescript/proxy_type'
require_relative 'typescript/system'
9 changes: 9 additions & 0 deletions lib/finitio/typescript/ad_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Finitio
class AdType

def to_typescript(*args, &bl)
contracts.map{|c| c.infotype.ts_name || c.infotype.to_typescript(*args, &bl) }.join('|')
end

end # class AdType
end # module Finitio
9 changes: 9 additions & 0 deletions lib/finitio/typescript/alias_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Finitio
class AliasType

def to_typescript(*args, &bl)
target.ts_name || target.to_typescript
end

end # class AliasType
end # module Finitio
9 changes: 9 additions & 0 deletions lib/finitio/typescript/any_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Finitio
class AnyType

def to_typescript(*args, &bl)
"any"
end

end # class AnyType
end # module Finitio
32 changes: 32 additions & 0 deletions lib/finitio/typescript/builtin_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Finitio
module Typescript

BUILTIN_MAPPING = {
NilClass => "null",
String => "string",
Integer => "number",
Fixnum => "number",
Bignum => "number",
Float => "number",
Numeric => "number",
TrueClass => "boolean",
FalseClass => "boolean",
Object => "any",
DateTime => "Date",
Date => "Date"
}

end
class BuiltinType

def to_typescript(*args, &bl)
mapped = Typescript::BUILTIN_MAPPING[ruby_type]
if mapped
mapped
else
raise Typescript::Error, "Unable to map #{ruby_type} to json-schema"
end
end

end # class BuiltinType
end # module Finitio
35 changes: 35 additions & 0 deletions lib/finitio/typescript/hash_based_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Finitio
module HashBasedType

def to_typescript(*args, &bl)
defs = []

attrs = heading.inject([]) do |ps,a|
separator = a.required? ? ": " : "?: "
type = if a.type.is_a?(UnionType)
a.type.to_typescript
## TODO @llambeau @blambeau why do we assign default names to inline types anyway?
elsif a.type.name && a.type.name[0] == '{'
a.type.to_typescript
else
a.type.ts_name || a.type.to_typescript
end
ps + ["#{a.name}#{separator}#{type}"]
end

defs << "{ #{attrs.join(', ')} }" unless attrs.empty?

if heading.allow_extra?
extra = if heading.allow_extra.is_a?(Finitio::AliasType)
heading.allow_extra.ts_name
else
heading.allow_extra.to_typescript(*args, &bl)
end
defs << "{ [key: string]: #{extra} }"
end

defs.join(' & ')
end

end # module HashBasedType
end # module UnionType
11 changes: 11 additions & 0 deletions lib/finitio/typescript/high_order_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Finitio
class HighOrderType < Type
def to_typescript(*args, &bl)
defn.ts_name || defn.to_typescript(*args, &bl)
end

def ts_name
"#{super}<#{vars.join(', ')}>" if super
end
end # class HighOrderType
end # module Finitio
13 changes: 13 additions & 0 deletions lib/finitio/typescript/proxy_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Finitio
class ProxyType

def to_typescript(*args, &bl)
@target_name
end

def ts_name
@target_name
end

end # module ProxyType
end # module UnionType
9 changes: 9 additions & 0 deletions lib/finitio/typescript/rel_based_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Finitio
module RelBasedType

def to_typescript(*args, &bl)
"Set<#{tuple_type.to_typescript(*args, &bl)}>"
end

end # module RelBasedType
end # module Finitio
10 changes: 10 additions & 0 deletions lib/finitio/typescript/seq_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Finitio
class SeqType

def to_typescript(*args, &bl)
type_ts = elm_type.ts_name || elm_type.to_typescript(*args, &bl)
"Array<#{type_ts}>"
end

end # class SeqType
end # module Finitio
10 changes: 10 additions & 0 deletions lib/finitio/typescript/set_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Finitio
class SetType

def to_typescript(*args, &bl)
type = elm_type.to_typescript(*args, &bl)
"Set<#{type}>"
end

end # class SetType
end # module Finitio
10 changes: 10 additions & 0 deletions lib/finitio/typescript/struct_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Finitio
class StructType

def to_typescript(*args, &bl)
elms = component_types.map{|c| c.to_typescript(*args, &bl) }
"[#{elms.join(', ')}]"
end

end # class StructType
end # module Finitio
9 changes: 9 additions & 0 deletions lib/finitio/typescript/sub_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Finitio
class SubType

def to_typescript(*args, &bl)
super_type.ts_name
end

end # class SubType
end # module Finitio
10 changes: 10 additions & 0 deletions lib/finitio/typescript/system.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module Finitio
class System
def to_typescript(*args, &bl)
ts = types.map do |name, t|
"export type #{t.ts_name} = #{t.to_typescript(*args, &bl)}"
end
ts.join("\n")
end
end # class AdType
end # module Finitio
11 changes: 11 additions & 0 deletions lib/finitio/typescript/type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Finitio
class Type

TS_TYPE_UNALLOWED_CHARS = /[^<>a-zA-Z_$]/.freeze

def ts_name
@name.gsub(TS_TYPE_UNALLOWED_CHARS, '') if @name
end

end # class Type
end # module Finitio
21 changes: 21 additions & 0 deletions lib/finitio/typescript/union_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Finitio
class UnionType

FALSE_TYPE = BuiltinType.new(TrueClass)

TRUE_TYPE = BuiltinType.new(FalseClass)

BOOLEAN_TYPE = UnionType.new([TRUE_TYPE, FALSE_TYPE])

def to_typescript(*args, &bl)
return 'boolean' if self == BOOLEAN_TYPE
if candidates.size == 1
c = candidates.first
c.ts_name || c.to_typescript(*args, &bl)
else
candidates.map{|c| c.ts_name || c.to_typescript(*args, &bl) }.join('|')
end
end

end # class UnionType
end # module Finitio
5 changes: 5 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'finitio/syntax'
require 'finitio/generation'
require 'finitio/json_schema'
require 'finitio/typescript'

require 'coveralls'
Coveralls.wear!
Expand Down Expand Up @@ -74,6 +75,10 @@ def stringType
@stringType ||= Finitio::BuiltinType.new(String, "stringType")
end

def namespacedStringType
@stringType ||= Finitio::BuiltinType.new(String, "Namespace.String")
end

def byte_full
@byte_full ||= Finitio::Constraint.new(->(i){ i>=0 && i<=255 }, :byte)
end
Expand Down
15 changes: 15 additions & 0 deletions spec/typescript/test_ad_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Finitio
module Typescript
describe "AdType" do

let(:type) {
type = AdType.new(Color, [rgb_contract, hex_contract])
}

it 'works as expected' do
expect(type.to_typescript).to eql("intType|stringType")
end

end
end
end
15 changes: 15 additions & 0 deletions spec/typescript/test_alias_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Finitio
module Typescript
describe "AliasType" do

let(:alias_type) {
AliasType.new(anyType, "X")
}

it 'works as expected' do
expect(alias_type.to_typescript).to eql('any')
end

end
end
end
11 changes: 11 additions & 0 deletions spec/typescript/test_any_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Finitio
module Typescript
describe "AnyType" do

it 'works as expected' do
expect(anyType.to_typescript).to eql('any')
end

end
end
end
51 changes: 51 additions & 0 deletions spec/typescript/test_builtin_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Finitio
module Typescript
describe 'BuiltinType' do

let(:builtin_type) {
BuiltinType.new(ruby_type)
}

subject {
builtin_type.to_typescript
}

context 'with NilClass' do
let(:ruby_type){ NilClass }

it 'works' do
expect(subject).to eql('null')
end
end

context 'with String' do
let(:ruby_type){ String }

it 'works' do
expect(subject).to eql('string')
end
end

[Fixnum, Bignum, Integer].each do |rt|
context 'with #{rt}' do
let(:ruby_type){ rt }

it 'works' do
expect(subject).to eql('number')
end
end
end

[Float, Numeric].each do |rt|
context 'with #{rt}' do
let(:ruby_type){ rt }

it 'works' do
expect(subject).to eql('number')
end
end
end

end
end
end
39 changes: 39 additions & 0 deletions spec/typescript/test_multi_relation_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Finitio
module Typescript
describe "MultiRelationType" do

context 'with a true allow extra and some optional attribute' do
let(:heading){
Heading.new([
Attribute.new(:a, anyType),
Attribute.new(:b, anyType, false),
], allow_extra: true)
}

let(:multi_relation_type) {
MultiRelationType.new(heading)
}

it 'works as expected' do
expect(multi_relation_type.to_typescript).to eql("Set<{ a: any, b?: any } & { [key: string]: any }>")
end
end

context 'with a allow extra requiring Strings' do
let(:heading){
Heading.new([
], allow_extra: BuiltinType.new(String))
}

let(:multi_relation_type) {
MultiRelationType.new(heading)
}

it 'works as expected' do
expect(multi_relation_type.to_typescript).to eql("Set<{ [key: string]: string }>")
end
end

end
end
end
Loading