docula 1.2.0 → 1.6.0
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.
- package/README.md +33 -716
- package/dist/docula.d.ts +106 -13
- package/dist/docula.js +863 -160
- package/package.json +6 -2
- package/templates/classic/changelog.hbs +23 -2
- package/templates/classic/css/base.css +75 -0
- package/templates/classic/css/variables.css +30 -0
- package/templates/classic/home.hbs +7 -0
- package/templates/modern/api.hbs +39 -2
- package/templates/modern/changelog-entry.hbs +1 -1
- package/templates/modern/changelog.hbs +24 -3
- package/templates/modern/css/styles.css +124 -36
- package/templates/modern/css/variables.css +32 -0
- package/templates/modern/home.hbs +10 -3
- package/templates/modern/includes/api-reference.hbs +1 -1
- package/templates/modern/includes/documentation.hbs +1 -1
- package/templates/modern/includes/footer.hbs +5 -2
- package/templates/modern/includes/header-bar.hbs +40 -22
- package/templates/modern/includes/header.hbs +18 -3
- package/templates/modern/includes/home.hbs +1 -1
- package/templates/modern/includes/scripts.hbs +43 -34
- package/templates/modern/js/api.js +17 -6
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="Toggle navigation menu">
|
|
5
5
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
|
6
6
|
</button>
|
|
7
|
-
<a href="/">
|
|
8
|
-
<img alt="{{siteTitle}}" class="logo__img" src="/logo.svg">
|
|
7
|
+
<a href="{{baseUrl}}/">
|
|
8
|
+
<img alt="{{siteTitle}}" class="logo__img" src="{{baseUrl}}/logo.svg">
|
|
9
9
|
</a>
|
|
10
10
|
<nav class="header-bottom__nav">
|
|
11
11
|
{{#if hasDocuments}}
|
|
12
|
-
<a class="header-bottom__item" href="/
|
|
12
|
+
<a class="header-bottom__item" href="{{docsUrl}}/" id="nav-docs">
|
|
13
13
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
14
14
|
<span>Documentation</span>
|
|
15
15
|
</a>
|
|
16
16
|
{{/if}}
|
|
17
17
|
{{#if openApiUrl}}
|
|
18
|
-
<a class="header-bottom__item" href="
|
|
18
|
+
<a class="header-bottom__item" href="{{apiUrl}}" id="nav-api">
|
|
19
19
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/></svg>
|
|
20
20
|
<span>API Reference</span>
|
|
21
21
|
</a>
|
|
22
22
|
{{/if}}
|
|
23
23
|
{{#if hasChangelog}}
|
|
24
|
-
<a class="header-bottom__item" href="
|
|
24
|
+
<a class="header-bottom__item" href="{{changelogUrl}}" id="nav-changelog">
|
|
25
25
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/><path d="M8 6v8"/></svg>
|
|
26
26
|
<span>Changelog</span>
|
|
27
27
|
</a>
|
|
@@ -39,37 +39,48 @@
|
|
|
39
39
|
{{/each}}
|
|
40
40
|
{{/if}}
|
|
41
41
|
</nav>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
<div class="header-actions">
|
|
43
|
+
{{#if cookieAuth.loginUrl}}
|
|
44
|
+
<div class="cookie-auth">
|
|
45
|
+
<a href="{{cookieAuth.loginUrl}}" class="cookie-auth-btn" id="cookie-auth-login">
|
|
46
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" x2="3" y1="12" y2="12"/></svg>
|
|
47
|
+
<span>Log In</span>
|
|
48
|
+
</a>
|
|
49
|
+
<span class="cookie-auth-user" id="cookie-auth-user"></span>
|
|
50
|
+
<script>
|
|
51
|
+
var auth = window.__doculaAuth;
|
|
52
|
+
if (auth && auth.displayName) {
|
|
53
|
+
var userEl = document.getElementById('cookie-auth-user');
|
|
54
|
+
if (userEl) userEl.textContent = auth.displayName;
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
<button class="cookie-auth-btn cookie-auth-logout" id="cookie-auth-logout">
|
|
58
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
|
|
59
|
+
<span>Log Out</span>
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
{{/if}}
|
|
63
|
+
{{> theme-toggle }}
|
|
64
|
+
</div>
|
|
54
65
|
</div>
|
|
55
66
|
</div>
|
|
56
67
|
</header>
|
|
57
68
|
<aside class="mobile-sidebar" id="mobile-sidebar">
|
|
58
69
|
<nav class="mobile-nav">
|
|
59
70
|
{{#if hasDocuments}}
|
|
60
|
-
<a class="mobile-nav__item" href="/
|
|
71
|
+
<a class="mobile-nav__item" href="{{docsUrl}}/">
|
|
61
72
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
62
73
|
<span>Documentation</span>
|
|
63
74
|
</a>
|
|
64
75
|
{{/if}}
|
|
65
76
|
{{#if openApiUrl}}
|
|
66
|
-
<a class="mobile-nav__item" href="
|
|
77
|
+
<a class="mobile-nav__item" href="{{apiUrl}}">
|
|
67
78
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/></svg>
|
|
68
79
|
<span>API Reference</span>
|
|
69
80
|
</a>
|
|
70
81
|
{{/if}}
|
|
71
82
|
{{#if hasChangelog}}
|
|
72
|
-
<a class="mobile-nav__item" href="
|
|
83
|
+
<a class="mobile-nav__item" href="{{changelogUrl}}">
|
|
73
84
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/><path d="M8 6v8"/></svg>
|
|
74
85
|
<span>Changelog</span>
|
|
75
86
|
</a>
|
|
@@ -91,8 +102,15 @@
|
|
|
91
102
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" x2="3" y1="12" y2="12"/></svg>
|
|
92
103
|
<span>Log In</span>
|
|
93
104
|
</a>
|
|
94
|
-
<span class="cookie-auth-user" id="cookie-auth-user-mobile"
|
|
95
|
-
<
|
|
105
|
+
<span class="cookie-auth-user" id="cookie-auth-user-mobile"></span>
|
|
106
|
+
<script>
|
|
107
|
+
var auth = window.__doculaAuth;
|
|
108
|
+
if (auth && auth.displayName) {
|
|
109
|
+
var userEl = document.getElementById('cookie-auth-user-mobile');
|
|
110
|
+
if (userEl) userEl.textContent = auth.displayName;
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
<button class="mobile-nav__item cookie-auth-btn--mobile" id="cookie-auth-logout-mobile">
|
|
96
114
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
|
|
97
115
|
<span>Log Out</span>
|
|
98
116
|
</button>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<meta charset="UTF-8">
|
|
2
2
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3
3
|
<meta name="description" content="{{siteDescription}}">
|
|
4
|
-
<link rel="stylesheet" href="/css/
|
|
5
|
-
<link rel="stylesheet" href="/css/
|
|
6
|
-
<link rel="
|
|
4
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/variables.css">
|
|
5
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/styles.css">
|
|
6
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/highlight/styles/base16/docula.css">
|
|
7
|
+
<link rel="icon" href="{{baseUrl}}/favicon.ico">
|
|
7
8
|
<script>
|
|
8
9
|
(function(){
|
|
9
10
|
window.__doculaThemeKey = 'docula:theme:' + ({{#if siteUrl}}'{{siteUrl}}'{{else}}location.origin{{/if}}).replace(/^https?:\/\//, '');
|
|
@@ -12,5 +13,19 @@
|
|
|
12
13
|
? (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark')
|
|
13
14
|
: mode;
|
|
14
15
|
if (resolved === 'light') document.documentElement.setAttribute('data-theme', 'light');
|
|
16
|
+
try {
|
|
17
|
+
var authState = JSON.parse(localStorage.getItem('docula-auth-state'));
|
|
18
|
+
if (authState) {
|
|
19
|
+
window.__doculaAuth = authState;
|
|
20
|
+
if (authState.loggedIn) {
|
|
21
|
+
document.documentElement.classList.add('docula-auth-logged-in');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch (e) {
|
|
25
|
+
// Ignore localStorage parsing errors
|
|
26
|
+
}
|
|
27
|
+
if (!window.__doculaAuth) {
|
|
28
|
+
window.__doculaAuth = { loggedIn: false, displayName: null };
|
|
29
|
+
}
|
|
15
30
|
})();
|
|
16
31
|
</script>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script src="/css/highlight/highlight.min.js"></script>
|
|
1
|
+
<script src="{{baseUrl}}/css/highlight/highlight.min.js"></script>
|
|
2
2
|
<script>
|
|
3
3
|
document.addEventListener('DOMContentLoaded', () => {
|
|
4
4
|
document.querySelectorAll('pre code').forEach(el => { el.textContent = el.textContent.trimEnd(); });
|
|
@@ -90,43 +90,32 @@
|
|
|
90
90
|
})();
|
|
91
91
|
</script>
|
|
92
92
|
{{#if cookieAuth}}
|
|
93
|
-
<div id="cookie-auth-config" hidden data-
|
|
93
|
+
<div id="cookie-auth-config" hidden{{#if cookieAuth.logoutUrl}} data-logout-url="{{cookieAuth.logoutUrl}}"{{/if}}{{#if cookieAuth.authCheckUrl}} data-auth-check-url="{{cookieAuth.authCheckUrl}}"{{/if}}{{#if cookieAuth.authCheckMethod}} data-auth-check-method="{{cookieAuth.authCheckMethod}}"{{/if}}{{#if cookieAuth.authCheckUserPath}} data-auth-check-user-path="{{cookieAuth.authCheckUserPath}}"{{/if}}></div>
|
|
94
94
|
<script>
|
|
95
95
|
(function() {
|
|
96
96
|
var configEl = document.getElementById('cookie-auth-config');
|
|
97
97
|
if (!configEl) return;
|
|
98
|
-
var cookieName = configEl.getAttribute('data-cookie-name');
|
|
99
98
|
var logoutUrl = configEl.getAttribute('data-logout-url');
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
var authCheckUrl = configEl.getAttribute('data-auth-check-url');
|
|
100
|
+
var authCheckMethod = configEl.getAttribute('data-auth-check-method') || 'GET';
|
|
101
|
+
var authCheckUserPath = configEl.getAttribute('data-auth-check-user-path');
|
|
102
|
+
function getNestedValue(obj, path) {
|
|
103
|
+
if (!path) return null;
|
|
104
|
+
var parts = path.split('.');
|
|
105
|
+
var current = obj;
|
|
106
|
+
for (var i = 0; i < parts.length; i++) {
|
|
107
|
+
if (current == null || typeof current !== 'object') return null;
|
|
108
|
+
current = current[parts[i]];
|
|
107
109
|
}
|
|
110
|
+
return current || null;
|
|
108
111
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
var payload = token.split('.')[1];
|
|
118
|
-
if (!payload) return null;
|
|
119
|
-
var json = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
|
|
120
|
-
var claims = JSON.parse(json);
|
|
121
|
-
return claims.name || claims.preferred_username || claims.email || null;
|
|
122
|
-
} catch (e) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
function updateAuthUI() {
|
|
127
|
-
var token = getCookieValue();
|
|
128
|
-
var loggedIn = !!token;
|
|
129
|
-
var displayName = loggedIn ? getDisplayName(token) : null;
|
|
112
|
+
var cachedAuth = null;
|
|
113
|
+
try { cachedAuth = JSON.parse(localStorage.getItem('docula-auth-state')); } catch(e) {}
|
|
114
|
+
window.__doculaAuth = cachedAuth || { loggedIn: false, displayName: null };
|
|
115
|
+
function setAuthUI(loggedIn, displayName) {
|
|
116
|
+
window.__doculaAuth = { loggedIn: loggedIn, displayName: displayName };
|
|
117
|
+
try { localStorage.setItem('docula-auth-state', JSON.stringify(window.__doculaAuth)); } catch(e) {}
|
|
118
|
+
document.dispatchEvent(new CustomEvent('docula-auth-change'));
|
|
130
119
|
var els = [
|
|
131
120
|
{ login: document.getElementById('cookie-auth-login'), logout: document.getElementById('cookie-auth-logout'), user: document.getElementById('cookie-auth-user') },
|
|
132
121
|
{ login: document.getElementById('cookie-auth-login-mobile'), logout: document.getElementById('cookie-auth-logout-mobile'), user: document.getElementById('cookie-auth-user-mobile') }
|
|
@@ -140,8 +129,29 @@
|
|
|
140
129
|
}
|
|
141
130
|
});
|
|
142
131
|
}
|
|
132
|
+
function checkAuth() {
|
|
133
|
+
if (!authCheckUrl) return;
|
|
134
|
+
fetch(authCheckUrl, { method: authCheckMethod, credentials: 'include' }).then(function(res) {
|
|
135
|
+
if (!res.ok) {
|
|
136
|
+
setAuthUI(false, null);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (authCheckUserPath) {
|
|
140
|
+
res.json().then(function(data) {
|
|
141
|
+
setAuthUI(true, getNestedValue(data, authCheckUserPath));
|
|
142
|
+
}).catch(function() {
|
|
143
|
+
setAuthUI(true, null);
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
setAuthUI(true, null);
|
|
147
|
+
}
|
|
148
|
+
}).catch(function() {
|
|
149
|
+
setAuthUI(false, null);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
143
152
|
document.addEventListener('DOMContentLoaded', function() {
|
|
144
|
-
|
|
153
|
+
if (cachedAuth) setAuthUI(cachedAuth.loggedIn, cachedAuth.displayName);
|
|
154
|
+
checkAuth();
|
|
145
155
|
var logoutEls = [
|
|
146
156
|
document.getElementById('cookie-auth-logout'),
|
|
147
157
|
document.getElementById('cookie-auth-logout-mobile')
|
|
@@ -149,10 +159,9 @@
|
|
|
149
159
|
logoutEls.forEach(function(el) {
|
|
150
160
|
if (el) {
|
|
151
161
|
el.addEventListener('click', function() {
|
|
152
|
-
if (
|
|
162
|
+
if (logoutUrl) {
|
|
153
163
|
window.location.href = logoutUrl;
|
|
154
164
|
} else {
|
|
155
|
-
document.cookie = cookieName + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
|
|
156
165
|
window.location.reload();
|
|
157
166
|
}
|
|
158
167
|
});
|
|
@@ -130,11 +130,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
130
130
|
authValueInput.value = '';
|
|
131
131
|
if (cookieStatusEl) {
|
|
132
132
|
cookieStatusEl.classList.remove('api-auth__cookie-status--hidden');
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
cookieStatusEl.textContent = hasCookie ? 'Logged in' : 'Not logged in — use Login button above';
|
|
137
|
-
cookieStatusEl.className = 'api-auth__cookie-status' + (hasCookie ? ' api-auth__cookie-status--ok' : ' api-auth__cookie-status--warn');
|
|
133
|
+
var auth = window.__doculaAuth || { loggedIn: false };
|
|
134
|
+
cookieStatusEl.textContent = auth.loggedIn ? 'Logged in' : 'Not logged in — use Login button above';
|
|
135
|
+
cookieStatusEl.className = 'api-auth__cookie-status' + (auth.loggedIn ? ' api-auth__cookie-status--ok' : ' api-auth__cookie-status--warn');
|
|
138
136
|
}
|
|
139
137
|
} else {
|
|
140
138
|
authValueInput.classList.remove('api-auth__value--hidden');
|
|
@@ -148,7 +146,20 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
148
146
|
if (cookieStatusEl) cookieStatusEl.classList.add('api-auth__cookie-status--hidden');
|
|
149
147
|
}
|
|
150
148
|
}
|
|
151
|
-
|
|
149
|
+
var savedAuth = localStorage.getItem('docula-api-auth-type');
|
|
150
|
+
if (savedAuth) {
|
|
151
|
+
for (var i = 0; i < authTypeSelect.options.length; i++) {
|
|
152
|
+
if (authTypeSelect.options[i].value === savedAuth) {
|
|
153
|
+
authTypeSelect.selectedIndex = i;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
authTypeSelect.addEventListener('change', function() {
|
|
159
|
+
localStorage.setItem('docula-api-auth-type', authTypeSelect.value);
|
|
160
|
+
updateAuthUI();
|
|
161
|
+
});
|
|
162
|
+
document.addEventListener('docula-auth-change', updateAuthUI);
|
|
152
163
|
updateAuthUI();
|
|
153
164
|
}
|
|
154
165
|
|