k_doc 0.0.4 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3ade2c96c7dd68a9b948f680c63a3a3f28d79f48a3808df328435054e32048f
4
- data.tar.gz: f932c466c175cd9258220b370ea040982e2fd57be560fd816c8a60818d4344c6
3
+ metadata.gz: 4dc18e7f82a4c59368f6870a693781586d274f21b8a8df64bd568aa6d0c43262
4
+ data.tar.gz: d2328c38cf349291486d22d46572698817df1e00ce64c628eba90d7451e97ca3
5
5
  SHA512:
6
- metadata.gz: 6f18c5daebd800c3e3e33ce5c8ec882833cc64b97c7d8b415c6078abed1c7fce76a6bb59f53afe51511035e77e198fdd1e106cf746dcff6fa7a96a3d0af88128
7
- data.tar.gz: 36ab77e3f217d639bc02f911b23674322ad0dd2c2e1aed0042f57195fda0b6b8f95e0119758e0c85f0bddb485b0ea77d73d2543b6c515b315bb5c5d95171ab77
6
+ metadata.gz: 0c844d63fc520e5dab619f01214a93df2306d60cc6877b923cda7a0963269bac0e6ba69b28b6f3d26fec4418e821d61fd92e84f58d0555b7f7ee9dd46ad5539b
7
+ data.tar.gz: 81f55829133fc0f3a2a581da5ec51d370bdc7050fdef00ef2aed7965cb43119ccd182413298894b6b40302848d0fc84eb0e77381676c820a70e2bb8ddd2adcbf
data/CODE_OF_CONDUCT.md CHANGED
@@ -11,7 +11,7 @@ orientation.
11
11
 
12
12
  ## Our Standards
13
13
 
14
- Examples of behavior that contributes to creating a positive environment
14
+ Examples of behaviour that contributes to creating a positive environment
15
15
  include:
16
16
 
17
17
  - Using welcoming and inclusive language
@@ -20,7 +20,7 @@ include:
20
20
  - Focusing on what is best for the community
21
21
  - Showing empathy towards other community members
22
22
 
23
- Examples of unacceptable behavior by participants include:
23
+ Examples of unacceptable behaviour by participants include:
24
24
 
25
25
  - The use of sexualized language or imagery and unwelcome sexual attention or
26
26
  advances
@@ -34,13 +34,13 @@ Examples of unacceptable behavior by participants include:
34
34
  ## Our Responsibilities
35
35
 
36
36
  Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
37
+ behaviour and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behaviour.
39
39
 
40
40
  Project maintainers have the right and responsibility to remove, edit, or
41
41
  reject comments, commits, code, wiki edits, issues, and other contributions
42
42
  that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
43
+ permanently any contributor for other behaviours that they deem inappropriate,
44
44
  threatening, offensive, or harmful.
45
45
 
46
46
  ## Scope
@@ -54,7 +54,7 @@ further defined and clarified by project maintainers.
54
54
 
55
55
  ## Enforcement
56
56
 
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
57
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be
58
58
  reported by contacting the project team at david.cruwys@bugcrowd.com. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
data/README.md CHANGED
@@ -68,10 +68,8 @@ Aaa::Bbb::Program.execute()
68
68
  To release a new version, update the version number in `version.rb`, build the gem and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
69
 
70
70
  ```bash
71
- gem build
72
- gem push rspec-usecases-?.?.??.gem
73
- # or push the latest gem
74
- ls *.gem | sort -r | head -1 | xargs gem push
71
+ rake publish
72
+ rake clean
75
73
  ```
76
74
 
77
75
  ## Contributing
data/STORIES.md CHANGED
@@ -10,22 +10,27 @@ As a Developer, I need flexible data structures defined in DSL, so can model ric
10
10
 
11
11
  As a Developer, I need flexible data structures defined in DSL, so can model rich documents
12
12
 
13
- ### Tasks next on list
13
+ ## Stories and tasks
14
14
 
15
- Setup RubyGems and RubyDoc
15
+ ### Stories - completed
16
16
 
17
- - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_doc)
18
- - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_doc/master)
17
+ As a Domain Modeler, I can define flexible tabular structures, so I can access dynamic tabular arrays
19
18
 
20
- Setup GitHub Action (test and lint)
19
+ - add DSL for table with columns and rows
20
+ - add support for data decorators
21
21
 
22
- - Setup Rspec action
23
- - Setup RuboCop action
22
+ As a Domain Modeler, I can define flexible key/value stores, so I can access settings data
24
23
 
