elder_docs 0.1.0 → 0.1.3
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 +4 -4
- data/README.md +49 -1
- data/elderdocs.yml.example +3 -0
- data/frontend/index.html +18 -0
- data/frontend/package.json +28 -0
- data/frontend/postcss.config.js +7 -0
- data/frontend/public/data.js +2 -0
- data/frontend/src/App.jsx +154 -0
- data/frontend/src/UiConfigApp.jsx +11 -0
- data/frontend/src/components/ApiExplorer.jsx +323 -0
- data/frontend/src/components/ContentPanel.jsx +228 -0
- data/frontend/src/components/Sidebar.jsx +157 -0
- data/frontend/src/components/UiConfigurator.jsx +470 -0
- data/frontend/src/contexts/ApiKeyContext.jsx +41 -0
- data/frontend/src/index.css +215 -0
- data/frontend/src/main.jsx +11 -0
- data/frontend/tailwind.config.js +40 -0
- data/frontend/vite.config.js +17 -0
- data/lib/elder_docs/cli.rb +7 -3
- data/lib/elder_docs/config.rb +29 -11
- data/lib/elder_docs/engine.rb +16 -1
- data/lib/elder_docs/generator.rb +34 -11
- data/lib/elder_docs/version.rb +1 -1
- metadata +18 -3
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Syne:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=Inter:wght@400;600;800&family=Space+Grotesk:wght@400;600;700&family=Oswald:wght@400;600;700&family=Fira+Code:wght@400;600&family=Roboto:wght@400;500;700&family=Open+Sans:wght@400;600;700&display=swap');
|
|
2
|
+
|
|
3
|
+
@tailwind base;
|
|
4
|
+
@tailwind components;
|
|
5
|
+
@tailwind utilities;
|
|
6
|
+
|
|
7
|
+
@layer base {
|
|
8
|
+
:root {
|
|
9
|
+
--bd-yellow: #f8d447;
|
|
10
|
+
--bd-charcoal: #000000;
|
|
11
|
+
--bd-ink: #121212;
|
|
12
|
+
--bd-white: #ffffff;
|
|
13
|
+
--bd-muted: #666666;
|
|
14
|
+
--bd-panel: #ffffff;
|
|
15
|
+
--bd-border: #000000;
|
|
16
|
+
|
|
17
|
+
--bd-radius: 0px;
|
|
18
|
+
--font-heading: 'Syne';
|
|
19
|
+
--font-body: 'IBM Plex Sans';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
* {
|
|
23
|
+
border-width: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
body {
|
|
27
|
+
font-family: var(--font-body), system-ui, -apple-system, BlinkMacSystemFont;
|
|
28
|
+
font-size: 15px;
|
|
29
|
+
line-height: 1.55;
|
|
30
|
+
color: var(--bd-ink);
|
|
31
|
+
background: var(--bd-white);
|
|
32
|
+
min-height: 100vh;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
body::before {
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
body::after {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
body[data-mounted='true'] .reveal {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
transform: translateY(0) scale(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@layer components {
|
|
50
|
+
.app-shell {
|
|
51
|
+
position: relative;
|
|
52
|
+
z-index: 1;
|
|
53
|
+
width: 100%;
|
|
54
|
+
height: 100%;
|
|
55
|
+
display: flex;
|
|
56
|
+
background: #ffffff;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.surface {
|
|
60
|
+
background: var(--bd-panel);
|
|
61
|
+
border: 3px solid var(--bd-border);
|
|
62
|
+
box-shadow: 8px 8px 0px 0px var(--bd-border);
|
|
63
|
+
border-radius: var(--bd-radius);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.surface--glass {
|
|
67
|
+
backdrop-filter: none;
|
|
68
|
+
background: var(--bd-panel);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.surface--highlight {
|
|
72
|
+
border-color: var(--bd-border);
|
|
73
|
+
box-shadow: 4px 4px 0px 0px var(--bd-yellow);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.pill {
|
|
77
|
+
font-family: var(--font-heading), system-ui;
|
|
78
|
+
letter-spacing: 0.1em;
|
|
79
|
+
font-size: 0.7rem;
|
|
80
|
+
text-transform: uppercase;
|
|
81
|
+
border: 2px solid var(--bd-border);
|
|
82
|
+
padding: 0.35rem 1rem;
|
|
83
|
+
border-radius: var(--bd-radius);
|
|
84
|
+
font-weight: 700;
|
|
85
|
+
color: var(--bd-charcoal);
|
|
86
|
+
background: var(--bd-yellow);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.chip {
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: 0.25rem;
|
|
93
|
+
font-size: 0.7rem;
|
|
94
|
+
text-transform: uppercase;
|
|
95
|
+
letter-spacing: 0.1em;
|
|
96
|
+
padding: 0.3rem 0.9rem;
|
|
97
|
+
border-radius: var(--bd-radius);
|
|
98
|
+
border: 2px solid var(--bd-border);
|
|
99
|
+
font-weight: 700;
|
|
100
|
+
background: var(--bd-panel);
|
|
101
|
+
color: var(--bd-ink);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.btn-primary {
|
|
105
|
+
font-family: var(--font-heading), system-ui;
|
|
106
|
+
text-transform: uppercase;
|
|
107
|
+
letter-spacing: 0.1em;
|
|
108
|
+
font-size: 0.8rem;
|
|
109
|
+
background: var(--bd-charcoal);
|
|
110
|
+
color: var(--bd-white);
|
|
111
|
+
padding: 0.85rem 1.6rem;
|
|
112
|
+
border: 3px solid var(--bd-border);
|
|
113
|
+
border-radius: var(--bd-radius);
|
|
114
|
+
transition: transform 0.1s ease, box-shadow 0.1s ease;
|
|
115
|
+
font-weight: 700;
|
|
116
|
+
box-shadow: 4px 4px 0px 0px var(--bd-yellow);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.btn-primary:hover {
|
|
120
|
+
transform: translate(-2px, -2px);
|
|
121
|
+
box-shadow: 6px 6px 0px 0px var(--bd-yellow);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.btn-primary:active {
|
|
125
|
+
transform: translate(2px, 2px);
|
|
126
|
+
box-shadow: 0px 0px 0px 0px var(--bd-yellow);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.btn-secondary {
|
|
130
|
+
font-family: var(--font-heading), system-ui;
|
|
131
|
+
text-transform: uppercase;
|
|
132
|
+
letter-spacing: 0.1em;
|
|
133
|
+
font-size: 0.7rem;
|
|
134
|
+
background: var(--bd-panel);
|
|
135
|
+
color: var(--bd-ink);
|
|
136
|
+
padding: 0.75rem 1.3rem;
|
|
137
|
+
border: 2px solid var(--bd-border);
|
|
138
|
+
border-radius: var(--bd-radius);
|
|
139
|
+
transition: transform 0.1s ease;
|
|
140
|
+
font-weight: 700;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.btn-secondary:hover {
|
|
144
|
+
background: var(--bd-yellow);
|
|
145
|
+
color: var(--bd-charcoal);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.input-field {
|
|
149
|
+
background: var(--bd-panel);
|
|
150
|
+
border: 3px solid var(--bd-border);
|
|
151
|
+
color: var(--bd-ink);
|
|
152
|
+
border-radius: var(--bd-radius);
|
|
153
|
+
padding: 0.65rem 0.9rem;
|
|
154
|
+
transition: box-shadow 0.1s ease;
|
|
155
|
+
font-weight: 500;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.input-field:focus {
|
|
159
|
+
outline: none;
|
|
160
|
+
box-shadow: 4px 4px 0px 0px var(--bd-yellow);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.nav-card {
|
|
164
|
+
border-radius: var(--bd-radius);
|
|
165
|
+
border: 2px solid transparent;
|
|
166
|
+
background: transparent;
|
|
167
|
+
transition: transform 0.1s ease;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.nav-card:hover {
|
|
171
|
+
background: var(--bd-panel);
|
|
172
|
+
border: 2px solid var(--bd-border);
|
|
173
|
+
transform: translate(-2px, -2px);
|
|
174
|
+
box-shadow: 4px 4px 0px 0px var(--bd-charcoal);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.nav-card--active {
|
|
178
|
+
background: var(--bd-yellow);
|
|
179
|
+
border: 2px solid var(--bd-border);
|
|
180
|
+
color: var(--bd-charcoal);
|
|
181
|
+
box-shadow: 4px 4px 0px 0px var(--bd-charcoal);
|
|
182
|
+
transform: translate(-2px, -2px);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.reveal {
|
|
186
|
+
opacity: 0;
|
|
187
|
+
transform: translateY(15px);
|
|
188
|
+
transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1), transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes floatGlow {
|
|
193
|
+
0% {
|
|
194
|
+
transform: translateY(0px);
|
|
195
|
+
opacity: 0.5;
|
|
196
|
+
}
|
|
197
|
+
50% {
|
|
198
|
+
transform: translateY(-12px);
|
|
199
|
+
opacity: 1;
|
|
200
|
+
}
|
|
201
|
+
100% {
|
|
202
|
+
transform: translateY(0px);
|
|
203
|
+
opacity: 0.5;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@keyframes shimmer {
|
|
208
|
+
0% {
|
|
209
|
+
background-position: 0% 50%;
|
|
210
|
+
}
|
|
211
|
+
100% {
|
|
212
|
+
background-position: 200% 50%;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: [
|
|
4
|
+
"./index.html",
|
|
5
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
6
|
+
],
|
|
7
|
+
theme: {
|
|
8
|
+
extend: {
|
|
9
|
+
fontFamily: {
|
|
10
|
+
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
11
|
+
},
|
|
12
|
+
fontSize: {
|
|
13
|
+
'xs': '16px',
|
|
14
|
+
'sm': '18px',
|
|
15
|
+
'base': '20px',
|
|
16
|
+
'lg': '24px',
|
|
17
|
+
'xl': '28px',
|
|
18
|
+
'2xl': '32px',
|
|
19
|
+
'3xl': '40px',
|
|
20
|
+
'4xl': '48px',
|
|
21
|
+
},
|
|
22
|
+
colors: {
|
|
23
|
+
'yellow': {
|
|
24
|
+
50: '#FFFBEB',
|
|
25
|
+
100: '#FEF3C7',
|
|
26
|
+
200: '#FDE68A',
|
|
27
|
+
300: '#FCD34D',
|
|
28
|
+
400: '#FBBF24',
|
|
29
|
+
500: '#F59E0B',
|
|
30
|
+
600: '#D97706',
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
borderRadius: {
|
|
34
|
+
'none': '0',
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
plugins: [],
|
|
39
|
+
}
|
|
40
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
plugins: [react()],
|
|
6
|
+
build: {
|
|
7
|
+
outDir: 'dist',
|
|
8
|
+
assetsDir: 'assets',
|
|
9
|
+
rollupOptions: {
|
|
10
|
+
output: {
|
|
11
|
+
manualChunks: undefined
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
base: './'
|
|
16
|
+
})
|
|
17
|
+
|
data/lib/elder_docs/cli.rb
CHANGED
|
@@ -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:
|
|
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(
|
|
69
|
+
ElderDocs.config.output_path || File.join(Dir.pwd, 'public', 'elderdocs')
|
|
66
70
|
end
|
|
67
71
|
end
|
|
68
72
|
end
|
data/lib/elder_docs/config.rb
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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
|
data/lib/elder_docs/engine.rb
CHANGED
|
@@ -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 =
|
|
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
|
data/lib/elder_docs/generator.rb
CHANGED
|
@@ -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
|
|
@@ -185,12 +185,28 @@ module ElderDocs
|
|
|
185
185
|
def build_frontend!
|
|
186
186
|
say '🔨 Building frontend...', :cyan
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
# Try multiple locations for frontend directory
|
|
189
|
+
# 1. Relative to lib (development repo)
|
|
190
|
+
# 2. At gem root (installed gem)
|
|
191
|
+
# 3. Using Engine.root if available (Rails context)
|
|
192
|
+
possible_paths = [
|
|
193
|
+
File.join(File.dirname(__FILE__), '..', '..', 'frontend'), # Development: lib/elder_docs/../../frontend
|
|
194
|
+
File.join(File.dirname(__FILE__), '..', '..', '..', 'frontend'), # Installed gem: lib/elder_docs/../../../frontend
|
|
195
|
+
]
|
|
189
196
|
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
# If Engine is available, try relative to gem root
|
|
198
|
+
if defined?(ElderDocs::Engine) && ElderDocs::Engine.root
|
|
199
|
+
possible_paths << ElderDocs::Engine.root.join('frontend').to_s
|
|
192
200
|
end
|
|
193
201
|
|
|
202
|
+
frontend_dir = possible_paths.find { |path| Dir.exist?(path) }
|
|
203
|
+
|
|
204
|
+
unless frontend_dir && Dir.exist?(frontend_dir)
|
|
205
|
+
raise ValidationError, "Frontend directory not found. Tried: #{possible_paths.join(', ')}"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
frontend_dir = File.expand_path(frontend_dir)
|
|
209
|
+
|
|
194
210
|
# Write compiled data to frontend public directory
|
|
195
211
|
public_dir = File.join(frontend_dir, 'public')
|
|
196
212
|
FileUtils.mkdir_p(public_dir)
|
|
@@ -240,13 +256,12 @@ module ElderDocs
|
|
|
240
256
|
index_html_path = File.join(output_path, 'index.html')
|
|
241
257
|
if File.exist?(index_html_path)
|
|
242
258
|
html_content = File.read(index_html_path, encoding: 'UTF-8')
|
|
243
|
-
|
|
244
|
-
html_content.gsub!(/src="\.\//,
|
|
245
|
-
html_content.gsub!(/href="\.\//,
|
|
246
|
-
html_content.gsub!(/src="\/assets\//,
|
|
247
|
-
html_content.gsub!(/href="\/assets\//,
|
|
248
|
-
#
|
|
249
|
-
html_content.gsub!(/src="\/data\.js/, 'src="/docs/data.js')
|
|
259
|
+
mount_path = normalized_mount_path
|
|
260
|
+
html_content.gsub!(/src="\.\//, %{src="#{mount_path}/})
|
|
261
|
+
html_content.gsub!(/href="\.\//, %{href="#{mount_path}/})
|
|
262
|
+
html_content.gsub!(/src="\/assets\//, %{src="#{mount_path}/assets/})
|
|
263
|
+
html_content.gsub!(/href="\/assets\//, %{href="#{mount_path}/assets/})
|
|
264
|
+
html_content.gsub!(/src="\/data\.js/, %{src="#{mount_path}/data.js})
|
|
250
265
|
File.write(index_html_path, html_content)
|
|
251
266
|
end
|
|
252
267
|
|
|
@@ -258,6 +273,14 @@ module ElderDocs
|
|
|
258
273
|
|
|
259
274
|
Thor::Base.shell.new.say(message, color)
|
|
260
275
|
end
|
|
276
|
+
|
|
277
|
+
def normalized_mount_path
|
|
278
|
+
mount_path = ElderDocs.config.mount_path || '/docs'
|
|
279
|
+
mount_path = "/#{mount_path}" unless mount_path.start_with?('/')
|
|
280
|
+
mount_path = '/' if mount_path == '//'
|
|
281
|
+
mount_path = mount_path.chomp('/')
|
|
282
|
+
mount_path.empty? ? '' : mount_path
|
|
283
|
+
end
|
|
261
284
|
end
|
|
262
285
|
end
|
|
263
286
|
|
data/lib/elder_docs/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ElderDocs
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '2.0'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '2.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rails
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,6 +107,21 @@ files:
|
|
|
107
107
|
- README.md
|
|
108
108
|
- elderdocs.yml.example
|
|
109
109
|
- exe/elderdocs
|
|
110
|
+
- frontend/index.html
|
|
111
|
+
- frontend/package.json
|
|
112
|
+
- frontend/postcss.config.js
|
|
113
|
+
- frontend/public/data.js
|
|
114
|
+
- frontend/src/App.jsx
|
|
115
|
+
- frontend/src/UiConfigApp.jsx
|
|
116
|
+
- frontend/src/components/ApiExplorer.jsx
|
|
117
|
+
- frontend/src/components/ContentPanel.jsx
|
|
118
|
+
- frontend/src/components/Sidebar.jsx
|
|
119
|
+
- frontend/src/components/UiConfigurator.jsx
|
|
120
|
+
- frontend/src/contexts/ApiKeyContext.jsx
|
|
121
|
+
- frontend/src/index.css
|
|
122
|
+
- frontend/src/main.jsx
|
|
123
|
+
- frontend/tailwind.config.js
|
|
124
|
+
- frontend/vite.config.js
|
|
110
125
|
- lib/elder_docs.rb
|
|
111
126
|
- lib/elder_docs/assets/ui_config.html
|
|
112
127
|
- lib/elder_docs/assets/viewer/assets/index-161b367b.css
|