elder_docs 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53d1646bb49d2be38dcc43d646f38e63a257e31e3e49e7725ee5b856e88eebcc
4
- data.tar.gz: 69f62037def7feea699bfbecf03b91b3769bc40321e86573f498f8bda2d41f8f
3
+ metadata.gz: 8f4aabd2e66c168f676bd5eb2e2f2e3266456e5800d3e88233a0897fcdae3060
4
+ data.tar.gz: 0e65cc39e7c4165aa4bb7eef14109ef0228b451cfc7e6b58ca93bd23eb38c894
5
5
  SHA512:
6
- metadata.gz: 209001181a6d81f7eaebab82cf9a0b2df905ecc7b00b867bad810c7d20714bec87defd399a1ad58c683702359bcd2dcf46bbaaec08fa90f76c851389d76e1f9e
7
- data.tar.gz: 1fd1fa84bb406777bc81cdb8121794cac0c0049cf0df3561615540f8bb3a19e8499561d32c5273d52bfa8d877132b2a18329aa62aea5df0c28914fd956c8d8b1
6
+ metadata.gz: 219d9898dbff6eaf5718b2d8750643fd902f875a690990d6d4d7b1d43a3106bb31a7c184e765cc88a3e67908ebd3056c17d3b4e0db1d142b36bfa34e81bda3c2
7
+ data.tar.gz: dd17c7cdf76a23782758eb95f72ecf1f090bfad4ee509f23cabd7612cddaf1250f0b7c38cd7ec57256e1c5503a1b9de4e73056871dc101d4622ccbc895008fa9
data/README.md CHANGED
@@ -71,6 +71,7 @@ Create `articles.json`:
71
71
  bundle exec elderdocs deploy
72
72
  ```
73
73
 
74
+ This builds the SPA into `public/elderdocs` (configurable via `output_path`) so the assets live alongside your application code.
74
75
  ### 4. Mount in routes
75
76
 
76
77
  ```ruby
@@ -123,6 +124,9 @@ ui:
123
124
 
124
125
  # Admin password for /docs/ui
125
126
  admin_password: your-secure-password
127
+
128
+ # Where to write generated assets (relative paths are resolved from Rails.root)
129
+ output_path: ./public/elderdocs
126
130
  ```
127
131
 
128
132
  ## CLI Options
@@ -131,7 +135,8 @@ admin_password: your-secure-password
131
135
  bundle exec elderdocs deploy \
132
136
  --definitions custom.json \
133
137
  --articles guides.json \
134
- --api-server https://api.example.com
138
+ --api-server https://api.example.com \
139
+ --output public/custom-docs
135
140
  ```
136
141
 
137
142
  ## Requirements
@@ -5,6 +5,9 @@
5
5
  # If /docs is already taken, ElderDocs will try: /api-docs, /documentation, /api, /docs/api
6
6
  mount_path: /docs
7
7
 
8
+ # Output directory for generated assets (relative to your Rails root)
9
+ output_path: ./public/elderdocs
10
+
8
11
  # Admin password for UI configuration page (/docs/ui)
9
12
  # Default: 'admin' (or set via ELDERDOCS_ADMIN_PASSWORD environment variable)
10
13
  # admin_password: your-secure-password-here
@@ -8,7 +8,7 @@ module ElderDocs
8
8
  desc 'deploy', 'Generate and deploy API documentation'
9
9
  method_option :definitions, type: :string, default: 'definitions.json', aliases: '-d'
10
10
  method_option :articles, type: :string, default: 'articles.json', aliases: '-a'
11
- method_option :output, type: :string, default: nil, aliases: '-o'
11
+ method_option :output, type: :string, default: nil, aliases: '-o', desc: 'Directory to write built assets (default: public/elderdocs)'
12
12
  method_option :api_server, type: :string, default: nil, desc: 'Default API server URL'