25
- ## Stories and tasks
24
+ - add DSL for key/value settings
25
+ - add support for data decorators
26
26
 
27
27
  ### Tasks - completed
28
28
 
29
+ Setup RubyGems and RubyDoc
30
+
31
+ - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_doc)
32
+ - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_doc/master)
33
+
29
34
  Setup project management, requirement and SCRUM documents
30
35
 
31
36
  - Setup readme file
@@ -33,6 +38,11 @@ Setup project management, requirement and SCRUM documents
33
38
  - Setup a project backlog
34
39
  - Setup an examples/usage document
35
40
 
41
+ Setup GitHub Action (test and lint)
42
+
43
+ - Setup Rspec action
44
+ - Setup RuboCop action
45
+
36
46
  Setup new Ruby GEM
37
47
 
38
48
  - Build out a standard GEM structure
data/ToDo.md ADDED
@@ -0,0 +1,91 @@
1
+ # K Doc
2
+
3
+ > KDoc provides a document in the form a DSL that contains flexible key/value and tabular data
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'k_doc'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ gem install k_doc
23
+ ```
24
+
25
+ ## Stories
26
+
27
+ ### Main Story
28
+
29
+ As a Developer, I need flexible data structures defined in DSL, so can model rich documents
30
+
31
+ See all [stories](./STORIES.md)
32
+
33
+ ## Usage
34
+
35
+ See all [usage examples](./USAGE.md)
36
+
37
+ ### Basic Example
38
+
39
+ #### Basic example
40
+
41
+ Description for a basic example to be featured in the main README.MD file
42
+
43
+ ```ruby
44
+ class SomeRuby; end
45
+ ```
46
+
47
+ ## Development
48
+
49
+ Checkout the repo
50
+
51
+ ```bash
52
+ git clone klueless-io/k_doc
53
+ ```
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
56
+
57
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
+
59
+ ```bash
60
+ bin/console
61
+
62
+ Aaa::Bbb::Program.execute()
63
+ # => ""
64
+ ```
65
+
66
+ `k_doc` is setup with Guard, run `guard`, this will watch development file changes and run tests automatically, if successful, it will then run rubocop for style quality.
67
+
68
+ To release a new version, update the version number in `version.rb`, build the gem and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
+
70
+ ```bash
71
+ gem build
72
+ gem push rspec-usecases-?.?.??.gem
73
+ # or push the latest gem
74
+ ls *.gem | sort -r | head -1 | xargs gem push
75
+ ```
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on GitHub at https://github.com/klueless-io/k_doc. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
80
+
81
+ ## License
82
+
83
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
84
+
85
+ ## Code of Conduct
86
+
87
+ Everyone interacting in the K Doc project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/klueless-io/k_doc/blob/master/CODE_OF_CONDUCT.md).
88
+
89
+ ## Copyright
90
+
91
+ Copyright (c) David Cruwys. See [MIT License](LICENSE.txt) for further details.
data/k_doc.gemspec CHANGED
@@ -38,7 +38,10 @@ Gem::Specification.new do |spec|
38
38
  spec.require_paths = ['lib']
39
39
  # spec.extensions = ['ext/k_doc/extconf.rb']
40
40
 
41
+ spec.add_dependency 'activesupport' , '~> 6'
42
+ spec.add_dependency 'k_decor' , '~> 0.0.0'
41
43
  spec.add_dependency 'k_log' , '~> 0.0.0'
44
+ spec.add_dependency 'k_type' , '~> 0.0.0'
42
45
  spec.add_dependency 'k_util' , '~> 0.0.0'
43
46
  # spec.add_dependency 'tty-box', '~> 0.5.0'
44
47
  end
data/lib/k_doc.rb CHANGED
@@ -2,32 +2,33 @@
2
2
 
3
3
  require 'securerandom'
4
4
 
5
- require 'logger'
6
5
  require 'table_print'
7
6
  require 'k_log'
7
+ require 'k_type'
8
8
  require 'k_util'
9
- require 'k_log/log_formatter'
10
- require 'k_log/log_helper'
11
- require 'k_log/log_util'
9
+ require 'k_decor'
12
10
 
13
11
  require 'k_doc/version'
12
+ require 'k_doc/container'
14
13
  require 'k_doc/data'
15
- require 'k_doc/document'
16
14
  require 'k_doc/fake_opinion'
17
15
  require 'k_doc/settings'
18
16
  require 'k_doc/table'
19
17
  require 'k_doc/util'
20
18
 
19
+ require 'k_doc/decorators/settings_decorator'
20
+ require 'k_doc/decorators/table_decorator'
21
+
21
22
  module KDoc
22
23
  # raise KDoc::Error, 'Sample message'
23
24
  class Error < StandardError; end
24
25
 
25
26
  class << self
26
- # Factory method to create a new document
27
- def doc(key = nil, **options, &block)
28
- doc = KDoc::Document.new(key, **options, &block)
29
- doc.execute_block
30
- doc
27
+ # Factory method to create a new data
28
+ def data(key = nil, **options, &block)
29
+ data = KDoc::Data.new(key, **options, &block)
30
+ data.execute_block
31
+ data
31
32
  end
32
33
 
33
34
  attr_accessor :opinion
@@ -37,16 +38,11 @@ module KDoc
37
38
 
38
39
  KDoc.opinion = KDoc::FakeOpinion.new
39
40
  KDoc.util = KDoc::Util.new
40
-
41
- # Need to move this into a KLog factory
42
- def self.configure_logger
43
- logger = Logger.new($stdout)
44
- logger.level = Logger::DEBUG
45
- logger.formatter = KLog::LogFormatter.new
46
- KLog::LogUtil.new(logger)
47
- end
48
-
49
- # KDoc.log = configure_logger
50
41
  end
51
42
 
52
- L = KDoc.configure_logger
43
+ if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
44
+ namespace = 'KDoc::Version'
45
+ file_path = $LOADED_FEATURES.find { |f| f.include?('k_doc/version') }
46
+ version = KDoc::VERSION.ljust(9)
47
+ puts "#{namespace.ljust(35)} : #{version.ljust(9)} : #{file_path}"
48
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDoc
4
+ # A container acts a base data object for any data requires tagging such as
5
+ # unique key, type and namespace.
6
+ class Container
7
+ # include KLog::Logging
8
+
9
+ attr_reader :key
10
+ attr_reader :type
11
+ attr_reader :namespace
12
+ attr_reader :project_key
13
+ attr_reader :error
14
+
15
+ # Create container for storing data/documents.
16
+ #
17
+ # Any container can be uniquely identified via it's
18
+ # key, type, namespace and project_key attributes
19
+ #
20
+ # @param [String|Symbol] name Name of the container
21
+ # @param [String|Symbol] type Type of the container, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
22
+ # @param [String|Symbol] namespace Namespace that the container belongs to
23
+ # @param [String|Symbol] project_key Project that the container belongs to
24
+ def initialize(key: nil, type: nil, namespace: nil, project_key: nil)
25
+ @key = key || SecureRandom.alphanumeric(8)
26
+ @type = type || KDoc.opinion.default_document_type
27
+ @namespace = namespace || ''
28
+ @project_key = project_key || ''
29
+ end
30
+
31
+ def unique_key
32
+ @unique_key ||= KDoc.util.build_unique_key(key, type, namespace, project_key)
33
+ end
34
+
35
+ def debug_header
36
+ log.kv 'key', key
37
+ log.kv 'type', type
38
+ log.kv 'namespace', namespace
39
+ log.kv 'project_key', namespace
40
+ log.kv 'error', error
41
+ end
42
+ end
43
+ end
data/lib/k_doc/data.rb CHANGED
@@ -1,258 +1,192 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # module KDoc
4
- # # TODO
5
- # # Missing tests around errors
6
- # # Make sure that error writes to resource or document appropriately
7
- # # Puts errors onto a project manager pipeline so that they can be be printed out after the documents
8
- # #
9
- # # General purpose document DSL
10
- # #
11
- # # Made up of 0 or more setting groups and table groups
12
- # class Data
13
- # extend Forwardable
14
-
15
- # attr_reader :key
16
- # attr_reader :type
17
- # attr_reader :namespace
18
- # attr_reader :options
19
- # attr_reader :error
20
-
21
- # # State of document
22
- # # - :initializing
23
- # # - :initialized
24
- # # - :loading
25
- # # - :loaded
26
- # # - :executing
27
- # # - :executed
28
- # attr_reader :state
29
-
30
- # # Shortcut to formatter
31
- # attr_reader :f
32
-
33
- # attr_accessor :resource
34
-
35
- # def_delegator :resource, :project
36
-
37
- # def state=(state)
38
- # @state = state
39
- # # if [:initialized, :loaded, :executed].include?(state) &&
40
- # # (project.nil? || project.name == 'k_dsl')
41
- # # # pname = project.nil? ? '' : "#{project&.name} "
42
- # # L.kv "#{unique_key} - state", state
43
- # # end
44
- # @state
45
- # end
46
-
47
- # # Create document
48
- # #
49
- # # @param [String|Symbol] name Name of the document
50
- # # @param args[0] Type of the document, defaults to KDsl.config.default_document_type if not set
51
- # # @param default: Default value (using named params), as above
52
- # def initialize(key = SecureRandom.alphanumeric(8), *args, **options, &block)
53
- # @key = key
54
- # @type = args.length.positive? ? args[0] || KDsl.config.default_document_type : KDsl.config.default_document_type
55
-
56
- # @options = options || {}
57
- # @namespace = options[:namespace] || ''
58
- # default_data = options[:default_data] || {}
59
-
60
- # @namespace = @namespace.to_s
61
- # @error = nil
62
-
63
- # self.state = :initializing
64
-
65
- # # Most documents live within a hash, some tabular documents such as
66
- # # CSV will use an []
67
- # set_data(default_data)
68
-
69
- # @f = KDsl::Util.format
70
-
71
- # @block = block if block_given?
72
-
73
- # self.state = :initialized
74
- # end
75
-
76
- # def execute_block(run_actions: nil)
77
- # return if @block.nil?
78
-
79
- # # The DSL actions method will only run on run_actions: true
80
- # @run_actions = run_actions
81
-
82
- # # if unique_key == 'template_options_entity'
83
- # # L.kv '2:CLASS_ID', object_id
84
- # # end
85
- # if initialized?
86
- # self.state = :loading
87
- # instance_eval(&@block)
88
- # self.state = :loaded
89
- # end
90
- # # if unique_key == 'template_options_entity'
91
- # # L.kv '3:CLASS_ID', resource_document.object_id
92
- # # end
93
-
94
- # if loaded? && run_actions && respond_to?(:on_action)
95
- # @state = :executed
96
- # on_action
97
- # end
98
- # rescue KDsl::Error => e
99
- # L.error('KDsl::Error in document')
100
- # L.kv 'key', unique_key
101
- # L.kv 'file', KDsl::Util.data.console_file_hyperlink(resource.file, resource.file)
102
- # L.error(e.message)
103
- # @error = e
104
- # # L.heading "Invalid code block in document_dsl during registration: #{k_key}"
105
- # # L.exception exception
106
- # raise
107
- # rescue StandardError => e
108
- # L.error('Standard error in document')
109
- # L.kv 'key', unique_key
110
- # L.kv 'file', KDsl::Util.data.console_file_hyperlink(resource.file, resource.file)
111
- # L.error(e.message)
112
- # @error = e
113
- # # L.exception exception2
114
- # raise
115
- # ensure
116
- # @run_actions = nil
117
- # return
118
- # end
119
-
120
- # def initialized?
121
- # @state == :initialized
122
- # end
123
-
124
- # def loaded?
125
- # @state == :loaded
126
- # end
127
-
128
- # def executed?
129
- # @state == :executed
130
- # end
131
-
132
- # def unique_key
133
- # @unique_key ||= KDsl::Util.dsl.build_unique_key(key, type, namespace)
134
- # end
135
-
136
- # def settings(key = nil, **options, &block)
137
- # options ||= {}
138
-
139
- # opts = {}.merge(@options) # Document Options
140
- # .merge(options) # Settings Options
141
-
142
- # settings = settings_instance(@data, key, parent: self, &block)
143
- # settings.run_decorators(opts)
144
- # settings
145
- # end
146
-
147
- # def table(key = :table, &block)
148
- # # NEED to add support for run_decorators I think
149
- # table_instance(@data, key, parent: self, &block)
150
- # end
151
- # alias rows table
152
-
153
- # # Sweet add-on would be builders
154
- # # def builder(key, &block)
155
- # # # example
156
- # # KDsl::Builder::Shotstack.new(@data, key, &block)
157
- # # end
158
-
159
- # def set_data(data)
160
- # @data = data
161
- # end
162
-
163
- # def data
164
- # @data.clone
165
- # end
166
-
167
- # def data_struct
168
- # KDsl::Util.data.to_struct(data)
169
- # end
170
- # alias d data_struct
171
-
172
- # def raw_data_struct
173
- # KDsl::Util.data.to_struct(raw_data)
174
- # end
175
-
176
- # def get_node_type(node_name)
177
- # node_name = KDsl::Util.data.clean_symbol(node_name)
178
- # node_data = @data[node_name]
179
-
180
- # raise KDsl::Error, "Node not found: #{node_name}" if node_data.nil?
181
-
182
- # if node_data.keys.length == 2 && (node_data.key?('fields') && node_data.key?('rows'))
183
- # :table
184
- # else
185
- # :settings
186
- # end
187
- # end
188
-
189
- # # Removes any meta data eg. "fields" from a table and just returns the raw data
190
- # def raw_data
191
- # # REFACT, what if this is CSV, meaning it is just an array?
192
- # # add specs
193
- # result = data
194
-
195
- # result.each_key do |key|
196
- # # ANTI: get_node_type uses @data while we are using @data.clone here
197
- # data[key] = if get_node_type(key) == :table
198
- # result[key].delete('fields')
199
- # else
200
- # result[key]
201
- # end
202
- # end
203
-
204
- # data
205
- # end
206
-
207
- # # Move this out to the logger function when it has been refactor
208
- # def debug(include_header = false)
209
- # debug_header if include_header
210
-
211
- # # tp dsls.values, :k_key, :k_type, :state, :save_at, :last_at, :data, :last_data, :source, { :file => { :width => 150 } }
212
- # # puts JSON.pretty_generate(data)
213
- # L.o(raw_data_struct)
214
- # end
215
-
216
- # def debug_header
217
- # L.heading self.class.name
218
- # L.kv 'key', key
219
- # L.kv 'type', type
220
- # L.kv 'namespace', namespace
221
- # L.kv 'error', error
222
- # L.kv 'state', state
223
- # L.kv 'respond_to?(:on_import)', respond_to?(:on_import)
224
- # L.kv 'respond_to?(:david)', respond_to?(:david)
225
- # david if respond_to?(:david)
226
- # # L.kv 'INITALIZED', resource_document.initialized?
227
- # # L.kv 'EXECUTED', resource_document.executed?
228
-
229
- # options&.keys.reject { |k| k == :namespace }&.each do |key|
230
- # L.kv key, options[key]
231
- # end
232
-
233
- # L.line
234
- # end
235
-
236
- # # Helpers that often get called by extensions
237
-
238
- # def project
239
- # project ||= resource&.project
240
- # end
241
-
242
- # # Warning message
243
- # def warn(message)
244
- # L.warn message
245
- # nil
246
- # end
247
-
248
- # private
249
-
250
- # def settings_instance(data, key, **options, &block)
251
- # KDsl.config.settings_class.new(data, key, **options, &block)
252
- # end
253
-
254
- # def table_instance(data, key, **options, &block)
255
- # KDsl.config.table_class.new(data, key, **options, &block)
256
- # end
257
- # end
258
- # end
3
+ module KDoc
4
+ # General purpose data DSL
5
+ #
6
+ # Made up of 0 or more setting groups and table groups
7
+ class Data < KDoc::Container
8
+ include KLog::Logging
9
+
10
+ # include KType::Error
11
+ # include KType::ManagedState
12
+ # include KType::NamedFolder
13
+ # include KType::LayeredFolder
14
+
15
+ attr_reader :options
16
+
17
+ # Create document
18
+ #
19
+ # @param [String|Symbol] name Name of the document
20
+ # @param args[0] Type of the document, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
21
+ # @param default: Default value (using named params), as above
22
+ def initialize(key = nil, **options, &block)
23
+ super(key: key, type: options[:type], namespace: options[:namespace], project_key: options[:project_key])
24
+ initialize_attributes(**options)
25
+
26
+ @block = block if block_given?
27
+ end
28
+
29
+ def execute_block(run_actions: nil)
30
+ return if @block.nil?
31
+
32
+ # The DSL actions method will only run on run_actions: true
33
+ @run_actions = run_actions
34
+
35
+ instance_eval(&@block)
36
+
37
+ on_action if run_actions && respond_to?(:on_action)
38
+ # rescue KDoc::Error => e
39
+ # puts('KDoc::Error in document')
40
+ # puts "key #{unique_key}"
41
+ # # puts "file #{KUtil.data.console_file_hyperlink(resource.file, resource.file)}"
42
+ # puts(e.message)
43
+ # @error = e
44
+ # raise
45
+ rescue StandardError => e
46
+ log.error('Standard error in document')
47
+ puts "key #{unique_key}"
48
+ # puts "file #{KUtil.data.console_file_hyperlink(resource.file, resource.file)}"
49
+ log.error(e.message)
50
+ @error = e
51
+ # log.exception exception2
52
+ raise
53
+ ensure
54
+ @run_actions = nil
55
+ end
56
+
57
+ def unique_key
58
+ @unique_key ||= KDoc.util.build_unique_key(key, type, namespace)
59
+ end
60
+
61
+ def settings(key = nil, **options, &block)
62
+ options ||= {}
63
+
64
+ opts = {}.merge(@options) # Data Options
65
+ .merge(options) # Settings Options
66
+ .merge(parent: self)
67
+
68
+ settings_instance(@data, key, **opts, &block)
69
+ # settings.run_decorators(opts)
70
+ end
71
+
72
+ def table(key = :table, **options, &block)
73
+ # NEED to add support for run_decorators I think
74
+ options.merge(parent: self)
75
+ table_instance(@data, key, **options, &block)
76
+ end
77
+ alias rows table
78
+
79
+ # Sweet add-on would be builders
80
+ # def builder(key, &block)
81
+ # # example
82
+ # KDoc::Builder::Shotstack.new(@data, key, &block)
83
+ # end
84
+
85
+ # def set_data(data)
86
+ # @data = data
87
+ # end
88
+
89
+ def data
90
+ @data.clone
91
+ end
92
+
93
+ def data_struct
94
+ KUtil.data.to_open_struct(data)
95
+ end
96
+ # alias d data_struct
97
+
98
+ def raw_data_struct
99
+ KUtil.data.to_open_struct(raw_data)
100
+ end
101
+
102
+ def get_node_type(node_name)
103
+ node_name = KUtil.data.clean_symbol(node_name)
104
+ node_data = @data[node_name]
105
+
106
+ raise KDoc::Error, "Node not found: #{node_name}" if node_data.nil?
107
+
108
+ if node_data.keys.length == 2 && (node_data.key?('fields') && node_data.key?('rows'))
109
+ :table
110
+ else
111
+ :settings
112
+ end
113
+ end
114
+
115
+ # Removes any meta data eg. "fields" from a table and just returns the raw data
116
+ # REFACTOR: IT MAY BE BEST TO MOVE raw_data into each of the node_types
117
+ def raw_data
118
+ # REFACT, what if this is CSV, meaning it is just an array?
119
+ # add specs
120
+ result = data
121
+
122
+ result.each_key do |key|
123
+ # ANTI: get_node_type uses @data while we are using @data.clone here
124
+ result[key] = if get_node_type(key) == :table
125
+ # Old format was to keep the rows and delete the fields
126
+ # Now the format is to pull the row_value up to the key and remove rows and fields
127
+ # result[key].delete('fields')
128
+ result[key]['rows']
129
+ else
130
+ result[key]
131
+ end
132
+ end
133
+
134
+ result
135
+ end
136
+
137
+ # Move this out to the logger function when it has been refactor
138
+ def debug(include_header: false)
139
+ debug_header if include_header
140
+
141
+ # tp dsls.values, :k_key, :k_type, :state, :save_at, :last_at, :data, :last_data, :source, { :file => { :width => 150 } }
142
+ # puts JSON.pretty_generate(data)
143
+ log.o(raw_data_struct)
144
+ end
145
+
146
+ # rubocop:disable Metrics/AbcSize
147
+ def debug_header
148
+ log.heading self.class.name
149
+ log.kv 'key', key
150
+ log.kv 'type', type
151
+ log.kv 'namespace', namespace
152
+ log.kv 'error', error
153
+
154
+ debug_header_keys
155
+
156
+ log.line
157
+ end
158
+ # rubocop:enable Metrics/AbcSize
159
+
160
+ def debug_header_keys
161
+ options&.keys&.reject { |k| k == :namespace }&.each do |key|
162
+ log.kv key, options[key]
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ def initialize_attributes(**options)
169
+ @options = options || {}
170
+ @parent = slice_option(:parent)
171
+
172
+ # Most documents live within a hash, some tabular documents such as CSV will use an []
173
+ @data = slice_option(:default_data) || {}
174
+ end
175
+
176
+ def settings_instance(data, key, **options, &block)
177
+ KDoc.opinion.settings_class.new(data, key, **options, &block)
178
+ end
179
+
180
+ def table_instance(data, key, **options, &block)
181
+ KDoc.opinion.table_class.new(data, key, **options, &block)
182
+ end
183
+
184
+ def slice_option(key)
185
+ return nil unless @options.key?(key)
186
+
187
+ result = @options[key]
188
+ @options.delete(key)
189
+ result
190
+ end
191
+ end
192
+ end