ledger_tiller_export 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +91 -0
- data/LICENSE.txt +21 -0
- data/README.md +162 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ledger_tiller_export.gemspec +32 -0
- data/lib/ledger_tiller_export.rb +180 -0
- data/lib/ledger_tiller_export/version.rb +4 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/addressable.rbi +199 -0
- data/sorbet/rbi/gems/declarative-option.rbi +24 -0
- data/sorbet/rbi/gems/declarative.rbi +75 -0
- data/sorbet/rbi/gems/faraday.rbi +316 -0
- data/sorbet/rbi/gems/google-api-client.rbi +4822 -0
- data/sorbet/rbi/gems/google_drive.rbi +360 -0
- data/sorbet/rbi/gems/googleauth.rbi +172 -0
- data/sorbet/rbi/gems/httpclient.rbi +810 -0
- data/sorbet/rbi/gems/jwt.rbi +68 -0
- data/sorbet/rbi/gems/ledger_gen.rbi +39 -0
- data/sorbet/rbi/gems/memoist.rbi +42 -0
- data/sorbet/rbi/gems/mini_mime.rbi +52 -0
- data/sorbet/rbi/gems/multi_json.rbi +62 -0
- data/sorbet/rbi/gems/multipart-post.rbi +53 -0
- data/sorbet/rbi/gems/nokogiri.rbi +1007 -0
- data/sorbet/rbi/gems/os.rbi +46 -0
- data/sorbet/rbi/gems/public_suffix.rbi +18 -0
- data/sorbet/rbi/gems/rake.rbi +636 -0
- data/sorbet/rbi/gems/representable.rbi +276 -0
- data/sorbet/rbi/gems/retriable.rbi +21 -0
- data/sorbet/rbi/gems/rspec-core.rbi +194 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +859 -0
- data/sorbet/rbi/gems/rspec-mocks.rbi +192 -0
- data/sorbet/rbi/gems/rspec-support.rbi +38 -0
- data/sorbet/rbi/gems/rspec.rbi +15 -0
- data/sorbet/rbi/gems/signet.rbi +121 -0
- data/sorbet/rbi/gems/uber.rbi +26 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +6574 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +11607 -0
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +8684 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +4222 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +111 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +543 -0
- metadata +190 -0
@@ -0,0 +1,180 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# typed: strict
|
3
|
+
|
4
|
+
require 'ledger_tiller_export/version'
|
5
|
+
require 'ledger_gen'
|
6
|
+
require 'set'
|
7
|
+
require 'google_drive'
|
8
|
+
require 'csv'
|
9
|
+
require 'open3'
|
10
|
+
require 'sorbet-runtime'
|
11
|
+
|
12
|
+
module LedgerTillerExport
|
13
|
+
class Row < T::Struct
|
14
|
+
extend T::Sig
|
15
|
+
|
16
|
+
prop :txn_date, Date
|
17
|
+
prop :txn_id, String
|
18
|
+
prop :account, String
|
19
|
+
prop :amount, Float
|
20
|
+
prop :description, String
|
21
|
+
|
22
|
+
sig {params(row: T::Hash[String, T.nilable(String)]).returns(Row)}
|
23
|
+
def self.from_csv_row(row)
|
24
|
+
new(
|
25
|
+
txn_date: Date.strptime(T.must(row["Date"]), "%m/%d/%Y"),
|
26
|
+
txn_id: T.must(row['Transaction ID']),
|
27
|
+
account: T.must(row['Account']),
|
28
|
+
amount: T.must(row["Amount"]).gsub('$', '').gsub(',', '').to_f,
|
29
|
+
description: T.must(row['Description']).gsub(/\+? /, '').capitalize,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module RuleInterface
|
35
|
+
extend T::Sig
|
36
|
+
extend T::Helpers
|
37
|
+
|
38
|
+
interface!
|
39
|
+
|
40
|
+
sig {abstract.params(row: Row).returns(T.nilable(String))}
|
41
|
+
def account_for_row(row); end
|
42
|
+
end
|
43
|
+
|
44
|
+
class RegexpRule < T::Struct
|
45
|
+
extend T::Sig
|
46
|
+
include RuleInterface
|
47
|
+
|
48
|
+
const :match, Regexp
|
49
|
+
const :account, String
|
50
|
+
|
51
|
+
sig {override.params(row: Row).returns(T.nilable(String))}
|
52
|
+
def account_for_row(row)
|
53
|
+
if match.match(row.description)
|
54
|
+
return account
|
55
|
+
end
|
56
|
+
|
57
|
+
nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Exporter
|
62
|
+
extend T::Sig
|
63
|
+
|
64
|
+
sig {returns(T::Array[RuleInterface])}
|
65
|
+
attr_reader :rules
|
66
|
+
|
67
|
+
sig {returns(String)}
|
68
|
+
attr_reader :spreadsheet
|
69
|
+
|
70
|
+
sig {returns(String)}
|
71
|
+
attr_reader :worksheet
|
72
|
+
|
73
|
+
sig {returns(String)}
|
74
|
+
attr_reader :default_account
|
75
|
+
|
76
|
+
sig {returns(String)}
|
77
|
+
attr_reader :ledger_pretty_print_options
|
78
|
+
|
79
|
+
sig {returns(GoogleDrive::Session)}
|
80
|
+
attr_reader :session
|
81
|
+
|
82
|
+
sig {returns(LedgerGen::Journal)}
|
83
|
+
attr_reader :journal
|
84
|
+
|
85
|
+
sig do
|
86
|
+
params(
|
87
|
+
rules: T::Array[RuleInterface],
|
88
|
+
spreadsheet: String,
|
89
|
+
worksheet: String,
|
90
|
+
default_account: String,
|
91
|
+
ledger_pretty_print_options: String,
|
92
|
+
ledger_date_format: String,
|
93
|
+
).void
|
94
|
+
end
|
95
|
+
def initialize(rules:, spreadsheet:, worksheet: 'Transactions', default_account: 'Expenses:Misc', ledger_pretty_print_options: '--sort=date', ledger_date_format: '%m/%d')
|
96
|
+
@rules = T.let(rules, T::Array[RuleInterface])
|
97
|
+
@spreadsheet = T.let(spreadsheet, String)
|
98
|
+
@worksheet = T.let(worksheet, String)
|
99
|
+
@default_account = T.let(default_account, String)
|
100
|
+
@ledger_pretty_print_options = T.let(ledger_pretty_print_options, String)
|
101
|
+
|
102
|
+
@session = T.let(GoogleDrive::Session.from_config('.config.json'), GoogleDrive::Session)
|
103
|
+
@journal = T.let(LedgerGen::Journal.new, LedgerGen::Journal)
|
104
|
+
|
105
|
+
@journal.date_format = ledger_date_format
|
106
|
+
end
|
107
|
+
|
108
|
+
sig {void}
|
109
|
+
def run
|
110
|
+
@known_transactions = T.let(fetch_known_transactions, T.nilable(T::Set[String]))
|
111
|
+
@known_transactions = T.must(@known_transactions)
|
112
|
+
|
113
|
+
worksheets = session.spreadsheet_by_key(spreadsheet).worksheets
|
114
|
+
|
115
|
+
ws = worksheets.detect { |w| w.title == worksheet }
|
116
|
+
raw_csv = ws.export_as_string.force_encoding('utf-8')
|
117
|
+
csv = CSV.parse(raw_csv, headers: true)
|
118
|
+
|
119
|
+
T.must(csv).each do |raw_row|
|
120
|
+
row = Row.from_csv_row(raw_row.to_h)
|
121
|
+
|
122
|
+
next if @known_transactions.include?(row.txn_id)
|
123
|
+
next if skip_row?(row)
|
124
|
+
|
125
|
+
journal_transaction(row)
|
126
|
+
end
|
127
|
+
|
128
|
+
puts @journal.pretty_print(@ledger_pretty_print_options)
|
129
|
+
end
|
130
|
+
|
131
|
+
sig {params(row: Row).returns(T::Boolean)}
|
132
|
+
def skip_row?(row)
|
133
|
+
false
|
134
|
+
end
|
135
|
+
|
136
|
+
sig {returns(T::Set[String])}
|
137
|
+
def fetch_known_transactions
|
138
|
+
cmd = [
|
139
|
+
'ledger',
|
140
|
+
%q{--register-format=%(tag("tiller_id"))\n},
|
141
|
+
'reg',
|
142
|
+
'expr',
|
143
|
+
'has_tag(/tiller_id/)',
|
144
|
+
]
|
145
|
+
|
146
|
+
raw_tags, err, status = Open3.capture3(*cmd)
|
147
|
+
|
148
|
+
if status.exitstatus && status.exitstatus != 0
|
149
|
+
STDERR.puts(err)
|
150
|
+
exit T.must(status.exitstatus)
|
151
|
+
end
|
152
|
+
|
153
|
+
Set.new(raw_tags.strip.split(/(\n|,)/).map(&:strip))
|
154
|
+
end
|
155
|
+
|
156
|
+
sig {params(row: Row).returns(String)}
|
157
|
+
def account_for_row(row)
|
158
|
+
rules.each do |rule|
|
159
|
+
account = rule.account_for_row(row)
|
160
|
+
return account if account
|
161
|
+
end
|
162
|
+
|
163
|
+
default_account
|
164
|
+
end
|
165
|
+
|
166
|
+
sig {params(row: Row).void}
|
167
|
+
def journal_transaction(row)
|
168
|
+
journal.transaction do |txn|
|
169
|
+
txn.cleared!
|
170
|
+
txn.date row.txn_date
|
171
|
+
txn.payee row.description
|
172
|
+
txn.comment "tiller_id: #{row.txn_id}"
|
173
|
+
|
174
|
+
txn.posting account_for_row(row), row.amount * -1
|
175
|
+
txn.posting row.account
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
data/sorbet/config
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
2
|
+
# srb rbi gems
|
3
|
+
|
4
|
+
# typed: strict
|
5
|
+
#
|
6
|
+
# If you would like to make changes to this file, great! Please create the gem's shim here:
|
7
|
+
#
|
8
|
+
# https://github.com/sorbet/sorbet-typed/new/master?filename=lib/addressable/all/addressable.rbi
|
9
|
+
#
|
10
|
+
# addressable-2.7.0
|
11
|
+
|
12
|
+
module Addressable
|
13
|
+
end
|
14
|
+
module Addressable::VERSION
|
15
|
+
end
|
16
|
+
module Addressable::IDNA
|
17
|
+
def self.lookup_unicode_combining_class(codepoint); end
|
18
|
+
def self.lookup_unicode_compatibility(codepoint); end
|
19
|
+
def self.lookup_unicode_composition(unpacked); end
|
20
|
+
def self.lookup_unicode_lowercase(codepoint); end
|
21
|
+
def self.punycode_adapt(delta, numpoints, firsttime); end
|
22
|
+
def self.punycode_basic?(codepoint); end
|
23
|
+
def self.punycode_decode(punycode); end
|
24
|
+
def self.punycode_decode_digit(codepoint); end
|
25
|
+
def self.punycode_delimiter?(codepoint); end
|
26
|
+
def self.punycode_encode(unicode); end
|
27
|
+
def self.punycode_encode_digit(d); end
|
28
|
+
def self.to_ascii(input); end
|
29
|
+
def self.to_unicode(input); end
|
30
|
+
def self.unicode_compose(unpacked); end
|
31
|
+
def self.unicode_compose_pair(ch_one, ch_two); end
|
32
|
+
def self.unicode_decompose(unpacked); end
|
33
|
+
def self.unicode_decompose_hangul(codepoint); end
|
34
|
+
def self.unicode_downcase(input); end
|
35
|
+
def self.unicode_normalize_kc(input); end
|
36
|
+
def self.unicode_sort_canonical(unpacked); end
|
37
|
+
end
|
38
|
+
class Addressable::IDNA::PunycodeBadInput < StandardError
|
39
|
+
end
|
40
|
+
class Addressable::IDNA::PunycodeBigOutput < StandardError
|
41
|
+
end
|
42
|
+
class Addressable::IDNA::PunycodeOverflow < StandardError
|
43
|
+
end
|
44
|
+
class Addressable::URI
|
45
|
+
def +(uri); end
|
46
|
+
def ==(uri); end
|
47
|
+
def ===(uri); end
|
48
|
+
def absolute?; end
|
49
|
+
def authority; end
|
50
|
+
def authority=(new_authority); end
|
51
|
+
def basename; end
|
52
|
+
def default_port; end
|
53
|
+
def defer_validation; end
|
54
|
+
def display_uri; end
|
55
|
+
def domain; end
|
56
|
+
def dup; end
|
57
|
+
def empty?; end
|
58
|
+
def eql?(uri); end
|
59
|
+
def extname; end
|
60
|
+
def fragment; end
|
61
|
+
def fragment=(new_fragment); end
|
62
|
+
def freeze; end
|
63
|
+
def hash; end
|
64
|
+
def host; end
|
65
|
+
def host=(new_host); end
|
66
|
+
def hostname; end
|
67
|
+
def hostname=(new_hostname); end
|
68
|
+
def inferred_port; end
|
69
|
+
def initialize(options = nil); end
|
70
|
+
def inspect; end
|
71
|
+
def ip_based?; end
|
72
|
+
def join!(uri); end
|
73
|
+
def join(uri); end
|
74
|
+
def merge!(uri); end
|
75
|
+
def merge(hash); end
|
76
|
+
def normalize!; end
|
77
|
+
def normalize; end
|
78
|
+
def normalized_authority; end
|
79
|
+
def normalized_fragment; end
|
80
|
+
def normalized_host; end
|
81
|
+
def normalized_password; end
|
82
|
+
def normalized_path; end
|
83
|
+
def normalized_port; end
|
84
|
+
def normalized_query(*flags); end
|
85
|
+
def normalized_scheme; end
|
86
|
+
def normalized_site; end
|
87
|
+
def normalized_user; end
|
88
|
+
def normalized_userinfo; end
|
89
|
+
def omit!(*components); end
|
90
|
+
def omit(*components); end
|
91
|
+
def origin; end
|
92
|
+
def origin=(new_origin); end
|
93
|
+
def password; end
|
94
|
+
def password=(new_password); end
|
95
|
+
def path; end
|
96
|
+
def path=(new_path); end
|
97
|
+
def port; end
|
98
|
+
def port=(new_port); end
|
99
|
+
def query; end
|
100
|
+
def query=(new_query); end
|
101
|
+
def query_values(return_type = nil); end
|
102
|
+
def query_values=(new_query_values); end
|
103
|
+
def relative?; end
|
104
|
+
def remove_composite_values; end
|
105
|
+
def replace_self(uri); end
|
106
|
+
def request_uri; end
|
107
|
+
def request_uri=(new_request_uri); end
|
108
|
+
def route_from(uri); end
|
109
|
+
def route_to(uri); end
|
110
|
+
def scheme; end
|
111
|
+
def scheme=(new_scheme); end
|
112
|
+
def self.convert_path(path); end
|
113
|
+
def self.encode(uri, return_type = nil); end
|
114
|
+
def self.encode_component(component, character_class = nil, upcase_encoded = nil); end
|
115
|
+
def self.escape(uri, return_type = nil); end
|
116
|
+
def self.form_encode(form_values, sort = nil); end
|
117
|
+
def self.form_unencode(encoded_value); end
|
118
|
+
def self.heuristic_parse(uri, hints = nil); end
|
119
|
+
def self.ip_based_schemes; end
|
120
|
+
def self.join(*uris); end
|
121
|
+
def self.normalize_component(component, character_class = nil, leave_encoded = nil); end
|
122
|
+
def self.normalize_path(path); end
|
123
|
+
def self.normalized_encode(uri, return_type = nil); end
|
124
|
+
def self.parse(uri); end
|
125
|
+
def self.port_mapping; end
|
126
|
+
def self.unencode(uri, return_type = nil, leave_encoded = nil); end
|
127
|
+
def self.unencode_component(uri, return_type = nil, leave_encoded = nil); end
|
128
|
+
def self.unescape(uri, return_type = nil, leave_encoded = nil); end
|
129
|
+
def self.unescape_component(uri, return_type = nil, leave_encoded = nil); end
|
130
|
+
def site; end
|
131
|
+
def site=(new_site); end
|
132
|
+
def split_path(path); end
|
133
|
+
def tld; end
|
134
|
+
def tld=(new_tld); end
|
135
|
+
def to_hash; end
|
136
|
+
def to_s; end
|
137
|
+
def to_str; end
|
138
|
+
def user; end
|
139
|
+
def user=(new_user); end
|
140
|
+
def userinfo; end
|
141
|
+
def userinfo=(new_userinfo); end
|
142
|
+
def validate; end
|
143
|
+
end
|
144
|
+
class Addressable::URI::InvalidURIError < StandardError
|
145
|
+
end
|
146
|
+
module Addressable::URI::CharacterClasses
|
147
|
+
end
|
148
|
+
class Addressable::Template
|
149
|
+
def ==(template); end
|
150
|
+
def eql?(template); end
|
151
|
+
def expand(mapping, processor = nil, normalize_values = nil); end
|
152
|
+
def extract(uri, processor = nil); end
|
153
|
+
def freeze; end
|
154
|
+
def generate(params = nil, recall = nil, options = nil); end
|
155
|
+
def initialize(pattern); end
|
156
|
+
def inspect; end
|
157
|
+
def join_values(operator, return_value); end
|
158
|
+
def keys; end
|
159
|
+
def match(uri, processor = nil); end
|
160
|
+
def named_captures; end
|
161
|
+
def names; end
|
162
|
+
def normalize_keys(mapping); end
|
163
|
+
def normalize_value(value); end
|
164
|
+
def ordered_variable_defaults; end
|
165
|
+
def parse_template_pattern(pattern, processor = nil); end
|
166
|
+
def partial_expand(mapping, processor = nil, normalize_values = nil); end
|
167
|
+
def pattern; end
|
168
|
+
def source; end
|
169
|
+
def to_regexp; end
|
170
|
+
def transform_capture(mapping, capture, processor = nil, normalize_values = nil); end
|
171
|
+
def transform_partial_capture(mapping, capture, processor = nil, normalize_values = nil); end
|
172
|
+
def variable_defaults; end
|
173
|
+
def variables; end
|
174
|
+
end
|
175
|
+
class Addressable::Template::InvalidTemplateValueError < StandardError
|
176
|
+
end
|
177
|
+
class Addressable::Template::InvalidTemplateOperatorError < StandardError
|
178
|
+
end
|
179
|
+
class Addressable::Template::TemplateOperatorAbortedError < StandardError
|
180
|
+
end
|
181
|
+
class Addressable::Template::MatchData
|
182
|
+
def [](key, len = nil); end
|
183
|
+
def captures; end
|
184
|
+
def initialize(uri, template, mapping); end
|
185
|
+
def inspect; end
|
186
|
+
def keys; end
|
187
|
+
def mapping; end
|
188
|
+
def names; end
|
189
|
+
def post_match; end
|
190
|
+
def pre_match; end
|
191
|
+
def string; end
|
192
|
+
def template; end
|
193
|
+
def to_a; end
|
194
|
+
def to_s; end
|
195
|
+
def uri; end
|
196
|
+
def values; end
|
197
|
+
def values_at(*indexes); end
|
198
|
+
def variables; end
|
199
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
2
|
+
# srb rbi gems
|
3
|
+
|
4
|
+
# typed: strict
|
5
|
+
#
|
6
|
+
# If you would like to make changes to this file, great! Please create the gem's shim here:
|
7
|
+
#
|
8
|
+
# https://github.com/sorbet/sorbet-typed/new/master?filename=lib/declarative-option/all/declarative-option.rbi
|
9
|
+
#
|
10
|
+
# declarative-option-0.1.0
|
11
|
+
|
12
|
+
module Declarative
|
13
|
+
def self.Option(value, options = nil); end
|
14
|
+
end
|
15
|
+
module Declarative::Callable
|
16
|
+
end
|
17
|
+
class Declarative::Option
|
18
|
+
def call(value, options = nil); end
|
19
|
+
def callable?(value, options); end
|
20
|
+
def lambda_for_callable(value, options); end
|
21
|
+
def lambda_for_proc(value, options); end
|
22
|
+
def lambda_for_static(value, options); end
|
23
|
+
def lambda_for_symbol(value, options); end
|
24
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# This file is autogenerated. Do not edit it by hand. Regenerate it with:
|
2
|
+
# srb rbi gems
|
3
|
+
|
4
|
+
# typed: true
|
5
|
+
#
|
6
|
+
# If you would like to make changes to this file, great! Please create the gem's shim here:
|
7
|
+
#
|
8
|
+
# https://github.com/sorbet/sorbet-typed/new/master?filename=lib/declarative/all/declarative.rbi
|
9
|
+
#
|
10
|
+
# declarative-0.0.10
|
11
|
+
|
12
|
+
module Declarative
|
13
|
+
end
|
14
|
+
class Declarative::Definitions < Hash
|
15
|
+
def add(name, options = nil, &block); end
|
16
|
+
def build_nested(options); end
|
17
|
+
def each(&block); end
|
18
|
+
def get(name); end
|
19
|
+
def initialize(definition_class); end
|
20
|
+
end
|
21
|
+
class Declarative::Definitions::Definition
|
22
|
+
def [](name); end
|
23
|
+
def initialize(name, options = nil, &block); end
|
24
|
+
def merge!(hash); end
|
25
|
+
def merge(hash); end
|
26
|
+
end
|
27
|
+
class Declarative::Defaults
|
28
|
+
def call(name, given_options); end
|
29
|
+
def handle_array_and_deprecate(variables); end
|
30
|
+
def initialize; end
|
31
|
+
def merge!(hash = nil, &block); end
|
32
|
+
def self.wrap_arrays(variables); end
|
33
|
+
end
|
34
|
+
class Declarative::Variables
|
35
|
+
def self.Append(appended_array); end
|
36
|
+
def self.Merge(merged_hash); end
|
37
|
+
def self.merge(defaults, overrides); end
|
38
|
+
end
|
39
|
+
class Declarative::Variables::Proc < Proc
|
40
|
+
end
|
41
|
+
class Declarative::DeepDup
|
42
|
+
def self.call(args); end
|
43
|
+
def self.dup_items(arr); end
|
44
|
+
end
|
45
|
+
class Declarative::Heritage < Array
|
46
|
+
def call!(inheritor, cfg); end
|
47
|
+
def call(inheritor, &block); end
|
48
|
+
def record(method, *args, &block); end
|
49
|
+
end
|
50
|
+
module Declarative::Heritage::DSL
|
51
|
+
def heritage; end
|
52
|
+
end
|
53
|
+
module Declarative::Heritage::Inherited
|
54
|
+
def inherited(subclass); end
|
55
|
+
end
|
56
|
+
module Declarative::Heritage::Included
|
57
|
+
def included(mod); end
|
58
|
+
end
|
59
|
+
module Declarative::Schema
|
60
|
+
def self.extended(extender); end
|
61
|
+
end
|
62
|
+
module Declarative::Schema::DSL
|
63
|
+
def _defaults; end
|
64
|
+
def build_definition(name, options = nil, &block); end
|
65
|
+
def defaults(options = nil, &block); end
|
66
|
+
def definition_class; end
|
67
|
+
def definitions; end
|
68
|
+
def nested_builder; end
|
69
|
+
def property(name, options = nil, &block); end
|
70
|
+
def wrap_arrays_from_block(block); end
|
71
|
+
end
|
72
|
+
module Declarative::Schema::Feature
|
73
|
+
def feature(*mods); end
|
74
|
+
def register_feature(mod); end
|
75
|
+
end
|