13
13
  method_option :skip_build, type: :boolean, default: false, desc: 'Skip frontend build if assets exist'
14
14
  method_option :force_build, type: :boolean, default: false, desc: 'Force rebuilding frontend assets'
@@ -29,10 +29,14 @@ module ElderDocs
29
29
  File.write(articles_path, [].to_json)
30
30
  end
31
31
 
32
+ output_path = File.expand_path(options[:output] || default_output_path, Dir.pwd)
33
+
34
+ ElderDocs.config.output_path = output_path
35
+
32
36
  generator = Generator.new(
33
37
  definitions_path: definitions_path,
34
38
  articles_path: articles_path,
35
- output_path: options[:output] || default_output_path,
39
+ output_path: output_path,
36
40
  api_server: options[:api_server],
37
41
  skip_build: options[:skip_build],
38
42
  force_build: options[:force_build]
@@ -62,7 +66,7 @@ module ElderDocs
62
66
  private
63
67
 
64
68
  def default_output_path
65
- File.join(File.dirname(__FILE__), '..', '..', 'lib', 'elder_docs', 'assets', 'viewer')
69
+ ElderDocs.config.output_path || File.join(Dir.pwd, 'public', 'elderdocs')
66
70
  end
67
71
  end
68
72
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
+ require 'pathname'
4
5
 
5
6
  module ElderDocs
6
7
  class Config
7
- attr_accessor :mount_path, :api_server, :auth_types, :ui_config, :admin_password
8
+ attr_accessor :mount_path, :api_server, :auth_types, :ui_config, :admin_password, :output_path
8
9
 
9
10
  def initialize
10
11
  @mount_path = nil
@@ -12,6 +13,8 @@ module ElderDocs
12
13
  @auth_types = ['bearer', 'api_key', 'basic', 'oauth2']
13
14
  @ui_config = {}
14
15
  @admin_password = nil
16
+ @api_servers = []
17
+ @output_path = default_output_path
15
18
  load_config_file
16
19
  end
17
20
 
@@ -29,19 +32,34 @@ module ElderDocs
29
32
  return unless config_path
30
33
 
31
34
  begin
32
- config = YAML.load_file(config_path)
33
- @mount_path = config['mount_path'] if config['mount_path']
34
- @api_server = config['api_server'] if config['api_server']
35
- @api_servers = config['api_servers'] if config['api_servers']
36
- @auth_types = config['auth_types'] if config['auth_types']
37
- @ui_config = config['ui'] if config['ui'] # YAML uses 'ui' key, but we store as ui_config
38
- @admin_password = config['admin_password'] if config['admin_password']
39
- rescue => e
40
- warn "Warning: Could not load elderdocs.yml: #{e.message}"
35
+ config = YAML.load_file(config_path)
36
+ config_dir = File.dirname(config_path)
37
+ @mount_path = config['mount_path'] if config['mount_path']
38
+ @api_server = config['api_server'] if config['api_server']
39
+ @api_servers = config['api_servers'] if config['api_servers']
40
+ @auth_types = config['auth_types'] if config['auth_types']
41
+ @ui_config = config['ui'] if config['ui'] # YAML uses 'ui' key, but we store as ui_config
42
+ @admin_password = config['admin_password'] if config['admin_password']
43
+ if config['output_path']
44
+ @output_path = File.expand_path(config['output_path'], config_dir)
41
45
  end
46
+ rescue => e
47
+ warn "Warning: Could not load elderdocs.yml: #{e.message}"
42
48
  end
49
+ end
50
+
51
+ def default_output_path
52
+ base_path =
53
+ if defined?(Rails) && Rails.root
54
+ Rails.root
55
+ else
56
+ Pathname.new(Dir.pwd)
57
+ end
43
58
 
44
- attr_reader :api_servers
59
+ base_path.join('public', 'elderdocs').to_s
60
+ end
61
+
62
+ attr_reader :api_servers
45
63
 
46
64
  def self.instance
47
65
  @instance ||= new
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
4
+
3
5
  module ElderDocs
4
6
  class Engine < ::Rails::Engine
5
7
  isolate_namespace ElderDocs
@@ -47,7 +49,7 @@ module ElderDocs
47
49
  include ActionController::MimeResponds
48
50
 
49
51
  def show
50
- viewer_path = Engine.root.join('lib', 'elder_docs', 'assets', 'viewer')
52
+ viewer_path = resolve_viewer_path
51
53
  requested_path = params[:path]
52
54
  requested_path = requested_path.present? ? requested_path : 'index'
53
55
  requested_path = [requested_path, params[:format]].compact.join('.')
@@ -69,6 +71,19 @@ module ElderDocs
69
71
 
70
72
  private
71
73
 
74
+ def resolve_viewer_path
75
+ custom_path = ElderDocs.config.output_path
76
+ if custom_path && Dir.exist?(custom_path)
77
+ Pathname.new(custom_path)
78
+ else
79
+ fallback_viewer_path
80
+ end
81
+ end
82
+
83
+ def fallback_viewer_path
84
+ Engine.root.join('lib', 'elder_docs', 'assets', 'viewer')
85
+ end
86
+
72
87
  def mime_type_for(file_path)
73
88
  ext = File.extname(file_path.to_s)
74
89
  case ext
@@ -13,7 +13,7 @@ module ElderDocs
13
13
  def initialize(definitions_path:, articles_path:, output_path:, api_server: nil, skip_build: false, force_build: false)
14
14
  @definitions_path = definitions_path
15
15
  @articles_path = articles_path
16
- @output_path = output_path
16
+ @output_path = File.expand_path(output_path, Dir.pwd)
17
17
  @api_server = api_server
18
18
  @skip_build = skip_build
19
19
  @force_build = force_build
@@ -240,13 +240,12 @@ module ElderDocs
240
240
  index_html_path = File.join(output_path, 'index.html')
241
241
  if File.exist?(index_html_path)
242
242
  html_content = File.read(index_html_path, encoding: 'UTF-8')
243
- # Replace relative paths with paths relative to mount point
244
- html_content.gsub!(/src="\.\//, 'src="/docs/')
245
- html_content.gsub!(/href="\.\//, 'href="/docs/')
246
- html_content.gsub!(/src="\/assets\//, 'src="/docs/assets/')
247
- html_content.gsub!(/href="\/assets\//, 'href="/docs/assets/')
248
- # Fix data.js path
249
- html_content.gsub!(/src="\/data\.js/, 'src="/docs/data.js')
243
+ mount_path = normalized_mount_path
244
+ html_content.gsub!(/src="\.\//, %{src="#{mount_path}/})
245
+ html_content.gsub!(/href="\.\//, %{href="#{mount_path}/})
246
+ html_content.gsub!(/src="\/assets\//, %{src="#{mount_path}/assets/})
247
+ html_content.gsub!(/href="\/assets\//, %{href="#{mount_path}/assets/})
248
+ html_content.gsub!(/src="\/data\.js/, %{src="#{mount_path}/data.js})
250
249
  File.write(index_html_path, html_content)
251
250
  end
252
251
 
@@ -258,6 +257,14 @@ module ElderDocs
258
257
 
259
258
  Thor::Base.shell.new.say(message, color)
260
259
  end
260
+
261
+ def normalized_mount_path
262
+ mount_path = ElderDocs.config.mount_path || '/docs'
263
+ mount_path = "/#{mount_path}" unless mount_path.start_with?('/')
264
+ mount_path = '/' if mount_path == '//'
265
+ mount_path = mount_path.chomp('/')
266
+ mount_path.empty? ? '' : mount_path
267
+ end
261
268
  end
262
269
  end
263
270
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ElderDocs
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.2'
5
5
  end
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elder_docs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - ElderDocs