k_doc 0.0.5 → 0.0.11

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: 03b82733202ef286cfa4fb0d07f46da4b6b6979361b17174f737e5e8e677fa04
4
- data.tar.gz: cadbc6795fc6816aae37fdab6155aedb87b3088674fed43fbce7c1d295a7f20c
3
+ metadata.gz: f3a22296c27473f92f9012c2c58c341cd622041f4f54b853cd098e667e2bd861
4
+ data.tar.gz: 1a39ea8f5f79db0a05204f18b6e070f2083d1bbd756b17ca24de7e0c77208c43
5
5
  SHA512:
6
- metadata.gz: 4490d6fdbd9e74ad5bafe67107eede6f0585df1a2971fcb11a55ac273f17abab111731ebdd2bc4c7588f19374bc4f5a46b8e2f25e2bd72a5b0f00bec9a9e9d61
7
- data.tar.gz: df71d4889f44ec61a235862392bb2dbc5c83ad2f750295c03f5b267df308cb9cd7f6ae53d24180f8343597b4481855586d6519c07089616f9678d36c436d47ec
6
+ metadata.gz: d66c94012e5dfed8899f89abdfaf8fd2ae13c3a35b8c31e77b45555d1ce539b66f88ca61fd56b42db6d2c9184c58d6df7cfc14949a40d30e5238e15e9bb5fa42
7
+ data.tar.gz: cb190abbb8f67ad7421a72474245ddaaa44901c70d6f4fd09cdfe7b325b759ff353fd30199396680751b2025a9a6f364a1043480c32551b885038dc7d101ad40
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,18 +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
53
-
54
- puts "KDoc::Version: #{KDoc::VERSION}" if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
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,55 @@
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 [Hash] **opts The options
21
+ # @option opts [String|Symbol] name Name of the container
22
+ # @option opts [String|Symbol] type Type of the container, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
23
+ # @option opts [String|Symbol] namespace Namespace that the container belongs to
24
+ # @option opts [String|Symbol] project_key Project that the container belongs to
25
+ def initialize(**opts)
26
+ @key = opts[:key] || SecureRandom.alphanumeric(8)
27
+ @type = opts[:type] || KDoc.opinion.default_document_type
28
+ @namespace = opts[:namespace] || ''
29
+ @project_key = opts[:project_key] || ''
30
+
31
+ # Old name is default_data, wonder if I still need that idea?
32
+ # Most documents live within a hash, some tabular documents such as CSV will use an []
33
+ # @data = slice_option(:default_data) || {}
34
+ @data = opts[:data] || {}
35
+ end
36
+
37
+ def unique_key
38
+ @unique_key ||= KDoc.util.build_unique_key(key, type, namespace, project_key)
39
+ end
40
+
41
+ def debug_header
42
+ log.kv 'key', key
43
+ log.kv 'type', type
44
+ log.kv 'namespace', namespace
45
+ log.kv 'project_key', namespace
46
+ log.kv 'error', error
47
+ end
48
+
49
+ attr_writer :data
50
+
51
+ def data
52
+ @data.clone
53
+ end
54
+ end
55
+ end
data/lib/k_doc/data.rb CHANGED
@@ -1,258 +1,184 @@
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 data_struct
86
+ KUtil.data.to_open_struct(data)
87
+ end
88
+ # alias d data_struct
89
+
90
+ def raw_data_struct
91
+ KUtil.data.to_open_struct(raw_data)
92
+ end
93
+
94
+ def get_node_type(node_name)
95
+ node_name = KUtil.data.clean_symbol(node_name)
96
+ node_data = @data[node_name]
97
+
98
+ raise KDoc::Error, "Node not found: #{node_name}" if node_data.nil?
99
+
100
+ if node_data.keys.length == 2 && (node_data.key?('fields') && node_data.key?('rows'))
101
+ :table
102
+ else
103
+ :settings
104
+ end
105
+ end
106
+
107
+ # Removes any meta data eg. "fields" from a table and just returns the raw data
108
+ # REFACTOR: IT MAY BE BEST TO MOVE raw_data into each of the node_types
109
+ def raw_data
110
+ # REFACT, what if this is CSV, meaning it is just an array?
111
+ # add specs
112
+ result = data
113
+
114
+ result.each_key do |key|
115
+ # ANTI: get_node_type uses @data while we are using @data.clone here
116
+ result[key] = if get_node_type(key) == :table
117
+ # Old format was to keep the rows and delete the fields
118
+ # Now the format is to pull the row_value up to the key and remove rows and fields
119
+ # result[key].delete('fields')
120
+ result[key]['rows']
121
+ else
122
+ result[key]
123
+ end
124
+ end
125
+
126
+ result
127
+ end
128
+
129
+ # Move this out to the logger function when it has been refactor
130
+ def debug(include_header: false)
131
+ debug_header if include_header
132
+
133
+ # tp dsls.values, :k_key, :k_type, :state, :save_at, :last_at, :data, :last_data, :source, { :file => { :width => 150 } }
134
+ # puts JSON.pretty_generate(data)
135
+ log.o(raw_data_struct)
136
+ end
137
+
138
+ # rubocop:disable Metrics/AbcSize
139
+ def debug_header
140
+ log.heading self.class.name
141
+ log.kv 'key', key
142
+ log.kv 'type', type
143
+ log.kv 'namespace', namespace
144
+ log.kv 'error', error
145
+
146
+ debug_header_keys
147
+
148
+ log.line
149
+ end
150
+ # rubocop:enable Metrics/AbcSize
151
+
152
+ def debug_header_keys
153
+ options&.keys&.reject { |k| k == :namespace }&.each do |key|
154
+ log.kv key, options[key]
155
+ end
156
+ end
157
+
158
+ private
159
+
160
+ def initialize_attributes(**options)
161
+ @options = options || {}
162
+ @parent = slice_option(:parent)
163
+
164
+ # Most documents live within a hash, some tabular documents such as CSV will use an []
165
+ @data = slice_option(:default_data) || {}
166
+ end
167
+
168
+ def settings_instance(data, key, **options, &block)
169
+ KDoc.opinion.settings_class.new(data, key, **options, &block)
170
+ end
171
+
172
+ def table_instance(data, key, **options, &block)
173
+ KDoc.opinion.table_class.new(data, key, **options, &block)
174
+ end
175
+
176
+ def slice_option(key)
177
+ return nil unless @options.key?(key)
178
+
179
+ result = @options[key]
180
+ @options.delete(key)
181
+ result
182
+ end
183
+ end
184
+ end